summaryrefslogtreecommitdiffstats
path: root/contrib/tcl/tests
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1996-06-26 06:06:43 +0000
committerphk <phk@FreeBSD.org>1996-06-26 06:06:43 +0000
commit00febf60093a024ccc629fdfc81e02a40c5f6572 (patch)
tree4d70f77f44120e6541d1418223baf06562774975 /contrib/tcl/tests
downloadFreeBSD-src-00febf60093a024ccc629fdfc81e02a40c5f6572.zip
FreeBSD-src-00febf60093a024ccc629fdfc81e02a40c5f6572.tar.gz
Tcl 7.5, various makefiles will be updated to use these sources as soon
as I get these back down to my machine.
Diffstat (limited to 'contrib/tcl/tests')
-rw-r--r--contrib/tcl/tests/README96
-rw-r--r--contrib/tcl/tests/all16
-rw-r--r--contrib/tcl/tests/append.test158
-rw-r--r--contrib/tcl/tests/assocd.test57
-rw-r--r--contrib/tcl/tests/async.test131
-rw-r--r--contrib/tcl/tests/case.test83
-rw-r--r--contrib/tcl/tests/clock.test101
-rw-r--r--contrib/tcl/tests/cmdAH.test1132
-rw-r--r--contrib/tcl/tests/cmdInfo.test74
-rw-r--r--contrib/tcl/tests/concat.test39
-rw-r--r--contrib/tcl/tests/dcall.test40
-rw-r--r--contrib/tcl/tests/defs346
-rw-r--r--contrib/tcl/tests/dstring.test247
-rw-r--r--contrib/tcl/tests/env.test108
-rw-r--r--contrib/tcl/tests/error.test171
-rw-r--r--contrib/tcl/tests/eval.test55
-rw-r--r--contrib/tcl/tests/event.test927
-rw-r--r--contrib/tcl/tests/exec.test489
-rw-r--r--contrib/tcl/tests/expr.test890
-rw-r--r--contrib/tcl/tests/fhandle.test63
-rw-r--r--contrib/tcl/tests/fileName.test1401
-rw-r--r--contrib/tcl/tests/for.test211
-rw-r--r--contrib/tcl/tests/format.test366
-rw-r--r--contrib/tcl/tests/get.test72
-rw-r--r--contrib/tcl/tests/history.test386
-rw-r--r--contrib/tcl/tests/if.test148
-rw-r--r--contrib/tcl/tests/incr.test88
-rw-r--r--contrib/tcl/tests/info.test555
-rw-r--r--contrib/tcl/tests/interp.test570
-rw-r--r--contrib/tcl/tests/io.test4341
-rw-r--r--contrib/tcl/tests/ioCmd.test394
-rw-r--r--contrib/tcl/tests/join.test38
-rw-r--r--contrib/tcl/tests/license.terms32
-rw-r--r--contrib/tcl/tests/lindex.test74
-rw-r--r--contrib/tcl/tests/link.test230
-rw-r--r--contrib/tcl/tests/linsert.test86
-rw-r--r--contrib/tcl/tests/list.test73
-rw-r--r--contrib/tcl/tests/llength.test35
-rw-r--r--contrib/tcl/tests/load.test147
-rw-r--r--contrib/tcl/tests/lrange.test77
-rw-r--r--contrib/tcl/tests/lreplace.test111
-rw-r--r--contrib/tcl/tests/lsearch.test67
-rw-r--r--contrib/tcl/tests/lsort.test126
-rw-r--r--contrib/tcl/tests/misc.test70
-rw-r--r--contrib/tcl/tests/parse.test520
-rw-r--r--contrib/tcl/tests/pid.test52
-rw-r--r--contrib/tcl/tests/pkg.test549
-rw-r--r--contrib/tcl/tests/proc.test461
-rw-r--r--contrib/tcl/tests/regexp.test315
-rw-r--r--contrib/tcl/tests/remote.tcl161
-rw-r--r--contrib/tcl/tests/rename.test131
-rw-r--r--contrib/tcl/tests/scan.test257
-rw-r--r--contrib/tcl/tests/set.test677
-rw-r--r--contrib/tcl/tests/socket.test1009
-rw-r--r--contrib/tcl/tests/source.test180
-rw-r--r--contrib/tcl/tests/split.test44
-rw-r--r--contrib/tcl/tests/string.test375
-rw-r--r--contrib/tcl/tests/subst.test106
-rw-r--r--contrib/tcl/tests/switch.test170
-rw-r--r--contrib/tcl/tests/trace.test930
-rw-r--r--contrib/tcl/tests/unknown.test60
-rw-r--r--contrib/tcl/tests/uplevel.test109
-rw-r--r--contrib/tcl/tests/upvar.test377
-rw-r--r--contrib/tcl/tests/while.test99
64 files changed, 21503 insertions, 0 deletions
diff --git a/contrib/tcl/tests/README b/contrib/tcl/tests/README
new file mode 100644
index 0000000..7dce2a2
--- /dev/null
+++ b/contrib/tcl/tests/README
@@ -0,0 +1,96 @@
+Tcl Test Suite
+--------------
+
+SCCS: @(#) README 1.6 96/04/17 10:51:11
+
+This directory contains a set of validation tests for the Tcl
+commands. Each of the files whose name ends in ".test" is
+intended to fully exercise one or a few Tcl commands. The
+commands tested by a given file are listed in the first line
+of the file.
+
+You can run the tests in two ways:
+ (a) type "make test" in ../unix; this will run all of the tests.
+ (b) start up tcltest in this directory, then "source" the test
+ file (for example, type "source parse.test"). To run all
+ of the tests, type "source all".
+In either case no output will be generated if all goes well, except
+for a listing of the tests.. If there are errors then additional
+messages will appear in the format described below. Note: don't
+run the tests as superuser, since this will cause several of the tests
+to fail.
+
+The rest of this file provides additional information on the
+features of the testing environment.
+
+This approach to testing was designed and initially implemented
+by Mary Ann May-Pumphrey of Sun Microsystems. Many thanks to
+her for donating her work back to the public Tcl release.
+
+Definitions file:
+-----------------
+
+The file "defs" defines a collection of procedures and variables
+used to run the tests. It is read in automatically by each of the
+.test files if needed, but once it has been read once it will not
+be read again by the .test files. If you change defs while running
+tests you'll have to "source" it by hand to load its new contents.
+
+Test output:
+------------
+
+Normally, output only appears when there are errors. However, if
+the variable VERBOSE is set to 1 then tests will be run in "verbose"
+mode and output will be generated for each test regardless of
+whether it succeeded or failed. Test output consists of the
+following information:
+
+ - the test identifier (which can be used to locate the test code
+ in the .test file)
+ - a brief description of the test
+ - the contents of the test code
+ - the actual results produced by the tests
+ - a "PASSED" or "FAILED" message
+ - the expected results (if the test failed)
+
+You can set VERBOSE either interactively (after the defs file has been
+read in), or you can change the default value in "defs".
+
+Selecting tests for execution:
+------------------------------
+
+Normally, all the tests in a file are run whenever the file is
+"source"d. However, you can select a specific set of tests using
+the global variable TESTS. This variable contains a pattern; any
+test whose identifier matches TESTS will be run. For example,
+the following interactive command causes all of the "for" tests in
+groups 2 and 4 to be executed:
+
+ set TESTS {for-[24]*}
+
+TESTS defaults to *, but you can change the default in "defs" if
+you wish.
+
+Saving keystrokes:
+------------------
+
+A convenience procedure named "dotests" is included in file
+"defs". It takes two arguments--the name of the test file (such
+as "parse.test"), and a pattern selecting the tests you want to
+execute. It sets TESTS to the second argument, calls "source" on
+the file specified in the first argument, and restores TESTS to
+its pre-call value at the end.
+
+Batch vs. interactive execution:
+--------------------------------
+
+The tests can be run in either batch or interactive mode. Batch
+mode refers to using I/O redirection from a UNIX shell. For example,
+the following command causes the tests in the file named "parse.test"
+to be executed:
+
+ tclTest < parse.test > parse.test.results
+
+Users who want to execute the tests in this fashion need to first
+ensure that the file "defs" has proper values for the global
+variables that control the testing environment (VERBOSE and TESTS).
diff --git a/contrib/tcl/tests/all b/contrib/tcl/tests/all
new file mode 100644
index 0000000..b50794c
--- /dev/null
+++ b/contrib/tcl/tests/all
@@ -0,0 +1,16 @@
+# This file contains a top-level script to run all of the Tcl
+# tests. Execute it by invoking "source all" when running tclTest
+# in this directory.
+#
+# SCCS: @(#) all 1.7 96/02/16 08:55:38
+
+foreach i [lsort [glob *.test]] {
+ if [string match l.*.test $i] {
+ # This is an SCCS lock file; ignore it.
+ continue
+ }
+ puts stdout $i
+ if [catch {source $i} msg] {
+ puts $msg
+ }
+}
diff --git a/contrib/tcl/tests/append.test b/contrib/tcl/tests/append.test
new file mode 100644
index 0000000..2be7194
--- /dev/null
+++ b/contrib/tcl/tests/append.test
@@ -0,0 +1,158 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) append.test 1.14 96/04/05 15:28:42
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+catch {unset x}
+test append-1.1 {append command} {
+ catch {unset 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} {
+ list [catch {append} msg] $msg
+} {1 {wrong # args: should be "append varName ?value value ...?"}}
+test append-3.2 {append errors} {
+ set x ""
+ list [catch {append x(0) 44} msg] $msg
+} {1 {can't set "x(0)": variable isn't array}}
+test append-3.3 {append errors} {
+ catch {unset x}
+ list [catch {append x} msg] $msg
+} {1 {can't read "x": no such variable}}
+
+test append-4.1 {lappend command} {
+ catch {unset 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} {
+ proc foo {} {
+ global x
+ set x old
+ unset x
+ lappend x new
+ }
+ set result [foo]
+ rename foo {}
+ set 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} {
+ set x " \{"
+ lappend x abc
+} " {abc"
+test append-4.10 {lappend command} {
+ set x " \{"
+ lappend x abc
+} " {abc"
+test append-4.11 {lappend command} {
+ set x "\{\{\{"
+ lappend x abc
+} "{{{abc"
+test append-4.12 {lappend command} {
+ set x "x \{\{\{"
+ lappend x abc
+} "x {{{abc"
+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"
+
+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 != "item $i"} {
+ return "element $i should have been \"item $i\", was \"$j\""
+ }
+ }
+ return ok
+}
+test append-5.1 {long lappends} {
+ set x ""
+ for {set i 0} {$i < 300} {set i [expr $i+1]} {
+ lappend x "item $i"
+ }
+ check $x 300
+} ok
+
+test append-6.1 {lappend errors} {
+ list [catch {lappend} msg] $msg
+} {1 {wrong # args: should be "lappend varName ?value value ...?"}}
+test append-6.2 {lappend errors} {
+ set x ""
+ list [catch {lappend x(0) 44} msg] $msg
+} {1 {can't set "x(0)": variable isn't array}}
+test append-6.3 {lappend errors} {
+ catch {unset x}
+ list [catch {lappend x} msg] $msg
+} {1 {can't read "x": no such variable}}
diff --git a/contrib/tcl/tests/assocd.test b/contrib/tcl/tests/assocd.test
new file mode 100644
index 0000000..20e8223
--- /dev/null
+++ b/contrib/tcl/tests/assocd.test
@@ -0,0 +1,57 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# "@(#) assocd.test 1.5 95/08/02 17:11:37"
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+if {[string compare testsetassocdata [info commands testsetassocdata]] != 0} {
+ puts "This application hasn't been compiled with the tests for assocData,"
+ puts "therefore I am skipping all of these tests."
+ return
+}
+
+test assocd-1.1 {testing setting assoc data} {
+ testsetassocdata a 1
+} ""
+test assocd-1.2 {testing setting assoc data} {
+ testsetassocdata a 2
+} ""
+test assocd-1.3 {testing setting assoc data} {
+ testsetassocdata 123 456
+} ""
+test assocd-1.4 {testing setting assoc data} {
+ testsetassocdata abc "abc d e f"
+} ""
+
+test assocd-2.1 {testing getting assoc data} {
+ testgetassocdata a
+} 2
+test assocd-2.2 {testing getting assoc data} {
+ testgetassocdata 123
+} 456
+test assocd-2.3 {testing getting assoc data} {
+ testgetassocdata abc
+} {abc d e f}
+test assocd-2.4 {testing getting assoc data} {
+ testgetassocdata xxx
+} ""
+
+test assocd-3.1 {testing deleting assoc data} {
+ testdelassocdata a
+} ""
+test assocd-3.2 {testing deleting assoc data} {
+ testdelassocdata 123
+} ""
+test assocd-3.3 {testing deleting assoc data} {
+ list [catch {testdelassocdata nonexistent} msg] $msg
+} {0 {}}
diff --git a/contrib/tcl/tests/async.test b/contrib/tcl/tests/async.test
new file mode 100644
index 0000000..cfc572c
--- /dev/null
+++ b/contrib/tcl/tests/async.test
@@ -0,0 +1,131 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) async.test 1.5 96/04/05 15:29:38
+
+if {[info commands testasync] == {}} {
+ puts "This application hasn't been compiled with the \"testasync\""
+ puts "command, so I can't test Tcl_AsyncCreate et al."
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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
+}
+
+set handler1 [testasync create async1]
+set handler2 [testasync create async2]
+set handler3 [testasync create async3]
+test async-1.1 {basic async handlers} {
+ 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} {
+ 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} {
+ 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} {
+ 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} {
+ set aresult xxx
+ list [catch {testasync mark $handler3 "foobar" 0} msg] $msg $aresult
+} {0 foobar {test pattern}}
+test async-1.6 {basic async handlers} {
+ set aresult xxx
+ list [catch {testasync mark $handler3 "foobar" 1} msg] $msg $aresult
+} {1 foobar {test pattern}}
+
+proc mult1 {result code} {
+ global x
+ lappend x mult1
+ return -code 7 mult1
+}
+set hm1 [testasync create mult1]
+proc mult2 {result code} {
+ global x
+ lappend x mult2
+ return -code 9 mult2
+}
+set hm2 [testasync create 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
+}
+set hm3 [testasync create mult3]
+
+test async-2.1 {multiple handlers} {
+ 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
+}
+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} {
+ set x {}
+ list [catch {testasync mark $hm2 "foobar" 5} msg] $msg $x
+} {3 del2 {0 0 0 del1 del2}}
+
+testasync delete
diff --git a/contrib/tcl/tests/case.test b/contrib/tcl/tests/case.test
new file mode 100644
index 0000000..9224372
--- /dev/null
+++ b/contrib/tcl/tests/case.test
@@ -0,0 +1,83 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) case.test 1.13 96/02/16 08:55:41
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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? patList 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}}
diff --git a/contrib/tcl/tests/clock.test b/contrib/tcl/tests/clock.test
new file mode 100644
index 0000000..a14f13a
--- /dev/null
+++ b/contrib/tcl/tests/clock.test
@@ -0,0 +1,101 @@
+# Commands covered: clock
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) clock.test 1.5 96/04/05 15:30:36
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test clock-1.1 {clock tests} {
+ list [catch {clock} msg] $msg
+} {1 {wrong # args: should be "clock option ?arg ...?"}}
+test clock-1.2 {clock tests} {
+ list [catch {clock foo} msg] $msg
+} {1 {unknown option "foo": must be clicks, format, scan, or seconds}}
+
+# clock clicks
+test clock-2.1 {clock clicks tests} {
+ expr [clock clicks]+1
+ concat {}
+} {}
+test clock-2.2 {clock clicks tests} {
+ list [catch {clock clicks foo} msg] $msg
+} {1 {wrong # arguments: must be "clock clicks"}}
+test clock-2.3 {clock clicks tests} {
+ set start [clock clicks]
+ after 10
+ set end [clock clicks]
+ expr "$end > $start"
+} {1}
+
+# clock format
+test clock-3.1 {clock format tests} {unixOnly} {
+ set clockval 657687766
+ clock format $clockval -format {%a %b %d %I:%M:%S %p %Y} -gmt true
+} {Sun Nov 04 03:02:46 AM 1990}
+test clock-3.2 {clock format tests} {
+ list [catch {clock format} msg] $msg
+} {1 {wrong # args: clock format clockval ?-format string? ?-gmt boolean?}}
+test clock-3.3 {clock format tests} {
+ list [catch {clock format foo} msg] $msg
+} {1 {expected unsigned time but got "foo"}}
+test clock-3.4 {clock format tests} {unixOnly} {
+ set clockval 657687766
+ clock format $clockval -format "%a %b %d %I:%M:%S %p %Y" -gmt true
+} "Sun Nov 04 03:02:46 AM 1990"
+
+# clock scan
+test clock-4.1 {clock scan tests} {
+ list [catch {clock scan} msg] $msg
+} {1 {wrong # args: clock scan dateString ?-base clockValue? ?-gmt boolean?}}
+test clock-4.2 {clock scan tests} {
+ list [catch {clock scan "bad-string"} msg] $msg
+} {1 {unable to convert date-time string "bad-string"}}
+test clock-4.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-4.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-4.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-4.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-4.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-4.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}
+
+# clock seconds
+test clock-5.1 {clock seconds tests} {
+ expr [clock seconds]+1
+ concat {}
+} {}
+test clock-5.2 {clock seconds tests} {
+ list [catch {clock seconds foo} msg] $msg
+} {1 {wrong # arguments: must be "clock seconds"}}
+test clock-5.3 {clock seconds tests} {
+ set start [clock seconds]
+ after 2000
+ set end [clock seconds]
+ expr "$end > $start"
+} {1}
+
diff --git a/contrib/tcl/tests/cmdAH.test b/contrib/tcl/tests/cmdAH.test
new file mode 100644
index 0000000..058ee73
--- /dev/null
+++ b/contrib/tcl/tests/cmdAH.test
@@ -0,0 +1,1132 @@
+# 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 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.
+#
+# SCCS: @(#) cmdah.test 1.7 96/04/12 10:49:01
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+global env
+set platform [testgetplatform]
+
+test cmdah-1.1 {Tcl_FileCmd} {
+ list [catch file msg] $msg
+} {1 {wrong # args: should be "file option name ?arg ...?"}}
+test cmdah-1.2 {Tcl_FileCmd} {
+ list [catch {file x} msg] $msg
+} {1 {wrong # args: should be "file option name ?arg ...?"}}
+
+# dirname
+
+test cmdah-2.1 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname a b} msg] $msg
+} {1 {wrong # args: should be "file dirname name"}}
+test cmdah-2.2 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ file dirname /a/b
+} /a
+test cmdah-2.3 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ file dirname {}
+} .
+test cmdah-2.4 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ file dirname {}
+} :
+test cmdah-2.5 {Tcl_FileCmd: dirname} {
+ testsetplatform win
+ file dirname {}
+} .
+test cmdah-2.6 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ file dirname .def
+} .
+test cmdah-2.7 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ file dirname a
+} :
+test cmdah-2.8 {Tcl_FileCmd: dirname} {
+ testsetplatform win
+ file dirname a
+} .
+test cmdah-2.9 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ file d a/b/c.d
+} a/b
+test cmdah-2.10 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ file dirname a/b.c/d
+} a/b.c
+test cmdah-2.11 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ file dirname /.
+} /
+test cmdah-2.12 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname /} msg] $msg
+} {0 /}
+test cmdah-2.13 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname /foo} msg] $msg
+} {0 /}
+test cmdah-2.14 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname //foo} msg] $msg
+} {0 /}
+test cmdah-2.15 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname //foo/bar} msg] $msg
+} {0 /foo}
+test cmdah-2.16 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname {//foo\/bar/baz}} msg] $msg
+} {0 {/foo\/bar}}
+test cmdah-2.17 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname {//foo\/bar/baz/blat}} msg] $msg
+} {0 {/foo\/bar/baz}}
+test cmdah-2.18 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname /foo//} msg] $msg
+} {0 /}
+test cmdah-2.19 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname ./a} msg] $msg
+} {0 .}
+test cmdah-2.20 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname a/.a} msg] $msg
+} {0 a}
+test cmdah-2.21 {Tcl_FileCmd: dirname} {
+ testsetplatform windows
+ list [catch {file dirname c:foo} msg] $msg
+} {0 c:}
+test cmdah-2.22 {Tcl_FileCmd: dirname} {
+ testsetplatform windows
+ list [catch {file dirname c:} msg] $msg
+} {0 c:}
+test cmdah-2.23 {Tcl_FileCmd: dirname} {
+ testsetplatform windows
+ list [catch {file dirname c:/} msg] $msg
+} {0 c:/}
+test cmdah-2.24 {Tcl_FileCmd: dirname} {
+ testsetplatform windows
+ list [catch {file dirname {c:\foo}} msg] $msg
+} {0 c:/}
+test cmdah-2.25 {Tcl_FileCmd: dirname} {
+ testsetplatform windows
+ list [catch {file dirname {//foo/bar/baz}} msg] $msg
+} {0 //foo/bar}
+test cmdah-2.26 {Tcl_FileCmd: dirname} {
+ testsetplatform windows
+ list [catch {file dirname {//foo/bar}} msg] $msg
+} {0 //foo/bar}
+test cmdah-2.27 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname :} msg] $msg
+} {0 :}
+test cmdah-2.28 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname :Foo} msg] $msg
+} {0 :}
+test cmdah-2.29 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname Foo:} msg] $msg
+} {0 Foo:}
+test cmdah-2.30 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname Foo:bar} msg] $msg
+} {0 Foo:}
+test cmdah-2.31 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname :Foo:bar} msg] $msg
+} {0 :Foo}
+test cmdah-2.32 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname ::} msg] $msg
+} {0 :}
+test cmdah-2.33 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname :::} msg] $msg
+} {0 ::}
+test cmdah-2.34 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname /foo/bar/} msg] $msg
+} {0 foo:}
+test cmdah-2.35 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname /foo/bar} msg] $msg
+} {0 foo:}
+test cmdah-2.36 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname /foo} msg] $msg
+} {0 foo:}
+test cmdah-2.37 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname foo} msg] $msg
+} {0 :}
+test cmdah-2.38 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname ~/foo} msg] $msg
+} {0 ~}
+test cmdah-2.39 {Tcl_FileCmd: dirname} {
+ testsetplatform unix
+ list [catch {file dirname ~bar/foo} msg] $msg
+} {0 ~bar}
+test cmdah-2.40 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname ~bar/foo} msg] $msg
+} {0 ~bar:}
+test cmdah-2.41 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname ~/foo} msg] $msg
+} {0 ~:}
+test cmdah-2.42 {Tcl_FileCmd: dirname} {
+ testsetplatform mac
+ list [catch {file dirname ~:baz} msg] $msg
+} {0 ~:}
+test cmdah-2.43 {Tcl_FileCmd: dirname} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ set result [list [catch {file dirname ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 /home}
+test cmdah-2.44 {Tcl_FileCmd: dirname} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "~"
+ testsetplatform unix
+ set result [list [catch {file dirname ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 ~}
+test cmdah-2.45 {Tcl_FileCmd: dirname} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform windows
+ set result [list [catch {file dirname ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 /home}
+test cmdah-2.46 {Tcl_FileCmd: dirname} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform mac
+ set result [list [catch {file dirname ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 home:}
+
+# tail
+
+test cmdah-3.1 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ list [catch {file tail a b} msg] $msg
+} {1 {wrong # args: should be "file tail name"}}
+test cmdah-3.2 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail /a/b
+} b
+test cmdah-3.3 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail {}
+} {}
+test cmdah-3.4 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail {}
+} {}
+test cmdah-3.5 {Tcl_FileCmd: tail} {
+ testsetplatform win
+ file tail {}
+} {}
+test cmdah-3.6 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail .def
+} .def
+test cmdah-3.7 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail a
+} a
+test cmdah-3.8 {Tcl_FileCmd: tail} {
+ testsetplatform win
+ file tail a
+} a
+test cmdah-3.9 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file ta a/b/c.d
+} c.d
+test cmdah-3.10 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail a/b.c/d
+} d
+test cmdah-3.11 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail /.
+} .
+test cmdah-3.12 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail /
+} {}
+test cmdah-3.13 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail /foo
+} foo
+test cmdah-3.14 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail //foo
+} foo
+test cmdah-3.15 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail //foo/bar
+} bar
+test cmdah-3.16 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail {//foo\/bar/baz}
+} baz
+test cmdah-3.17 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail {//foo\/bar/baz/blat}
+} blat
+test cmdah-3.18 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail /foo//
+} foo
+test cmdah-3.19 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail ./a
+} a
+test cmdah-3.20 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail a/.a
+} .a
+test cmdah-3.21 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail c:foo
+} foo
+test cmdah-3.22 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail c:
+} {}
+test cmdah-3.23 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail c:/
+} {}
+test cmdah-3.24 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail {c:\foo}
+} foo
+test cmdah-3.25 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail {//foo/bar/baz}
+} baz
+test cmdah-3.26 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail {//foo/bar}
+} {}
+test cmdah-3.27 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail :
+} :
+test cmdah-3.28 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail :Foo
+} Foo
+test cmdah-3.29 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail Foo:
+} {}
+test cmdah-3.30 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail Foo:bar
+} bar
+test cmdah-3.31 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail :Foo:bar
+} bar
+test cmdah-3.32 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail ::
+} ::
+test cmdah-3.33 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail :::
+} ::
+test cmdah-3.34 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail /foo/bar/
+} bar
+test cmdah-3.35 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail /foo/bar
+} bar
+test cmdah-3.36 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail /foo
+} {}
+test cmdah-3.37 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail foo
+} foo
+test cmdah-3.38 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail ~:foo
+} foo
+test cmdah-3.39 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail ~bar:foo
+} foo
+test cmdah-3.40 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail ~bar/foo
+} foo
+test cmdah-3.41 {Tcl_FileCmd: tail} {
+ testsetplatform mac
+ file tail ~/foo
+} foo
+test cmdah-3.42 {Tcl_FileCmd: tail} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ set result [file tail ~]
+ set env(HOME) $temp
+ set result
+} {}
+test cmdah-3.43 {Tcl_FileCmd: tail} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "~"
+ testsetplatform unix
+ set result [file tail ~]
+ set env(HOME) $temp
+ set result
+} {}
+test cmdah-3.44 {Tcl_FileCmd: tail} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform windows
+ set result [file tail ~]
+ set env(HOME) $temp
+ set result
+} {}
+test cmdah-3.45 {Tcl_FileCmd: tail} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform mac
+ set result [file tail ~]
+ set env(HOME) $temp
+ set result
+} {}
+test cmdah-3.46 {Tcl_FileCmd: tail} {
+ testsetplatform unix
+ file tail {f.oo\bar/baz.bat}
+} baz.bat
+test cmdah-3.47 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail c:foo
+} foo
+test cmdah-3.48 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail c:
+} {}
+test cmdah-3.49 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail c:/foo
+} foo
+test cmdah-3.50 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail {c:/foo\bar}
+} bar
+test cmdah-3.51 {Tcl_FileCmd: tail} {
+ testsetplatform windows
+ file tail {foo\bar}
+} bar
+
+# rootname
+
+test cmdah-4.1 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ list [catch {file rootname a b} msg] $msg
+} {1 {wrong # args: should be "file rootname name"}}
+test cmdah-4.2 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname {}
+} {}
+test cmdah-4.3 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file ro foo
+} foo
+test cmdah-4.4 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname foo.
+} foo
+test cmdah-4.5 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname .foo
+} {}
+test cmdah-4.6 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname abc.def
+} abc
+test cmdah-4.7 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname abc.def.ghi
+} abc.def
+test cmdah-4.8 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname a/b/c.d
+} a/b/c
+test cmdah-4.9 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdah-4.10 {Tcl_FileCmd: rootname} {
+ testsetplatform unix
+ file rootname a/b.c/
+} a/b.c/
+test cmdah-4.11 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file ro foo
+} foo
+test cmdah-4.12 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname {}
+} {}
+test cmdah-4.13 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname foo.
+} foo
+test cmdah-4.14 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname .foo
+} {}
+test cmdah-4.15 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname abc.def
+} abc
+test cmdah-4.16 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname abc.def.ghi
+} abc.def
+test cmdah-4.17 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname a:b:c.d
+} a:b:c
+test cmdah-4.18 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname a:b.c:d
+} a:b.c:d
+test cmdah-4.19 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname a/b/c.d
+} a/b/c
+test cmdah-4.20 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdah-4.21 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname /a.b
+} /a
+test cmdah-4.22 {Tcl_FileCmd: rootname} {
+ testsetplatform mac
+ file rootname foo.c:
+} foo.c:
+test cmdah-4.23 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname {}
+} {}
+test cmdah-4.24 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file ro foo
+} foo
+test cmdah-4.25 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname foo.
+} foo
+test cmdah-4.26 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname .foo
+} {}
+test cmdah-4.27 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname abc.def
+} abc
+test cmdah-4.28 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname abc.def.ghi
+} abc.def
+test cmdah-4.29 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname a/b/c.d
+} a/b/c
+test cmdah-4.30 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname a/b.c/d
+} a/b.c/d
+test cmdah-4.31 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname a\\b.c\\
+} a\\b.c\\
+test cmdah-4.32 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname a\\b\\c.d
+} a\\b\\c
+test cmdah-4.33 {Tcl_FileCmd: rootname} {
+ testsetplatform windows
+ file rootname a\\b.c\\d
+} a\\b.c\\d
+test cmdah-4.34 {Tcl_FileCmd: rootname} {
+ 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-4.$num {Tcl_FileCmd: rootname and extension options} {
+ testsetplatform unix
+ format %s%s [file rootname $thing] [file ext $thing]
+ } $thing
+ set num [expr $num+1]
+ }
+}
+
+# extension
+
+test cmdah-5.1 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ list [catch {file extension a b} msg] $msg
+} {1 {wrong # args: should be "file extension name"}}
+test cmdah-5.2 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension {}
+} {}
+test cmdah-5.3 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file ext foo
+} {}
+test cmdah-5.4 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension foo.
+} .
+test cmdah-5.5 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension .foo
+} .foo
+test cmdah-5.6 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension abc.def
+} .def
+test cmdah-5.7 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension abc.def.ghi
+} .ghi
+test cmdah-5.8 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension a/b/c.d
+} .d
+test cmdah-5.9 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension a/b.c/d
+} {}
+test cmdah-5.10 {Tcl_FileCmd: extension} {
+ testsetplatform unix
+ file extension a/b.c/
+} {}
+test cmdah-5.11 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file ext foo
+} {}
+test cmdah-5.12 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension {}
+} {}
+test cmdah-5.13 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension foo.
+} .
+test cmdah-5.14 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension .foo
+} .foo
+test cmdah-5.15 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension abc.def
+} .def
+test cmdah-5.16 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension abc.def.ghi
+} .ghi
+test cmdah-5.17 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension a:b:c.d
+} .d
+test cmdah-5.18 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension a:b.c:d
+} {}
+test cmdah-5.19 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension a/b/c.d
+} .d
+test cmdah-5.20 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension a/b.c/d
+} {}
+test cmdah-5.21 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension /a.b
+} .b
+test cmdah-5.22 {Tcl_FileCmd: extension} {
+ testsetplatform mac
+ file extension foo.c:
+} {}
+test cmdah-5.23 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension {}
+} {}
+test cmdah-5.24 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file ext foo
+} {}
+test cmdah-5.25 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension foo.
+} .
+test cmdah-5.26 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension .foo
+} .foo
+test cmdah-5.27 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension abc.def
+} .def
+test cmdah-5.28 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension abc.def.ghi
+} .ghi
+test cmdah-5.29 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension a/b/c.d
+} .d
+test cmdah-5.30 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension a/b.c/d
+} {}
+test cmdah-5.31 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension a\\b.c\\
+} {}
+test cmdah-5.32 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension a\\b\\c.d
+} .d
+test cmdah-5.33 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension a\\b.c\\d
+} {}
+test cmdah-5.34 {Tcl_FileCmd: extension} {
+ testsetplatform windows
+ file extension a\\b.c\\
+} {}
+
+# pathtype
+
+test cmdah-6.1 {Tcl_FileCmd: pathtype} {
+ testsetplatform unix
+ list [catch {file pathtype a b} msg] $msg
+} {1 {wrong # args: should be "file pathtype name"}}
+test cmdah-6.2 {Tcl_FileCmd: pathtype} {
+ testsetplatform unix
+ file pathtype /a
+} absolute
+test cmdah-6.3 {Tcl_FileCmd: pathtype} {
+ testsetplatform unix
+ file p a
+} relative
+test cmdah-6.4 {Tcl_FileCmd: pathtype} {
+ testsetplatform windows
+ file pathtype c:a
+} volumerelative
+
+# split
+
+test cmdah-7.1 {Tcl_FileCmd: split} {
+ testsetplatform unix
+ list [catch {file split a b} msg] $msg
+} {1 {wrong # args: should be "file split name"}}
+test cmdah-7.2 {Tcl_FileCmd: split} {
+ testsetplatform unix
+ file split a
+} a
+test cmdah-7.3 {Tcl_FileCmd: split} {
+ testsetplatform unix
+ file split a/b
+} {a b}
+
+# join
+
+test cmdah-8.1 {Tcl_FileCmd: join} {
+ testsetplatform unix
+ file join a
+} a
+test cmdah-8.2 {Tcl_FileCmd: join} {
+ testsetplatform unix
+ file join a b
+} a/b
+test cmdah-8.3 {Tcl_FileCmd: join} {
+ testsetplatform unix
+ file join a b c d
+} a/b/c/d
+
+# error handling of Tcl_TranslateFileName
+
+test cmdah-9.1 {Tcl_FileCmd} {
+ testsetplatform unix
+ list [catch {file readable ~_bad_user} msg] $msg
+} {1 {user "_bad_user" doesn't exist}}
+
+makeFile abcde gorp.file
+makeDirectory dir.file
+
+# readable
+# Can't run on macintosh - requires chmod
+if {$tcl_platform(platform) != "macintosh"} {
+
+test cmdah-10.1 {Tcl_FileCmd: readable} {
+ list [catch {file readable a b} msg] $msg
+} {1 {wrong # args: should be "file readable name"}}
+catch {exec chmod 444 gorp.file}
+test cmdah-10.2 {Tcl_FileCmd: readable} {unixExecs} {file readable gorp.file} 1
+catch {exec chmod 333 gorp.file}
+if {$user != "root"} {
+ test cmdah-10.3 {Tcl_FileCmd: readable} {unixOnly} {
+ file reada gorp.file
+ } 0
+}
+}
+
+# writable
+# Can't run on macintosh - requires chmod
+if {$tcl_platform(platform) != "macintosh"} {
+
+test cmdah-11.1 {Tcl_FileCmd: writable} {
+ list [catch {file writable a b} msg] $msg
+} {1 {wrong # args: should be "file writable name"}}
+catch {exec chmod 555 gorp.file}
+if {$user != "root"} {
+ test cmdah-11.2 {Tcl_FileCmd: writable} {unixExecs} {
+ file writable gorp.file
+ } 0
+}
+catch {exec chmod 222 gorp.file}
+test cmdah-11.3 {Tcl_FileCmd: writable} {unixExecs} {file w gorp.file} 1
+}
+
+# executable
+# Can't run on macintosh - requires chmod
+if {$tcl_platform(platform) != "macintosh"} {
+
+test cmdah-12.1 {Tcl_FileCmd: executable} {unixExecs} {
+ list [catch {file executable a b} msg] $msg
+} {1 {wrong # args: should be "file executable name"}}
+catch {exec chmod 000 dir.file}
+if {$user != "root"} {
+ test cmdah-12.2 {Tcl_FileCmd: executable} {unixOnly} {
+ file executable gorp.file
+ } 0
+}
+catch {exec chmod 775 gorp.file}
+test cmdah-12.3 {Tcl_FileCmd: executable} {unixExecs} {file exe gorp.file} 1
+}
+
+# exists
+
+test cmdah-13.1 {Tcl_FileCmd: exists} {
+ list [catch {file exists a b} msg] $msg
+} {1 {wrong # args: should be "file exists name"}}
+catch {exec chmod 777 dir.file}
+removeFile [file join dir.file gorp.file]
+removeFile gorp.file
+removeDirectory dir.file
+removeFile link.file
+test cmdah-13.2 {Tcl_FileCmd: exists} {file exists gorp.file} 0
+test cmdah-13.3 {Tcl_FileCmd: exists} {
+ file exists [file join dir.file gorp.file]
+} 0
+catch {
+ makeFile abcde gorp.file
+ makeDirectory dir.file
+ makeFile 12345 [file join dir.file gorp.file]
+}
+test cmdah-13.4 {Tcl_FileCmd: exists} {unixExecs} {file exists gorp.file} 1
+test cmdah-13.5 {Tcl_FileCmd: exists} {unixExecs} {
+ file exi [file join dir.file gorp.file]
+} 1
+
+# 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.
+
+if {$tcl_platform(platform) == "unix"} {
+ removeFile /tmp/tcl.foo.dir/file
+ removeDirectory /tmp/tcl.foo.dir
+ makeDirectory /tmp/tcl.foo.dir
+ makeFile 12345 /tmp/tcl.foo.dir/file
+ exec chmod 000 /tmp/tcl.foo.dir
+ if {$user != "root"} {
+ test cmdah-13.3 {Tcl_FileCmd: exists} {
+ file exists /tmp/tcl.foo.dir/file
+ } 0
+ }
+ exec chmod 775 /tmp/tcl.foo.dir
+ removeFile /tmp/tcl.foo.dir/file
+ removeDirectory /tmp/tcl.foo.dir
+}
+
+# Stat related commands
+
+removeFile gorp.file
+makeFile "Test string" gorp.file
+catch {exec chmod 765 gorp.file}
+
+# atime
+
+test cmdah-14.1 {Tcl_FileCmd: atime} {
+ list [catch {file atime a b} msg] $msg
+} {1 {wrong # args: should be "file atime name"}}
+test cmdah-14.2 {Tcl_FileCmd: atime} {
+ catch {unset stat}
+ file stat gorp.file stat
+ list [expr {[file mtime gorp.file] == $stat(mtime)}] \
+ [expr {[file atime gorp.file] == $stat(atime)}]
+} {1 1}
+test cmdah-12.1 {Tcl_FileCmd: atime} {
+ string tolower [list [catch {file atime _bogus_} msg] \
+ $msg $errorCode]
+} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+
+# isdirectory
+
+test cmdah-15.1 {Tcl_FileCmd: isdirectory} {
+ list [catch {file isdirectory a b} msg] $msg
+} {1 {wrong # args: should be "file isdirectory name"}}
+test cmdah-15.2 {Tcl_FileCmd: isdirectory} {file isdirectory gorp.file} 0
+test cmdah-15.3 {Tcl_FileCmd: isdirectory} {unixExecs} {file isd dir.file} 1
+
+# isfile
+
+test cmdah-15.4 {Tcl_FileCmd: isfile} {
+ list [catch {file isfile a b} msg] $msg
+} {1 {wrong # args: should be "file isfile name"}}
+test cmdah-15.5 {Tcl_FileCmd: isfile} {file isfile gorp.file} 1
+test cmdah-15.6 {Tcl_FileCmd: isfile} {file isfile dir.file} 0
+
+# lstat and readlink: don't run these tests everywhere, since not all
+# sites will have symbolic links
+
+catch {exec ln -s gorp.file link.file}
+test cmdah-16.1 {Tcl_FileCmd: lstat} {unixExecs} {
+ list [catch {file lstat a} msg] $msg
+} {1 {wrong # args: should be "file lstat name varName"}}
+test cmdah-16.2 {Tcl_FileCmd: lstat} {unixExecs} {
+ list [catch {file lstat a b c} msg] $msg
+} {1 {wrong # args: should be "file lstat name varName"}}
+test cmdah-16.3 {Tcl_FileCmd: lstat} {unixOnly nonPortable} {
+ catch {unset stat}
+ file lstat link.file stat
+ lsort [array names stat]
+} {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdah-16.4 {Tcl_FileCmd: lstat} {unixOnly nonPortable} {
+ catch {unset stat}
+ file lstat link.file stat
+ list $stat(nlink) [expr $stat(mode)&0777] $stat(type)
+} {1 511 link}
+test cmdah-16.5 {Tcl_FileCmd: lstat errors} {nonPortable} {
+ string tolower [list [catch {file lstat _bogus_ stat} msg] \
+ $msg $errorCode]
+} {1 {couldn't lstat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+test cmdah-16.6 {Tcl_FileCmd: lstat errors} {unixExecs nonPortable} {
+ catch {unset x}
+ set x 44
+ list [catch {file lstat gorp.file x} msg] $msg $errorCode
+} {1 {can't set "x(dev)": variable isn't array} NONE}
+catch {unset stat}
+
+# mtime
+
+test cmdah-17.1 {Tcl_FileCmd: mtime} {
+ list [catch {file mtime a b} msg] $msg
+} {1 {wrong # args: should be "file mtime name"}}
+test cmdah-17.2 {Tcl_FileCmd: mtime} {unixExecs} {
+ set old [file mtime gorp.file]
+ after 2000
+ set f [open gorp.file w]
+ puts $f "More text"
+ close $f
+ set new [file mtime gorp.file]
+ expr {($new > $old) && ($new <= ($old+5))}
+} {1}
+test cmdah-17.3 {Tcl_FileCmd: mtime} {unixExecs} {
+ catch {unset stat}
+ file stat gorp.file stat
+ list [expr {[file mtime gorp.file] == $stat(mtime)}] \
+ [expr {[file atime gorp.file] == $stat(atime)}]
+} {1 1}
+test cmdah-17.4 {Tcl_FileCmd: mtime} {unixExecs} {
+ string tolower [list [catch {file mtime _bogus_} msg] $msg \
+ $errorCode]
+} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+
+# owned
+
+test cmdah-18.1 {Tcl_FileCmd: owned} {
+ list [catch {file owned a b} msg] $msg
+} {1 {wrong # args: should be "file owned name"}}
+test cmdah-18.2 {Tcl_FileCmd: owned} {unixExecs} {file owned gorp.file} 1
+if {$user != "root"} {
+ test cmdah-18.3 {Tcl_FileCmd: owned} {unixOnly} {file owned /} 0
+}
+
+# readlink
+
+test cmdah-19.1 {Tcl_FileCmd: readlink} {
+ list [catch {file readlink a b} msg] $msg
+} {1 {wrong # args: should be "file readlink name"}}
+test cmdah-19.2 {Tcl_FileCmd: readlink} {unixOnly nonPortable} {
+ file readlink link.file
+} gorp.file
+test cmdah-19.3 {Tcl_FileCmd: readlink errors} {unixOnly nonPortable} {
+ list [catch {file readlink _bogus_} msg] [string tolower $msg] \
+ [string tolower $errorCode]
+} {1 {couldn't readlink "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+test cmdah-19.4 {Tcl_FileCmd: readlink errors} {macOrPc nonPortable} {
+ list [catch {file readlink _bogus_} msg] [string tolower $msg] \
+ [string tolower $errorCode]
+} {1 {couldn't readlink "_bogus_": invalid argument} {posix einval {invalid argument}}}
+
+# size
+
+test cmdah-20.1 {Tcl_FileCmd: size} {
+ list [catch {file size a b} msg] $msg
+} {1 {wrong # args: should be "file size name"}}
+test cmdah-20.2 {Tcl_FileCmd: size} {
+ set oldsize [file size gorp.file]
+ set f [open gorp.file a]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "More text"
+ close $f
+ expr {[file size gorp.file] - $oldsize}
+} {10}
+test cmdah-20.3 {Tcl_FileCmd: size} {
+ string tolower [list [catch {file size _bogus_} msg] $msg \
+ $errorCode]
+} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+
+# stat
+
+makeFile "Test string" gorp.file
+catch {exec chmod 765 gorp.file}
+
+test cmdah-21.1 {Tcl_FileCmd: stat} {
+ list [catch {file stat _bogus_} msg] $msg $errorCode
+} {1 {wrong # args: should be "file stat name varName"} NONE}
+test cmdah-21.2 {Tcl_FileCmd: stat} {
+ list [catch {file stat _bogus_ a b} msg] $msg $errorCode
+} {1 {wrong # args: should be "file stat name varName"} NONE}
+test cmdah-21.3 {Tcl_FileCmd: stat} {
+ catch {unset stat}
+ file stat gorp.file stat
+ lsort [array names stat]
+} {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdah-21.4 {Tcl_FileCmd: stat} {unixOnly} {
+ catch {unset stat}
+ file stat gorp.file stat
+ list $stat(nlink) $stat(size) [expr $stat(mode)&0777] $stat(type)
+} {1 12 501 file}
+test cmdah-21.5 {Tcl_FileCmd: stat} {
+ string tolower [list [catch {file stat _bogus_ stat} msg] \
+ $msg $errorCode]
+} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+test cmdah-21.6 {Tcl_FileCmd: stat} {
+ catch {unset x}
+ set x 44
+ list [catch {file stat gorp.file x} msg] $msg $errorCode
+} {1 {can't set "x(dev)": variable isn't array} NONE}
+catch {unset stat}
+
+# type
+
+removeFile link.file
+
+test cmdah-22.1 {Tcl_FileCmd: type} {
+ list [catch {file size a b} msg] $msg
+} {1 {wrong # args: should be "file size name"}}
+test cmdah-22.2 {Tcl_FileCmd: type} {unixExecs} {
+ file type dir.file
+} directory
+test cmdah-22.3 {Tcl_FileCmd: type} {
+ file type gorp.file
+} file
+test cmdah-22.4 {Tcl_FileCmd: type} {unixOnly nonPortable} {
+ exec ln -s a/b/c link.file
+ set result [file type link.file]
+ removeFile link.file
+ set result
+} link
+test cmdah-22.5 {Tcl_FileCmd: type} {
+ string tolower [list [catch {file type _bogus_} msg] $msg $errorCode]
+} {1 {couldn't stat "_bogus_": no such file or directory} {posix enoent {no such file or directory}}}
+
+# Error conditions
+
+test cmdah-23.1 {error conditions} {
+ list [catch {file gorp x} msg] $msg
+} {1 {bad option "gorp": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.2 {error conditions} {
+ list [catch {file ex x} msg] $msg
+} {1 {bad option "ex": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.3 {error conditions} {
+ list [catch {file is x} msg] $msg
+} {1 {bad option "is": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.4 {error conditions} {
+ list [catch {file n x} msg] $msg
+} {1 {bad option "n": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.5 {error conditions} {
+ list [catch {file read x} msg] $msg
+} {1 {bad option "read": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.6 {error conditions} {
+ list [catch {file s x} msg] $msg
+} {1 {bad option "s": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.7 {error conditions} {
+ list [catch {file t x} msg] $msg
+} {1 {bad option "t": should be atime, dirname, executable, exists, extension, isdirectory, isfile, join, lstat, mtime, owned, pathtype, readable, readlink, root, size, split, stat, tail, type, or writable}}
+test cmdah-23.8 {error conditions} {
+ list [catch {file dirname ~woohgy} msg] $msg
+} {1 {user "woohgy" doesn't exist}}
+
+catch {exec chmod 777 dir.file}
+removeFile dir.file/gorp.file
+removeFile gorp.file
+removeDirectory dir.file
+removeFile link.file
+
+testsetplatform $platform
+catch {unset platform}
+concat ""
diff --git a/contrib/tcl/tests/cmdInfo.test b/contrib/tcl/tests/cmdInfo.test
new file mode 100644
index 0000000..3034929
--- /dev/null
+++ b/contrib/tcl/tests/cmdInfo.test
@@ -0,0 +1,74 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) cmdinfo.test 1.5 96/04/05 15:28:12
+
+if {[info commands testcmdinfo] == {}} {
+ puts "This application hasn't been compiled with the \"testcmdinfo\""
+ puts "command, so I can't test Tcl_GetCommandInfo etc."
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test cmdinfo-1.1 {command procedure and clientData} {
+ testcmdinfo create x1
+ testcmdinfo get x1
+} {CmdProc1 original CmdDelProc1 original}
+test cmdinfo-1.2 {command procedure and clientData} {
+ testcmdinfo create x1
+ x1
+} {CmdProc1 original}
+test cmdinfo-1.3 {command procedure and clientData} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ testcmdinfo get x1
+} {CmdProc2 new_command_data CmdDelProc2 new_delete_data}
+test cmdinfo-1.4 {command procedure and clientData} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ x1
+} {CmdProc2 new_command_data}
+
+test cmdinfo-2.1 {command deletion callbacks} {
+ testcmdinfo create x1
+ testcmdinfo delete x1
+} {CmdDelProc1 original}
+test cmdinfo-2.2 {command deletion callbacks} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+ testcmdinfo delete x1
+} {CmdDelProc2 new_delete_data}
+
+test cmdinfo-3.1 {Tcl_Get/SetCommandInfo return values} {
+ testcmdinfo get non_existent
+} {??}
+test cmdinfo-3.2 {Tcl_Get/SetCommandInfo return values} {
+ testcmdinfo create x1
+ testcmdinfo modify x1
+} 1
+test cmdinfo-3.3 {Tcl_Get/SetCommandInfo return values} {
+ testcmdinfo modify non_existent
+} 0
+
+test cmdinfo-4.1 {Tcl_GetCommandName procedure} {
+ set x [testcmdtoken create x1]
+ rename x1 newName
+ set y [testcmdtoken name $x]
+ rename newName x1
+ lappend y [testcmdtoken name $x]
+} {newName x1}
+
+catch {rename x1 ""}
+concat {}
diff --git a/contrib/tcl/tests/concat.test b/contrib/tcl/tests/concat.test
new file mode 100644
index 0000000..b86aeed
--- /dev/null
+++ b/contrib/tcl/tests/concat.test
@@ -0,0 +1,39 @@
+# 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 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) concat.test 1.8 96/02/16 08:55:43
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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: no arguments} {
+ list [catch concat msg] $msg
+} {0 {}}
+
+test concat-3.1 {pruning off extra white space} {
+ concat {} {a b c}
+} {a b c}
+test concat-3.2 {pruning off extra white space} {
+ concat x y " a b c \n\t " " " " def "
+} {x y a b c def}
diff --git a/contrib/tcl/tests/dcall.test b/contrib/tcl/tests/dcall.test
new file mode 100644
index 0000000..c7ad1c6
--- /dev/null
+++ b/contrib/tcl/tests/dcall.test
@@ -0,0 +1,40 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) dcall.test 1.6 96/02/16 08:55:44
+
+if {[info commands testdcall] == {}} {
+ puts "This application hasn't been compiled with the \"testdcall\""
+ puts "command, so I can't test Tcl_CallWhenDeleted."
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test dcall-1.1 {deletion callbacks} {
+ lsort -increasing [testdcall 1 2 3]
+} {1 2 3}
+test dcall-1.2 {deletion callbacks} {
+ testdcall
+} {}
+test dcall-1.3 {deletion callbacks} {
+ lsort -increasing [testdcall 20 21 22 -22]
+} {20 21}
+test dcall-1.4 {deletion callbacks} {
+ lsort -increasing [testdcall 20 21 22 -20]
+} {21 22}
+test dcall-1.5 {deletion callbacks} {
+ lsort -increasing [testdcall 20 21 22 -21]
+} {20 22}
+test dcall-1.6 {deletion callbacks} {
+ lsort -increasing [testdcall 20 21 22 -21 -22 -20]
+} {}
diff --git a/contrib/tcl/tests/defs b/contrib/tcl/tests/defs
new file mode 100644
index 0000000..aaf6cfc
--- /dev/null
+++ b/contrib/tcl/tests/defs
@@ -0,0 +1,346 @@
+# This file contains support code for the Tcl test suite. It is
+# normally sourced by the individual files in the test suite before
+# they run their tests. This improved approach to testing was designed
+# and initially implemented by Mary Ann May-Pumphrey of Sun Microsystems.
+#
+# 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.
+#
+# SCCS: @(#) defs 1.37 96/04/12 13:45:04
+
+if ![info exists VERBOSE] {
+ set VERBOSE 0
+}
+if ![info exists TESTS] {
+ set TESTS {}
+}
+
+# If tests are being run as root, issue a warning message and set a
+# variable to prevent some tests from running at all.
+
+set user {}
+catch {set user [exec whoami]}
+if {$user == "root"} {
+ puts stdout "Warning: you're executing as root. I'll have to"
+ puts stdout "skip some of the tests, since they'll fail as root."
+}
+
+# Some of the tests don't work on some system configurations due to
+# differences in word length, file system configuration, etc. In order
+# to prevent false alarms, these tests are generally only run in the
+# master development directory for Tcl. The presence of a file
+# "doAllTests" in this directory is used to indicate that the non-portable
+# tests should be run.
+
+set doNonPortableTests [file exists doAllTests]
+
+# If there is no "memory" command (because memory debugging isn't
+# enabled), generate a dummy command that does nothing.
+
+if {[info commands memory] == ""} {
+ proc memory args {}
+}
+
+# Check configuration information that will determine which tests
+# to run. To do this, create an array testConfig. Each element
+# has a 0 or 1 value, and the following elements are defined:
+# unixOnly - 1 means this is a UNIX platform, so it's OK
+# to run tests that only work under UNIX.
+# macOnly - 1 means this is a Mac platform, so it's OK
+# to run tests that only work on Macs.
+# pcOnly - 1 means this is a PC platform, so it's OK to
+# run tests that only work on PCs.
+# unixOrPc - 1 means this is a UNIX or PC platform.
+# macOrPc - 1 means this is a Mac or PC platform.
+# nonPortable - 1 means this the tests are being running in
+# the master Tcl/Tk development environment;
+# Some tests are inherently non-portable because
+# they depend on things like word length, file system
+# configuration, window manager, etc. These tests
+# are only run in the main Tcl development directory
+# where the configuration is well known. The presence
+# of the file "doAllTests" in this directory indicates
+# that it is safe to run non-portable tests.
+# tempNotPc - The inverse of pcOnly. This flag is used to
+# temporarily disable a test.
+# nonBlockFiles - 1 means this platform supports setting files into
+# nonblocking mode.
+# asyncPipeClose- 1 means this platform supports async flush and
+# async close on a pipe.
+# unixExecs - 1 means this machine has commands such as 'cat',
+# 'echo' etc available.
+
+catch {unset testConfig}
+if {$tcl_platform(platform) == "unix"} {
+ set testConfig(unixOnly) 1
+ set testConfig(tempNotPc) 1
+} else {
+ set testConfig(unixOnly) 0
+}
+if {$tcl_platform(platform) == "macintosh"} {
+ set testConfig(tempNotPc) 1
+ set testConfig(macOnly) 1
+} else {
+ set testConfig(macOnly) 0
+}
+if {$tcl_platform(platform) == "windows"} {
+ set testConfig(pcOnly) 1
+} else {
+ set testConfig(pcOnly) 0
+}
+set testConfig(unixOrPc) [expr $testConfig(unixOnly) || $testConfig(pcOnly)]
+set testConfig(macOrPc) [expr $testConfig(macOnly) || $testConfig(pcOnly)]
+set testConfig(nonPortable) [file exists doAllTests]
+
+set f [open defs r]
+if {[expr [catch {fconfigure $f -blocking off}]] == 0} {
+ set testConfig(nonBlockFiles) 1
+} else {
+ set testConfig(nonBlockFiles) 0
+}
+close $f
+
+# Test for SCO Unix - cannot run async flushing tests because a potential
+# problem with select is apparently interfering. (Mark Diekhans).
+
+if {$tcl_platform(platform) == "unix"} {
+ if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} {
+ set testConfig(asyncPipeClose) 0
+ } else {
+ set testConfig(asyncPipeClose) 1
+ }
+} else {
+ set testConfig(asyncPipeClose) 1
+}
+
+# Test to see if execed commands such as cat, echo, rm and so forth are
+# present on this machine.
+
+set testConfig(unixExecs) 1
+if {$tcl_platform(platform) == "macintosh"} {
+ set testConfig(unixExecs) 0
+}
+if {($testConfig(unixExecs) == 1) && ($tcl_platform(platform) == "windows")} {
+ if {[catch {exec cat defs}] == 1} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec echo hello}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec sh -c echo hello}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec wc defs}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {$testConfig(unixExecs) == 1} {
+ exec echo hello > removeMe
+ if {[catch {exec rm removeMe}] == 1} {
+ set testConfig(unixExecs) 0
+ }
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec sleep 1}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec fgrep unixExecs defs}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && ([catch {exec ps}] == 1)} {
+ set testConfig(unixExecs) 0
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec echo abc > removeMe}] == 0) && \
+ ([catch {exec chmod 644 removeMe}] == 1) && \
+ ([catch {exec rm removeMe}] == 0)} {
+ set testConfig(unixExecs) 0
+ } else {
+ catch {exec rm -f removeMe}
+ }
+ if {($testConfig(unixExecs) == 1) && \
+ ([catch {exec mkdir removeMe}] == 1)} {
+ set testConfig(unixExecs) 0
+ } else {
+ catch {exec rm -r removeMe}
+ }
+}
+
+proc print_verbose {name description script code answer} {
+ puts stdout "\n"
+ puts stdout "==== $name $description"
+ puts stdout "==== Contents of test case:"
+ puts stdout "$script"
+ if {$code != 0} {
+ if {$code == 1} {
+ puts stdout "==== Test generated error:"
+ puts stdout $answer
+ } elseif {$code == 2} {
+ puts stdout "==== Test generated return exception; result was:"
+ puts stdout $answer
+ } elseif {$code == 3} {
+ puts stdout "==== Test generated break exception"
+ } elseif {$code == 4} {
+ puts stdout "==== Test generated continue exception"
+ } else {
+ puts stdout "==== Test generated exception $code; message was:"
+ puts stdout $answer
+ }
+ } else {
+ puts stdout "==== Result was:"
+ puts stdout "$answer"
+ }
+}
+
+# test --
+# This procedure runs a test and prints an error message if the
+# test fails. If VERBOSE has been set, it also prints a message
+# even if the test succeeds. The test will be skipped if it
+# doesn't match the TESTS variable, or if one of the elements
+# of "constraints" turns out not to be true.
+#
+# Arguments:
+# name - Name of test, in the form foo-1.2.
+# description - Short textual description of the test, to
+# help humans understand what it does.
+# constraints - A list of one or more keywords, each of
+# which must be the name of an element in
+# the array "testConfig". If any of these
+# elements is zero, the test is skipped.
+# This argument may be omitted.
+# script - Script to run to carry out the test. It must
+# return a result that can be checked for
+# correctness.
+# answer - Expected result from script.
+
+proc test {name description script answer args} {
+ global VERBOSE TESTS testConfig
+ if {[string compare $TESTS ""] != 0} then {
+ set ok 0
+ foreach test $TESTS {
+ if [string match $test $name] then {
+ set ok 1
+ break
+ }
+ }
+ if !$ok then return
+ }
+ set i [llength $args]
+ if {$i == 0} {
+ # Empty body
+ } elseif {$i == 1} {
+ # "constraints" argument exists; shuffle arguments down, then
+ # make sure that the constraints are satisfied.
+
+ set constraints $script
+ set script $answer
+ set answer [lindex $args 0]
+ foreach constraint $constraints {
+ if {![info exists testConfig($constraint)]
+ || !$testConfig($constraint)} {
+ return
+ }
+ }
+ } else {
+ error "wrong # args: must be \"test name description ?constraints? script answer\""
+ }
+ memory tag $name
+ set code [catch {uplevel $script} result]
+ if {$code != 0} {
+ print_verbose $name $description $script \
+ $code $result
+ } elseif {[string compare $result $answer] == 0} then {
+ if $VERBOSE then {
+ if {$VERBOSE > 0} {
+ print_verbose $name $description $script \
+ $code $result
+ }
+ puts stdout "++++ $name PASSED"
+ }
+ } else {
+ print_verbose $name $description $script \
+ $code $result
+ puts stdout "---- Result should have been:"
+ puts stdout "$answer"
+ puts stdout "---- $name FAILED"
+ }
+}
+
+proc dotests {file args} {
+ global TESTS
+ set savedTests $TESTS
+ set TESTS $args
+ source $file
+ set TESTS $savedTests
+}
+
+proc normalizeMsg {msg} {
+ regsub "\n$" [string tolower $msg] "" msg
+ regsub -all "\n\n" $msg "\n" msg
+ regsub -all "\n\}" $msg "\}" msg
+ return $msg
+}
+
+proc makeFile {contents name} {
+ set fd [open $name w]
+ fconfigure $fd -translation lf
+ if {[string index $contents [expr [string length $contents] - 1]] == "\n"} {
+ puts -nonewline $fd $contents
+ } else {
+ puts $fd $contents
+ }
+ close $fd
+}
+
+proc removeFile {name} {
+ global tcl_platform testConfig
+ if {$tcl_platform(platform) == "macintosh"} {
+ catch {rm -f $name}
+ } else {
+ catch {exec rm -f $name}
+ }
+}
+
+proc makeDirectory {name} {
+ global tcl_platform testConfig
+ if {$tcl_platform(platform) == "macintosh"} {
+ catch {mkdir $name}
+ } else {
+ catch {exec mkdir $name}
+ }
+}
+
+proc removeDirectory {name} {
+ global tcl_platform testConfig
+ if {$tcl_platform(platform) == "macintosh"} {
+ catch {rmdir $name}
+ } else {
+ catch {exec rm -rf $name}
+ }
+}
+
+proc viewFile {name} {
+ global tcl_platform testConfig
+ if {($tcl_platform(platform) == "macintosh") || \
+ ($testConfig(unixExecs) == 0)} {
+ set f [open $name]
+ set data [read -nonewline $f]
+ close $f
+ return $data
+ } else {
+ exec cat $name
+ }
+}
+
+# Locate tcltest executable
+
+set tcltest [list [info nameofexecutable]]
+if {$tcltest == "{}"} {
+ set tcltest {}
+ puts "Unable to find tcltest executable, multiple process tests will fail."
+}
+
+
diff --git a/contrib/tcl/tests/dstring.test b/contrib/tcl/tests/dstring.test
new file mode 100644
index 0000000..2ae157a
--- /dev/null
+++ b/contrib/tcl/tests/dstring.test
@@ -0,0 +1,247 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) dstring.test 1.8 96/02/16 08:55:46
+
+if {[info commands testdstring] == {}} {
+ puts "This application hasn't been compiled with the \"testdstring\""
+ puts "command, so I can't test Tcl_DStringAppend et al."
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test dstring-1.1 {appending and retrieving} {
+ testdstring free
+ testdstring append "abc" -1
+ list [testdstring get] [testdstring length]
+} {abc 3}
+test dstring-1.2 {appending and retrieving} {
+ testdstring free
+ testdstring append "abc" -1
+ testdstring append " xyzzy" 3
+ testdstring append " 12345" -1
+ list [testdstring get] [testdstring length]
+} {{abc xy 12345} 12}
+test dstring-1.3 {appending and retrieving} {
+ testdstring free
+ 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]
+} {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} 352}
+
+test dstring-2.1 {appending list elements} {
+ testdstring free
+ testdstring element "abc"
+ testdstring element "d e f"
+ list [testdstring get] [testdstring length]
+} {{abc {d e f}} 11}
+test dstring-2.2 {appending list elements} {
+ testdstring free
+ testdstring element "x"
+ testdstring element "\{"
+ testdstring element "ab\}"
+ testdstring get
+} {x \{ ab\}}
+test dstring-2.3 {appending list elements} {
+ testdstring free
+ 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
+} {aaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccc ddddddddddddddddddddd eeeeeeeeeeeeeeeeeeeee fffffffffffffffffffff ggggggggggggggggggggg hhhhhhhhhhhhhhhhhhhhh iiiiiiiiiiiiiiiiiiiii jjjjjjjjjjjjjjjjjjjjj kkkkkkkkkkkkkkkkkkkkk lllllllllllllllllllll mmmmmmmmmmmmmmmmmmmmm nnnnnnnnnnnnnnnnnnnnn ooooooooooooooooooooo ppppppppppppppppppppp}
+test dstring-2.4 {appending list elements} {
+ testdstring free
+ testdstring append "a\{" -1
+ testdstring element abc
+ testdstring append " \{" -1
+ testdstring element xyzzy
+ testdstring get
+} "a{ abc {xyzzy"
+test dstring-2.5 {appending list elements} {
+ testdstring free
+ testdstring append " \{" -1
+ testdstring element abc
+ testdstring get
+} " {abc"
+test dstring-2.6 {appending list elements} {
+ testdstring free
+ testdstring append " " -1
+ testdstring element abc
+ testdstring get
+} { abc}
+test dstring-2.7 {appending list elements} {
+ testdstring free
+ testdstring append "\\ " -1
+ testdstring element abc
+ testdstring get
+} "\\ abc"
+test dstring-2.8 {appending list elements} {
+ testdstring free
+ testdstring append "x " -1
+ testdstring element abc
+ testdstring get
+} {x abc}
+
+test dstring-3.1 {nested sublists} {
+ testdstring free
+ testdstring start
+ testdstring element foo
+ testdstring element bar
+ testdstring end
+ testdstring element another
+ testdstring get
+} {{foo bar} another}
+test dstring-3.2 {nested sublists} {
+ testdstring free
+ testdstring start
+ testdstring start
+ testdstring element abc
+ testdstring element def
+ testdstring end
+ testdstring end
+ testdstring element ghi
+ testdstring get
+} {{{abc def}} ghi}
+test dstring-3.3 {nested sublists} {
+ testdstring free
+ 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
+} {{{{foo foo2}} foo3} foo4}
+test dstring-3.4 {nested sublists} {
+ testdstring free
+ testdstring element before
+ testdstring start
+ testdstring element during
+ testdstring element more
+ testdstring end
+ testdstring element last
+ testdstring get
+} {before {during more} last}
+test dstring-3.4 {nested sublists} {
+ testdstring free
+ testdstring element "\{"
+ testdstring start
+ testdstring element first
+ testdstring element second
+ testdstring end
+ testdstring get
+} {\{ {first second}}
+
+test dstring-4.1 {truncation} {
+ testdstring free
+ testdstring append "abcdefg" -1
+ testdstring trunc 3
+ list [testdstring get] [testdstring length]
+} {abc 3}
+test dstring-4.2 {truncation} {
+ testdstring free
+ testdstring append "xyzzy" -1
+ testdstring trunc 0
+ list [testdstring get] [testdstring length]
+} {{} 0}
+
+test dstring-5.1 {copying to result} {
+ testdstring free
+ testdstring append xyz -1
+ testdstring result
+} xyz
+test dstring-5.2 {copying to result} {
+ testdstring free
+ 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]
+} {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} abc}
+
+test dstring-6.1 {Tcl_DStringGetResult} {
+ testdstring free
+ list [testdstring gresult staticsmall] [testdstring get]
+} {{} short}
+test dstring-6.2 {Tcl_DStringGetResult} {
+ testdstring free
+ 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]
+} {{} short}
+test dstring-6.3 {Tcl_DStringGetResult} {
+ set result {}
+ lappend result [testdstring gresult staticlarge]
+ testdstring append x 1
+ lappend result [testdstring get]
+} {{} {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} {
+ set result {}
+ lappend result [testdstring gresult free]
+ testdstring append y 1
+ lappend result [testdstring get]
+} {{} {This is a malloc-ed stringy}}
+test dstring-6.5 {Tcl_DStringGetResult} {
+ set result {}
+ lappend result [testdstring gresult special]
+ testdstring append z 1
+ lappend result [testdstring get]
+} {{} {This is a specially-allocated stringz}}
+
+testdstring free
diff --git a/contrib/tcl/tests/env.test b/contrib/tcl/tests/env.test
new file mode 100644
index 0000000..22f1284
--- /dev/null
+++ b/contrib/tcl/tests/env.test
@@ -0,0 +1,108 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) env.test 1.9 96/02/16 08:55:47
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# If there is no "printenv" program on this system, then it's just too
+# much trouble to run this test (can't necessarily run csh to get the
+# environment: on some systems it barfs if there isn't a minimum set
+# predefined environment variables. Also, printenv returns a non-zero
+# status on some systems, so read the environment using a procedure
+# that catches errors.
+
+set printenv {}
+if [info exists env(PATH)] {
+ set dirs [split $env(PATH) :]
+} else {
+ set dirs {/bin /usr/bin /usr/ucb /usr/local /usr/public /usr/etc}
+}
+foreach i $dirs {
+ if [file executable $i/printenv] {
+ # The following hack is needed because of weirdness with
+ # environment variables in symbolic lines on Apollos (?!#?).
+ if ![catch {exec sh -c "cd $i; pwd"} x] {
+ set printenv $x/printenv
+ } else {
+ set printenv $i/printenv
+ }
+ break
+ }
+}
+if {$printenv == ""} {
+ puts stdout "Skipping env tests: need \"printenv\" to read environment."
+ return ""
+}
+proc getenv {} {
+ global printenv
+ catch {exec $printenv} out
+ if {$out == "child process exited abnormally"} {
+ set out {}
+ }
+ return $out
+}
+
+# Save the current environment variables at the start of the test.
+
+foreach name [array names env] {
+ set env2($name) $env($name)
+ unset env($name)
+}
+
+test env-1.1 {adding environment variables} {
+ getenv
+} {}
+
+set env(NAME1) "test string"
+test env-1.2 {adding environment variables} {
+ getenv
+} {NAME1=test string}
+
+set env(NAME2) "more"
+test env-1.3 {adding environment variables} {
+ getenv
+} {NAME1=test string
+NAME2=more}
+
+set env(XYZZY) "garbage"
+test env-1.4 {adding environment variables} {
+ getenv
+} {NAME1=test string
+NAME2=more
+XYZZY=garbage}
+
+set env(NAME2) "new value"
+test env-2.1 {changing environment variables} {
+ getenv
+} {NAME1=test string
+NAME2=new value
+XYZZY=garbage}
+
+unset env(NAME2)
+test env-3.1 {unsetting environment variables} {
+ getenv
+} {NAME1=test string
+XYZZY=garbage}
+unset env(NAME1)
+test env-3.2 {unsetting environment variables} {
+ getenv
+} {XYZZY=garbage}
+
+# Restore the environment variables at the end of the test.
+
+foreach name [array names env] {
+ unset env($name)
+}
+foreach name [array names env2] {
+ set env($name) $env2($name)
+}
diff --git a/contrib/tcl/tests/error.test b/contrib/tcl/tests/error.test
new file mode 100644
index 0000000..9adbe05
--- /dev/null
+++ b/contrib/tcl/tests/error.test
@@ -0,0 +1,171 @@
+# Commands covered: error, catch
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) error.test 1.14 96/02/16 08:55:48
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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 compare]} b
+} 1
+
+test error-1.2 {simple errors from commands} {
+ catch {format [string compare]} b
+ set b
+} {wrong # args: should be "string compare string1 string2"}
+
+test error-1.3 {simple errors from commands} {
+ catch {format [string compare]} b
+ set errorInfo
+} {wrong # args: should be "string compare string1 string2"
+ while executing
+"string compare"
+ invoked from within
+"format [string compare]..."}
+
+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} b
+} 1
+
+test error-1.7 {simple errors from commands} {
+ catch {catch a b c} b
+ set b
+} {wrong # args: should be "catch command ?varName?"}
+
+test error-2.1 {simple errors from commands} {
+ catch catch
+} 1
+
+# 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"
+ invoked from within
+"format [error glorp2]..."
+ (procedure "foo2" line 1)
+ 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 command ?varName?"}}
+test error-3.2 {errors in catch command} {
+ list [catch {catch a b c} msg] $msg
+} {1 {wrong # args: should be "catch command ?varName?"}}
+test error-3.3 {errors in catch command} {
+ catch {unset a}
+ set a(0) 22
+ list [catch {catch {format 44} a} msg] $msg
+} {1 {couldn't save command result in variable}}
+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 {}}
+
+# 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}
+
+return ""
diff --git a/contrib/tcl/tests/eval.test b/contrib/tcl/tests/eval.test
new file mode 100644
index 0000000..dcd2ea8
--- /dev/null
+++ b/contrib/tcl/tests/eval.test
@@ -0,0 +1,55 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) eval.test 1.7 96/02/16 08:55:49
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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\"
+ }\""
diff --git a/contrib/tcl/tests/event.test b/contrib/tcl/tests/event.test
new file mode 100644
index 0000000..b48ee22
--- /dev/null
+++ b/contrib/tcl/tests/event.test
@@ -0,0 +1,927 @@
+# This file contains a collection of tests for the procedures in the file
+# tclEvent.c, which includes the "after", "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-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.
+#
+# "@(#) event.test 1.20 96/04/09 15:54:05"
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+if {[catch {testfilehandler create 0 off off}] == 0 } {
+ test event-1.1 {Tcl_CreateFileHandler, reading} {
+ testfilehandler close
+ testfilehandler create 0 readable off
+ testfilehandler clear 0
+ testfilehandler oneevent
+ set result ""
+ lappend result [testfilehandler counts 0]
+ testfilehandler fillpartial 0
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler close
+ set result
+ } {{0 0} {1 0} {2 0}}
+ test event-1.2 {Tcl_CreateFileHandler, writing} {nonPortable} {
+ # This test is non-portable because on some systems (e.g.
+ # SunOS 4.1.3) pipes seem to be writable always.
+ testfilehandler close
+ testfilehandler create 0 off writable
+ testfilehandler clear 0
+ testfilehandler oneevent
+ set result ""
+ 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]
+ testfilehandler close
+ set result
+ } {{0 1} {0 2} {0 2}}
+ test event-1.3 {Tcl_DeleteFileHandler} {
+ testfilehandler close
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler create 0 disabled disabled
+ testfilehandler fillpartial 1
+ set result ""
+ 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]
+ testfilehandler close
+ set result
+ } {{0 1} {1 1} {1 2} {0 0}}
+
+ test event-2.1 {Tcl_DeleteFileHandler} {
+ testfilehandler close
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ set result ""
+ 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]
+ testfilehandler close
+ set result
+ } {{0 1} {1 1} {1 2} {0 0}}
+ test event-2.2 {Tcl_DeleteFileHandler, fd reused & events still pending} {
+ testfilehandler close
+ testfilehandler create 0 readable writable
+ testfilehandler fillpartial 0
+ set result ""
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler close
+ testfilehandler create 0 readable writable
+ testfilehandler oneevent
+ lappend result [testfilehandler counts 0]
+ testfilehandler close
+ set result
+ } {{0 1} {0 0}}
+
+ test event-3.1 {FileHandlerCheckProc, TCL_FILE_EVENTS off } {
+ testfilehandler close
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ testfilehandler windowevent
+ set result [testfilehandler counts 1]
+ testfilehandler close
+ set result
+ } {0 0}
+
+ test event-4.1 {FileHandlerEventProc, race between event and disabling } {
+ testfilehandler close
+ testfilehandler create 2 disabled disabled
+ testfilehandler create 1 readable writable
+ testfilehandler fillpartial 1
+ set result ""
+ 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]
+ testfilehandler close
+ set result
+ } {{0 1} {1 1} {1 2} {0 0}}
+ test event-4.2 {FileHandlerEventProc, TCL_FILE_EVENTS off } {
+ testfilehandler close
+ 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]
+ testfilehandler close
+ set result
+ } {{0 0} {0 1} {0 0} {0 1}}
+ testfilehandler close
+ update
+}
+
+test event-5.1 {Tcl_CreateTimerHandler procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ set x ""
+ foreach i {100 200 1000 50 150} {
+ after $i lappend x $i
+ }
+ after 200
+ update
+ set x
+} {50 100 150 200}
+
+test event-6.1 {Tcl_DeleteTimerHandler procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ set x ""
+ foreach i {100 200 300 50 150} {
+ after $i lappend x $i
+ }
+ after cancel lappend x 150
+ after cancel lappend x 50
+ after 200
+ update
+ set x
+} {100 200}
+
+if {[info commands testmodal] != ""} {
+ test event-7.1 {Tcl_CreateModalTimeout and Tcl_DeleteModalTimeout procedures} {
+ update
+ set x {}
+ set result {}
+ testmodal create 50 first
+ testmodal create 200 second
+ after 100
+ testmodal eventnotimers
+ lappend result $x
+ after 150
+ testmodal eventnotimers
+ lappend result $x
+ testmodal delete
+ testmodal eventnotimers
+ lappend result $x
+ testmodal eventnotimers
+ lappend result $x
+ testmodal delete
+ testmodal eventnotimers
+ lappend result $x
+ } {{} second {second first} {second first first} {second first first}}
+
+ test event-8.1 {TimerHandlerSetupProc procedure, choosing correct timer} {
+ update
+ set x {}
+ after 100 {lappend x normal}
+ testmodal create 200 modal
+ vwait x
+ testmodal delete
+ set x
+ } {normal}
+ test event-8.2 {TimerHandlerSetupProc procedure, choosing correct timer} {
+ update
+ set x {}
+ after 200 {lappend x normal}
+ testmodal create 100 modal
+ vwait x
+ testmodal delete
+ set x
+ } {modal}
+}
+
+# No tests for TimerHandlerCheckProc: it's already tested by other tests
+# above and below.
+
+test event-9.1 {TimerHandlerEventProc procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ foreach i {100 200 300} {
+ after $i lappend x $i
+ }
+ after 100
+ set result ""
+ set x ""
+ update
+ lappend result $x
+ after 100
+ update
+ lappend result $x
+ after 100
+ update
+ lappend result $x
+} {100 {100 200} {100 200 300}}
+
+# No tests for Tcl_DoWhenIdle: it's already tested by other tests
+# below.
+
+test event-10.1 {Tk_CancelIdleCall procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+ concat $x $y $z
+} {after1 before after3}
+test event-10.2 {Tk_CancelIdleCall procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+ concat $x $y $z
+} {before after2 after3}
+
+test event-11.1 {Tcl_ServiceIdle, self-rescheduling handlers} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+} {2 24 4}
+
+test event-12.1 {Tcl_BackgroundError, HandleBgErrors procedures} {
+ catch {rename bgerror {}}
+ 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
+ rename bgerror {}
+ set x
+} {{{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-12.2 {Tcl_BackgroundError, HandleBgErrors procedures} {
+ catch {rename bgerror {}}
+ 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
+ rename bgerror {}
+ set x
+} {{a simple error}}
+
+test event-13.1 {BgErrorDeleteProc procedure} {
+ catch {interp delete foo}
+ interp create foo
+ foo eval {
+ proc bgerror args {
+ global errorInfo
+ set f [open err.out r+]
+ seek $f 0 end
+ puts $f "$args $errorInfo"
+ close $f
+ }
+ after 100 {error "first error"}
+ after 100 {error "second error"}
+ }
+ makeFile Unmodified err.out
+ after 100 {interp delete foo}
+ after 200
+ update
+ set f [open err.out r]
+ set result [read $f]
+ close $f
+ removeFile err.out
+ set result
+} {Unmodified
+}
+
+test event-14.1 {tkerror/bgerror backwards compabitility} {
+ catch {rename bgerror {}}
+ proc tkerror {x y} {
+ return [expr $x + $y]
+ }
+ list [tkerror 4 7] [bgerror 8 -3]
+} {11 5}
+test event-14.2 {tkerror/bgerror backwards compabitility} {
+ proc bgerror {x y} {
+ return [expr 1 + $x + $y]
+ }
+ list [tkerror 6 -2] [bgerror 7 2]
+} {5 10}
+test event-14.3 {tkerror/bgerror backwards compabitility} {
+ proc bgerror {x y} {
+ return [expr 1 + $x + $y]
+ }
+ set result [list [info commands bgerror] [info commands tkerror]]
+ rename tkerror {}
+ lappend result [info commands bgerror] [info commands tkerror]
+} {bgerror tkerror {} {}}
+test event-14.4 {tkerror/bgerror backwards compabitility} {
+ proc tkerror {x y} {
+ return [expr 1 + $x + $y]
+ }
+ set result [list [info commands bgerror] [info commands tkerror]]
+ rename bgerror {}
+ lappend result [info commands bgerror] [info commands tkerror]
+} {bgerror tkerror {} {}}
+test event-14.5 {tkerror/bgerror backwards compabitility} {
+ proc tkerror {x y} {
+ return [expr 1 + $x + $y]
+ }
+ rename tkerror foo
+ list [info commands bgerror] [info commands tkerror] [foo 4 3]
+} {{} {} 8}
+test event-14.6 {tkerror/bgerror backwards compabitility} {
+ proc bgerror {x y} {
+ return [expr 1 + $x + $y]
+ }
+ catch {rename foo {}}
+ rename bgerror foo
+ list [info commands bgerror] [info commands tkerror] [foo 4 3]
+} {{} {} 8}
+test event-14.7 {tkerror/bgerror backwards compabitility} {
+ proc foo args {return $args}
+ catch {rename tkerror {}}
+ rename foo tkerror
+ list [info commands bgerror] [info commands tkerror] [info commands foo] [tkerror a b c d]
+} {bgerror tkerror {} {a b c d}}
+test event-14.8 {tkerror/bgerror backwards compabitility} {
+ proc foo args {return $args}
+ catch {rename bgerror {}}
+ rename foo bgerror
+ list [info commands bgerror] [info commands tkerror] [info commands foo] [tkerror a b c d]
+} {bgerror tkerror {} {a b c d}}
+test event-14.9 {tkerror/bgerror backwards compabitility} {
+ proc bgerror args {return $args}
+ list [catch {rename bgerror tkerror} msg] $msg
+} {1 {can't rename to "tkerror": command already exists}}
+rename bgerror {}
+
+if {[info commands testexithandler] != ""} {
+ test event-15.1 {Tcl_CreateExitHandler procedure} {unixOrPc} {
+ set child [open |[list [info nameofexecutable]] r+]
+ puts $child "testexithandler create 41; testexithandler create 4"
+ puts $child "testexithandler create 6; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ set result
+ } {even 6
+even 4
+odd 41
+}
+
+ test event-16.1 {Tcl_DeleteExitHandler procedure} {unixOrPc} {
+ set child [open |[list [info nameofexecutable]] 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
+ set result
+ } {even 16
+even 6
+even 4
+}
+ test event-16.2 {Tcl_DeleteExitHandler procedure} {unixOrPc} {
+ set child [open |[list [info nameofexecutable]] 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
+ set result
+ } {even 16
+even 6
+odd 41
+}
+ test event-16.3 {Tcl_DeleteExitHandler procedure} {unixOrPc} {
+ set child [open |[list [info nameofexecutable]] 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
+ set result
+ } {even 16
+even 4
+odd 41
+}
+ test event-16.4 {Tcl_DeleteExitHandler procedure} {unixOrPc} {
+ set child [open |[list [info nameofexecutable]] r+]
+ puts $child "testexithandler create 41; testexithandler delete 41"
+ puts $child "testexithandler create 16; exit"
+ flush $child
+ set result [read $child]
+ close $child
+ set result
+ } {even 16
+}
+}
+
+test event-17.1 {Tcl_Exit procedure} {unixOrPc} {
+ set child [open |[list [info nameofexecutable]] 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-18.1 {Tcl_AfterCmd procedure, basics} {
+ list [catch {after} msg] $msg
+} {1 {wrong # args: should be "after option ?arg arg ...?"}}
+test event-18.2 {Tcl_AfterCmd procedure, basics} {
+ list [catch {after 2x} msg] $msg
+} {1 {expected integer but got "2x"}}
+test event-18.3 {Tcl_AfterCmd procedure, basics} {
+ list [catch {after gorp} msg] $msg
+} {1 {bad argument "gorp": must be cancel, idle, info, or a number}}
+test event-18.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 event-18.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 event-18.6 {Tcl_AfterCmd procedure, cancel option} {
+ list [catch {after cancel} msg] $msg
+} {1 {wrong # args: should be "after cancel id|command"}}
+test event-18.7 {Tcl_AfterCmd procedure, cancel option} {
+ after cancel after#1
+} {}
+test event-18.8 {Tcl_AfterCmd procedure, cancel option} {
+ after cancel {foo bar}
+} {}
+test event-18.9 {Tcl_AfterCmd procedure, cancel option} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ set x before
+ set y [after 100 set x after]
+ after cancel $y
+ after 200
+ update
+ set x
+} {before}
+test event-18.10 {Tcl_AfterCmd procedure, cancel option} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ set x before
+ after 100 set x after
+ after cancel {set x after}
+ after 200
+ update
+ set x
+} {before}
+test event-18.11 {Tcl_AfterCmd procedure, cancel option} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+} {after cleared}
+test event-18.12 {Tcl_AfterCmd procedure, cancel option} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+ set x
+} {first third}
+test event-18.13 {Tcl_AfterCmd procedure, cancel option, multiple arguments for command} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+ set x
+} {first third}
+test event-18.14 {Tcl_AfterCmd procedure, cancel option, cancel during handler, used to dump core} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ set id [
+ after 100 {
+ set x done
+ after cancel $id
+ }
+ ]
+ vwait x
+} {}
+test event-18.15 {Tcl_AfterCmd procedure, cancel option, multiple interps} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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}]
+ interp delete x
+ set result
+} {2 0 aaa bbb {before b-after}}
+test event-18.16 {Tcl_AfterCmd procedure, idle option} {
+ list [catch {after idle} msg] $msg
+} {1 {wrong # args: should be "after idle script script ..."}}
+test event-18.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 event-18.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 event-18.19 {Tcl_AfterCmd, info option} {
+ lsort [after info]
+} "$event1 $event2"
+test event-18.20 {Tcl_AfterCmd, info option} {
+ list [catch {after info a b} msg] $msg
+} {1 {wrong # args: should be "after info ?id?"}}
+test event-18.21 {Tcl_AfterCmd, info option} {
+ list [catch {after info $childEvent} msg] $msg
+} "1 {event \"$childEvent\" doesn't exist}"
+test event-18.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
+
+set event [after idle foo bar]
+scan $event after#%d id
+test event-19.1 {GetAfterEvent procedure} {
+ list [catch {after info xfter#$id} msg] $msg
+} "1 {event \"xfter#$id\" doesn't exist}"
+test event-19.2 {GetAfterEvent procedure} {
+ list [catch {after info afterx$id} msg] $msg
+} "1 {event \"afterx$id\" doesn't exist}"
+test event-19.3 {GetAfterEvent procedure} {
+ list [catch {after info after#ab} msg] $msg
+} {1 {event "after#ab" doesn't exist}}
+test event-19.4 {GetAfterEvent procedure} {
+ list [catch {after info after#} msg] $msg
+} {1 {event "after#" doesn't exist}}
+test event-19.5 {GetAfterEvent procedure} {
+ list [catch {after info after#${id}x} msg] $msg
+} "1 {event \"after#${id}x\" doesn't exist}"
+test event-19.6 {GetAfterEvent procedure} {
+ list [catch {after info afterx[expr $id+1]} msg] $msg
+} "1 {event \"afterx[expr $id+1]\" doesn't exist}"
+after cancel $event
+
+test event-20.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 event-20.2 {AfterProc procedure} {
+ catch {rename bgerror {}}
+ proc bgerror msg {
+ global x errorInfo
+ set x [list $msg $errorInfo]
+ }
+ set x empty
+ after 100 {error "After error"}
+ after 200
+ set y $x
+ update
+ catch {rename bgerror {}}
+ list $y $x
+} {empty {{After error} {After error
+ while executing
+"error "After error""
+ ("after" script)}}}
+test event-20.3 {AfterProc procedure, deleting handler from itself} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+ set x
+} {{{error "I shouldn't ever have executed"} timer}}
+test event-20.4 {AfterProc procedure, deleting handler from itself} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+ set x
+} {{{error "I shouldn't ever have executed"} timer}}
+ foreach i [after info] {
+ after cancel $i
+ }
+
+test event-21.1 {AfterCleanupProc procedure} {
+ catch {interp delete x}
+ 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
+ set x
+} {before after2 after4}
+
+test event-22.1 {Tcl_VwaitCmd procedure} {
+ list [catch {vwait} msg] $msg
+} {1 {wrong # args: should be "vwait name"}}
+test event-22.2 {Tcl_VwaitCmd procedure} {
+ list [catch {vwait a b} msg] $msg
+} {1 {wrong # args: should be "vwait name"}}
+test event-22.3 {Tcl_VwaitCmd procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+} {{} x-done y-done before q-done}
+
+test event-23.1 {Tcl_UpdateCmd procedure} {
+ list [catch {update a b} msg] $msg
+} {1 {wrong # args: should be "update ?idletasks?"}}
+test event-23.2 {Tcl_UpdateCmd procedure} {
+ list [catch {update bogus} msg] $msg
+} {1 {bad option "bogus": must be idletasks}}
+test event-23.3 {Tcl_UpdateCmd procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ 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
+} {before after {after, y = after}}
+test event-23.4 {Tcl_UpdateCmd procedure} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 200 {set x x-done}
+ after 500 {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
+} {x-done before z-done}
+
+if {[info commands testfilehandler] != ""} {
+ test event-24.1 {Tcl_WaitForFile procedure, readable} unixOnly {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 set x timeout
+ testfilehandler close
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 0]
+ update
+ testfilehandler close
+ list $result $x
+ } {{} {no timeout}}
+ test event-24.2 {Tcl_WaitForFile procedure, readable} unixOnly {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 set x timeout
+ testfilehandler close
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ testfilehandler close
+ list $result $x
+ } {{} timeout}
+ test event-24.3 {Tcl_WaitForFile procedure, readable} unixOnly {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 set x timeout
+ testfilehandler close
+ testfilehandler create 1 off off
+ testfilehandler fillpartial 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 readable 100]
+ update
+ testfilehandler close
+ list $result $x
+ } {readable {no timeout}}
+ test event-24.4 {Tcl_WaitForFile procedure, writable} {unixOnly nonPortable} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 set x timeout
+ testfilehandler close
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 0]
+ update
+ testfilehandler close
+ list $result $x
+ } {{} {no timeout}}
+ test event-24.5 {Tcl_WaitForFile procedure, writable} {unixOnly nonPortable} {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 set x timeout
+ testfilehandler close
+ testfilehandler create 1 off off
+ testfilehandler fill 1
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ testfilehandler close
+ list $result $x
+ } {{} timeout}
+ test event-24.6 {Tcl_WaitForFile procedure, writable} unixOnly {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 set x timeout
+ testfilehandler close
+ testfilehandler create 1 off off
+ set x "no timeout"
+ set result [testfilehandler wait 1 writable 100]
+ update
+ testfilehandler close
+ list $result $x
+ } {writable {no timeout}}
+ test event-24.7 {Tcl_WaitForFile procedure, don't call other event handlers} unixOnly {
+ foreach i [after info] {
+ after cancel $i
+ }
+ after 100 lappend x timeout
+ after idle lappend x idle
+ testfilehandler close
+ testfilehandler create 1 off off
+ set x ""
+ set result [list [testfilehandler wait 1 readable 200] $x]
+ update
+ testfilehandler close
+ lappend result $x
+ } {{} {} {timeout idle}}
+ test event-24.8 {Tcl_WaitForFile procedure, waiting indefinitely} unixOnly {
+ set f [open "|sleep 2" r]
+ set result ""
+ lappend result [testfilewait $f readable 100]
+ lappend result [testfilewait $f readable -1]
+ close $f
+ set result
+ } {{} readable}
+}
+
+foreach i [after info] {
+ after cancel $i
+}
diff --git a/contrib/tcl/tests/exec.test b/contrib/tcl/tests/exec.test
new file mode 100644
index 0000000..75dd359
--- /dev/null
+++ b/contrib/tcl/tests/exec.test
@@ -0,0 +1,489 @@
+# 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 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) exec.test 1.53 96/04/12 16:33:37
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# If exec is not defined just return with no error
+# Some platforms like the Macintosh do not have the exec command
+if {[info commands exec] == ""} {
+ puts "exec not implemented for this machine"
+ return
+}
+
+# This procedure generates a shell command to be passed to exec
+# to mask the differences between Unix and PC shells.
+
+proc shellCmd {string} {
+ global tcl_platform
+ if {$tcl_platform(platform) == "unix"} {
+ return "sh -c \"$string\""
+ } else {
+ return "sh -c {\"$string\"}"
+ }
+}
+
+# Basic operations.
+
+test exec-1.1 {basic exec operation} {unixExecs} {
+ exec echo a b c
+} "a b c"
+test exec-1.2 {pipelining} {unixExecs} {
+ exec echo a b c d | cat | cat
+} "a b c d"
+test exec-1.3 {pipelining} {unixExecs} {
+ set a [exec echo a b c d | cat | 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} {unixExecs} {
+ exec echo $arg
+} $arg
+set arg {}
+
+# I/O redirection: input from Tcl command.
+
+test exec-2.1 {redirecting input from immediate source} {unixExecs} {
+ exec cat << "Sample text"
+} {Sample text}
+test exec-2.2 {redirecting input from immediate source} {unixExecs} {
+ exec << "Sample text" cat | cat
+} {Sample text}
+test exec-2.3 {redirecting input from immediate source} {unixExecs} {
+ exec cat << "Sample text" | cat
+} {Sample text}
+test exec-2.4 {redirecting input from immediate source} {unixExecs} {
+ exec cat | cat << "Sample text"
+} {Sample text}
+test exec-2.5 {redirecting input from immediate source} {unixExecs} {
+ exec cat "<<Joined to arrows"
+} {Joined to arrows}
+
+# I/O redirection: output to file.
+
+catch {exec rm -f gorp.file}
+test exec-3.1 {redirecting output to file} {unixExecs} {
+ exec echo "Some simple words" > gorp.file
+ exec cat gorp.file
+} "Some simple words"
+test exec-3.2 {redirecting output to file} {unixExecs} {
+ exec echo "More simple words" | >gorp.file cat | cat
+ exec cat gorp.file
+} "More simple words"
+test exec-3.3 {redirecting output to file} {unixExecs} {
+ exec > gorp.file echo "Different simple words" | cat | cat
+ exec cat gorp.file
+} "Different simple words"
+test exec-3.4 {redirecting output to file} {unixExecs} {
+ exec echo "Some simple words" >gorp.file
+ exec cat gorp.file
+} "Some simple words"
+test exec-3.5 {redirecting output to file} {unixExecs} {
+ exec echo "First line" >gorp.file
+ exec echo "Second line" >> gorp.file
+ exec cat gorp.file
+} "First line\nSecond line"
+test exec-3.6 {redirecting output to file} {unixExecs} {
+ exec echo "First line" >gorp.file
+ exec echo "Second line" >>gorp.file
+ exec cat gorp.file
+} "First line\nSecond line"
+test exec-3.7 {redirecting output to file} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f "Line 1"
+ flush $f
+ exec echo "More text" >@ $f
+ exec echo >@$f "Even more"
+ puts $f "Line 3"
+ close $f
+ exec cat gorp.file
+} "Line 1\nMore text\nEven more\nLine 3"
+
+# I/O redirection: output and stderr to file.
+
+catch {exec rm -f gorp.file}
+test exec-4.1 {redirecting output and stderr to file} {unixExecs} {
+ exec echo "test output" >& gorp.file
+ exec cat gorp.file
+} "test output"
+test exec-4.2 {redirecting output and stderr to file} {unixExecs} {
+ list [eval exec [shellCmd "echo foo bar 1>&2"] >&gorp.file] \
+ [exec cat gorp.file]
+} {{} {foo bar}}
+test exec-4.3 {redirecting output and stderr to file} {unixExecs} {
+ exec echo "first line" > gorp.file
+ list [eval exec [shellCmd "echo foo bar 1>&2"] >>&gorp.file] \
+ [exec cat gorp.file]
+} "{} {first line\nfoo bar}"
+test exec-4.4 {redirecting output and stderr to file} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f "Line 1"
+ flush $f
+ exec echo "More text" >&@ $f
+ exec echo >&@$f "Even more"
+ puts $f "Line 3"
+ close $f
+ exec cat gorp.file
+} "Line 1\nMore text\nEven more\nLine 3"
+test exec-4.5 {redirecting output and stderr to file} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f "Line 1"
+ flush $f
+ eval exec >&@ $f [shellCmd "echo foo bar 1>&2"]
+ eval exec >&@$f [shellCmd "echo xyzzy 1>&2"]
+ puts $f "Line 3"
+ close $f
+ exec cat gorp.file
+} "Line 1\nfoo bar\nxyzzy\nLine 3"
+
+# I/O redirection: input from file.
+
+catch {exec echo "Just a few thoughts" > gorp.file}
+test exec-5.1 {redirecting input from file} {unixExecs} {
+ exec cat < gorp.file
+} {Just a few thoughts}
+test exec-5.2 {redirecting input from file} {unixExecs} {
+ exec cat | cat < gorp.file
+} {Just a few thoughts}
+test exec-5.3 {redirecting input from file} {unixExecs} {
+ exec cat < gorp.file | cat
+} {Just a few thoughts}
+test exec-5.4 {redirecting input from file} {unixExecs} {
+ exec < gorp.file cat | cat
+} {Just a few thoughts}
+test exec-5.5 {redirecting input from file} {unixExecs} {
+ exec cat <gorp.file
+} {Just a few thoughts}
+test exec-5.6 {redirecting input from file} {unixExecs} {
+ set f [open gorp.file r]
+ set result [exec cat <@ $f]
+ close $f
+ set result
+} {Just a few thoughts}
+test exec-5.7 {redirecting input from file} {unixExecs} {
+ set f [open gorp.file r]
+ set result [exec <@$f cat]
+ close $f
+ set result
+} {Just a few thoughts}
+
+# I/O redirection: standard error through a pipeline.
+
+test exec-6.1 {redirecting stderr through a pipeline} {unixExecs} {
+ eval exec [shellCmd "echo foo bar"] |& cat
+} "foo bar"
+test exec-6.2 {redirecting stderr through a pipeline} {unixExecs} {
+ eval exec [shellCmd "echo foo bar 1>&2"] |& cat
+} "foo bar"
+test exec-6.3 {redirecting stderr through a pipeline} {unixExecs} {
+ eval exec [shellCmd "echo foo bar 1>&2"] \
+ |& [shellCmd "echo second msg 1>&2; cat"] |& cat
+} "second msg\nfoo bar"
+
+# I/O redirection: combinations.
+
+catch {exec rm -f gorp.file2}
+test exec-7.1 {multiple I/O redirections} {unixExecs} {
+ exec << "command input" > gorp.file2 cat < gorp.file
+ exec cat gorp.file2
+} {Just a few thoughts}
+test exec-7.2 {multiple I/O redirections} {unixExecs} {
+ exec < gorp.file << "command input" 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} {unixExecs} {
+ exec cat << $a
+} $a
+
+# Commands that return errors.
+
+test exec-9.1 {commands returning errors} {
+ 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} {unixExecs} {
+ string tolower [list [catch {exec 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} {unixExecs} {
+ list [catch {eval exec sleep 1 | [shellCmd "exit 43"] | sleep 1} msg] $msg
+} {1 {child process exited abnormally}}
+test exec-9.4 {commands returning errors} {unixExecs} {
+ list [catch {eval exec [shellCmd "exit 43"] | echo "foo bar"} msg] $msg
+} {1 {foo bar
+child process exited abnormally}}
+test exec-9.5 {commands returning errors} {unixExecs} {
+ list [catch {exec gorp456 | echo a b c} msg] [string tolower $msg]
+} {1 {couldn't execute "gorp456": no such file or directory}}
+test exec-9.6 {commands returning errors} {unixExecs} {
+ list [catch {eval exec [shellCmd "echo error msg 1>&2"]} msg] $msg
+} {1 {error msg}}
+test exec-9.7 {commands returning errors} {unixExecs} {
+ list [catch {eval exec [shellCmd "echo error msg 1>&2"] \
+ | [shellCmd "echo error msg 1>&2"]} msg] $msg
+} {1 {error msg
+error msg}}
+
+# Errors in executing the Tcl command, as opposed to errors in the
+# processes that are invoked.
+
+test exec-10.1 {errors in exec invocation} {
+ list [catch {exec} msg] $msg
+} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
+test exec-10.2 {errors in exec invocation} {
+ list [catch {exec | cat} msg] $msg
+} {1 {illegal use of | or |& in command}}
+test exec-10.3 {errors in exec invocation} {
+ list [catch {exec cat |} msg] $msg
+} {1 {illegal use of | or |& in command}}
+test exec-10.4 {errors in exec invocation} {
+ list [catch {exec cat | | cat} msg] $msg
+} {1 {illegal use of | or |& in command}}
+test exec-10.5 {errors in exec invocation} {
+ list [catch {exec cat | |& cat} msg] $msg
+} {1 {illegal use of | or |& in command}}
+test exec-10.6 {errors in exec invocation} {
+ list [catch {exec cat |&} msg] $msg
+} {1 {illegal use of | or |& in command}}
+test exec-10.7 {errors in exec invocation} {
+ list [catch {exec cat <} msg] $msg
+} {1 {can't specify "<" as last word in command}}
+test exec-10.8 {errors in exec invocation} {
+ list [catch {exec cat >} msg] $msg
+} {1 {can't specify ">" as last word in command}}
+test exec-10.9 {errors in exec invocation} {
+ list [catch {exec cat <<} msg] $msg
+} {1 {can't specify "<<" as last word in command}}
+test exec-10.10 {errors in exec invocation} {
+ list [catch {exec cat >>} msg] $msg
+} {1 {can't specify ">>" as last word in command}}
+test exec-10.11 {errors in exec invocation} {
+ list [catch {exec cat >&} msg] $msg
+} {1 {can't specify ">&" as last word in command}}
+test exec-10.12 {errors in exec invocation} {
+ list [catch {exec cat >>&} msg] $msg
+} {1 {can't specify ">>&" as last word in command}}
+test exec-10.13 {errors in exec invocation} {
+ list [catch {exec cat >@} msg] $msg
+} {1 {can't specify ">@" as last word in command}}
+test exec-10.14 {errors in exec invocation} {
+ list [catch {exec cat <@} msg] $msg
+} {1 {can't specify "<@" as last word in command}}
+test exec-10.15 {errors in exec invocation} {unixExecs} {
+ list [catch {exec cat < a/b/c} msg] [string tolower $msg]
+} {1 {couldn't read file "a/b/c": no such file or directory}}
+test exec-10.16 {errors in exec invocation} {unixExecs} {
+ list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
+} {1 {couldn't write file "a/b/c": no such file or directory}}
+test exec-10.17 {errors in exec invocation} {unixExecs} {
+ list [catch {exec cat << foo > a/b/c} msg] [string tolower $msg]
+} {1 {couldn't write file "a/b/c": no such file or directory}}
+set f [open gorp.file w]
+test exec-10.18 {errors in exec invocation} {
+ list [catch {exec cat <@ $f} msg] $msg
+} "1 {channel \"$f\" wasn't opened for reading}"
+close $f
+set f [open gorp.file r]
+test exec-10.19 {errors in exec invocation} {
+ list [catch {exec cat >@ $f} msg] $msg
+} "1 {channel \"$f\" wasn't opened for writing}"
+close $f
+test exec-10.20 {errors in exec invocation} {
+ list [catch {exec ~non_existent_user/foo/bar} msg] $msg
+} {1 {user "non_existent_user" doesn't exist}}
+test exec-10.21 {errors in exec invocation} {unixExecs} {
+ list [catch {exec true | ~xyzzy_bad_user/x | false} msg] $msg
+} {1 {user "xyzzy_bad_user" doesn't exist}}
+
+# Commands in background.
+
+test exec-11.1 {commands in background} {unixExecs} {
+ set x [lindex [time {exec sleep 2 &}] 0]
+ expr $x<1000000
+} 1
+test exec-11.2 {commands in background} {unixExecs} {
+ list [catch {exec echo a &b} msg] $msg
+} {0 {a &b}}
+test exec-11.3 {commands in background} {unixExecs} {
+ llength [exec sleep 1 &]
+} 1
+test exec-11.4 {commands in background} {unixExecs} {
+ llength [exec sleep 1 | sleep 1 | sleep 1 &]
+} 3
+test exec-11.5 {commands in background} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f { catch { exec echo foo & } }
+ close $f
+ string compare "foo" [exec [info nameofexecutable] gorp.file]
+} 0
+
+# Make sure that background commands are properly reaped when
+# they eventually die.
+
+catch {exec sleep 3}
+test exec-12.1 {reaping background processes} {unixOnly nonPortable} {
+ for {set i 0} {$i < 20} {incr i} {
+ exec echo foo > /dev/null &
+ }
+ exec sleep 1
+ catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
+ lindex $msg 0
+} 0
+test exec-12.2 {reaping background processes} {unixExecs 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]
+ exec sleep 3
+ 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} {unixOnly 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} {unixExecs} {
+ list [catch {exec cat < a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.2 {setting errorCode variable} {unixExecs} {
+ list [catch {exec cat > a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.3 {setting errorCode variable} {
+ 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}}}
+
+# Switches before the first argument
+
+test exec-14.1 {-keepnewline switch} {unixExecs} {
+ exec -keepnewline echo foo
+} "foo\n"
+test exec-14.2 {-keepnewline switch} {
+ list [catch {exec -keepnewline} msg] $msg
+} {1 {wrong # args: should be "exec ?switches? arg ?arg ...?"}}
+test exec-14.3 {unknown switch} {
+ list [catch {exec -gorp} msg] $msg
+} {1 {bad switch "-gorp": must be -keepnewline or --}}
+test exec-14.4 {-- switch} {
+ list [catch {exec -- -gorp} msg] [string tolower $msg]
+} {1 {couldn't execute "-gorp": no such file or directory}}
+
+# Redirecting standard error separately from standard output
+
+test exec-15.1 {standard error redirection} {unixExecs} {
+ exec echo "First line" > gorp.file
+ list [eval exec [shellCmd "echo foo bar 1>&2"] 2> gorp.file] \
+ [exec cat gorp.file]
+} {{} {foo bar}}
+test exec-15.2 {standard error redirection} {unixExecs} {
+ list [eval exec [shellCmd "echo foo bar 1>&2"] | echo biz baz >gorp.file \
+ 2> gorp.file2] [exec cat gorp.file] \
+ [exec cat gorp.file2]
+} {{} {biz baz} {foo bar}}
+test exec-15.3 {standard error redirection} {unixExecs} {
+ list [eval exec [shellCmd "echo foo bar 1>&2"] | echo biz baz 2>gorp.file \
+ > gorp.file2] [exec cat gorp.file] \
+ [exec cat gorp.file2]
+} {{} {foo bar} {biz baz}}
+test exec-15.4 {standard error redirection} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f "Line 1"
+ flush $f
+ eval exec [shellCmd "echo foo bar 1>&2"] 2>@ $f
+ puts $f "Line 3"
+ close $f
+ exec cat gorp.file
+} {Line 1
+foo bar
+Line 3}
+test exec-15.5 {standard error redirection} {unixExecs} {
+ exec echo "First line" > gorp.file
+ eval exec [shellCmd "echo foo bar 1>&2"] 2>> gorp.file
+ exec cat gorp.file
+} {First line
+foo bar}
+test exec-15.6 {standard error redirection} {unixExecs} {
+ eval exec [shellCmd "echo foo bar 1>&2"] > gorp.file2 2> gorp.file \
+ >& gorp.file 2> gorp.file2 | echo biz baz
+ list [exec cat gorp.file] [exec cat gorp.file2]
+} {{biz baz} {foo bar}}
+
+test exec-16.1 {flush output before exec} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f "First line"
+ exec echo "Second line" >@ $f
+ puts $f "Third line"
+ close $f
+ exec cat gorp.file
+} {First line
+Second line
+Third line}
+test exec-16.2 {flush output before exec} {unixExecs} {
+ set f [open gorp.file w]
+ puts $f "First line"
+ eval exec [shellCmd "echo Second line 1>&2"] >&@ $f > gorp.file2
+ puts $f "Third line"
+ close $f
+ exec cat gorp.file
+} {First line
+Second line
+Third line}
+
+test exec-17.1 { inheriting standard I/O } {unixOrPc unixExecs} {
+ set f [open script w]
+ puts $f {close stdout
+ set f [open gorp.file w]
+ catch {exec echo foobar &}
+ exec sleep 2
+ close $f
+ }
+ close $f
+ catch {eval exec $tcltest script} result
+ set f [open gorp.file r]
+ lappend result [read $f]
+ close $f
+ set result
+} {{foobar
+}}
+
+removeFile script
+removeFile gorp.file
+removeFile gorp.file2
+
+return {}
diff --git a/contrib/tcl/tests/expr.test b/contrib/tcl/tests/expr.test
new file mode 100644
index 0000000..d5dbab5
--- /dev/null
+++ b/contrib/tcl/tests/expr.test
@@ -0,0 +1,890 @@
+# 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) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) expr.test 1.48 96/02/16 08:55:51
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+if {([catch {expr T1()} msg] == 1) && ($msg == {unknown math function "T1"})} {
+ set gotT1 0
+ puts "This application hasn't been compiled with the \"T1\" and"
+ puts "\"T2\" math functions, so I'll skip some of the expr tests."
+} else {
+ set gotT1 1
+}
+
+# First, test all of the integer operators individually.
+
+test expr-1.1 {integer operators} {expr -4} -4
+test expr-1.2 {integer operators} {expr -(1+4)} -5
+test expr-1.3 {integer operators} {expr ~3} -4
+test expr-1.4 {integer operators} {expr !2} 0
+test expr-1.5 {integer operators} {expr !0} 1
+test expr-1.6 {integer operators} {expr 4*6} 24
+test expr-1.7 {integer operators} {expr 36/12} 3
+test expr-1.8 {integer operators} {expr 27/4} 6
+test expr-1.9 {integer operators} {expr 27%4} 3
+test expr-1.10 {integer operators} {expr 2+2} 4
+test expr-1.11 {integer operators} {expr 2-6} -4
+test expr-1.12 {integer operators} {expr 1<<3} 8
+test expr-1.13 {integer operators} {expr 0xff>>2} 63
+test expr-1.14 {integer operators} {expr -1>>2} -1
+test expr-1.15 {integer operators} {expr 3>2} 1
+test expr-1.16 {integer operators} {expr 2>2} 0
+test expr-1.17 {integer operators} {expr 1>2} 0
+test expr-1.18 {integer operators} {expr 3<2} 0
+test expr-1.19 {integer operators} {expr 2<2} 0
+test expr-1.20 {integer operators} {expr 1<2} 1
+test expr-1.21 {integer operators} {expr 3>=2} 1
+test expr-1.22 {integer operators} {expr 2>=2} 1
+test expr-1.23 {integer operators} {expr 1>=2} 0
+test expr-1.24 {integer operators} {expr 3<=2} 0
+test expr-1.25 {integer operators} {expr 2<=2} 1
+test expr-1.26 {integer operators} {expr 1<=2} 1
+test expr-1.27 {integer operators} {expr 3==2} 0
+test expr-1.28 {integer operators} {expr 2==2} 1
+test expr-1.29 {integer operators} {expr 3!=2} 1
+test expr-1.30 {integer operators} {expr 2!=2} 0
+test expr-1.31 {integer operators} {expr 7&0x13} 3
+test expr-1.32 {integer operators} {expr 7^0x13} 20
+test expr-1.33 {integer operators} {expr 7|0x13} 23
+test expr-1.34 {integer operators} {expr 0&&1} 0
+test expr-1.35 {integer operators} {expr 0&&0} 0
+test expr-1.36 {integer operators} {expr 1&&3} 1
+test expr-1.37 {integer operators} {expr 0||1} 1
+test expr-1.38 {integer operators} {expr 3||0} 1
+test expr-1.39 {integer operators} {expr 0||0} 0
+test expr-1.40 {integer operators} {expr 3>2?44:66} 44
+test expr-1.41 {integer operators} {expr 2>3?44:66} 66
+test expr-1.42 {integer operators} {expr 36/5} 7
+test expr-1.43 {integer operators} {expr 36%5} 1
+test expr-1.44 {integer operators} {expr -36/5} -8
+test expr-1.45 {integer operators} {expr -36%5} 4
+test expr-1.46 {integer operators} {expr 36/-5} -8
+test expr-1.47 {integer operators} {expr 36%-5} -4
+test expr-1.48 {integer operators} {expr -36/-5} 7
+test expr-1.49 {integer operators} {expr -36%-5} -1
+test expr-1.50 {integer operators} {expr +36} 36
+test expr-1.51 {integer operators} {expr +--++36} 36
+test expr-1.52 {integer operators} {expr +36%+5} 1
+
+# Check the floating-point operators individually, along with
+# automatic conversion to integers where needed.
+
+test expr-2.1 {floating-point operators} {expr -4.2} -4.2
+test expr-2.2 {floating-point operators} {expr -(1.1+4.2)} -5.3
+test expr-2.3 {floating-point operators} {expr +5.7} 5.7
+test expr-2.4 {floating-point operators} {expr +--+-62.0} -62.0
+test expr-2.5 {floating-point operators} {expr !2.1} 0
+test expr-2.6 {floating-point operators} {expr !0.0} 1
+test expr-2.7 {floating-point operators} {expr 4.2*6.3} 26.46
+test expr-2.8 {floating-point operators} {expr 36.0/12.0} 3.0
+test expr-2.9 {floating-point operators} {expr 27/4.0} 6.75
+test expr-2.10 {floating-point operators} {expr 2.3+2.1} 4.4
+test expr-2.11 {floating-point operators} {expr 2.3-6.5} -4.2
+test expr-2.12 {floating-point operators} {expr 3.1>2.1} 1
+test expr-2.13 {floating-point operators} {expr {2.1 > 2.1}} 0
+test expr-2.14 {floating-point operators} {expr 1.23>2.34e+1} 0
+test expr-2.15 {floating-point operators} {expr 3.45<2.34} 0
+test expr-2.16 {floating-point operators} {expr 0.002e3<--200e-2} 0
+test expr-2.17 {floating-point operators} {expr 1.1<2.1} 1
+test expr-2.18 {floating-point operators} {expr 3.1>=2.2} 1
+test expr-2.19 {floating-point operators} {expr 2.345>=2.345} 1
+test expr-2.20 {floating-point operators} {expr 1.1>=2.2} 0
+test expr-2.21 {floating-point operators} {expr 3.0<=2.0} 0
+test expr-2.22 {floating-point operators} {expr 2.2<=2.2} 1
+test expr-2.23 {floating-point operators} {expr 2.2<=2.2001} 1
+test expr-2.24 {floating-point operators} {expr 3.2==2.2} 0
+test expr-2.25 {floating-point operators} {expr 2.2==2.2} 1
+test expr-2.26 {floating-point operators} {expr 3.2!=2.2} 1
+test expr-2.27 {floating-point operators} {expr 2.2!=2.2} 0
+test expr-2.28 {floating-point operators} {expr 0.0&&0.0} 0
+test expr-2.29 {floating-point operators} {expr 0.0&&1.3} 0
+test expr-2.30 {floating-point operators} {expr 1.3&&0.0} 0
+test expr-2.31 {floating-point operators} {expr 1.3&&3.3} 1
+test expr-2.32 {floating-point operators} {expr 0.0||0.0} 0
+test expr-2.33 {floating-point operators} {expr 0.0||1.3} 1
+test expr-2.34 {floating-point operators} {expr 1.3||0.0} 1
+test expr-2.35 {floating-point operators} {expr 3.3||0.0} 1
+test expr-2.36 {floating-point operators} {expr 3.3>2.3?44.3:66.3} 44.3
+test expr-2.37 {floating-point operators} {expr 2.3>3.3?44.3:66.3} 66.3
+test expr-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-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-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-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-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-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-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-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-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-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-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-4.1 {string operators} {expr {"abc" > "def"}} 0
+test expr-4.2 {string operators} {expr {"def" > "def"}} 0
+test expr-4.3 {string operators} {expr {"g" > "def"}} 1
+test expr-4.4 {string operators} {expr {"abc" < "abd"}} 1
+test expr-4.5 {string operators} {expr {"abd" < "abd"}} 0
+test expr-4.6 {string operators} {expr {"abe" < "abd"}} 0
+test expr-4.7 {string operators} {expr {"abc" >= "def"}} 0
+test expr-4.8 {string operators} {expr {"def" >= "def"}} 1
+test expr-4.9 {string operators} {expr {"g" >= "def"}} 1
+test expr-4.10 {string operators} {expr {"abc" <= "abd"}} 1
+test expr-4.11 {string operators} {expr {"abd" <= "abd"}} 1
+test expr-4.12 {string operators} {expr {"abe" <= "abd"}} 0
+test expr-4.13 {string operators} {expr {"abc" == "abd"}} 0
+test expr-4.14 {string operators} {expr {"abd" == "abd"}} 1
+test expr-4.15 {string operators} {expr {"abc" != "abd"}} 1
+test expr-4.16 {string operators} {expr {"abd" != "abd"}} 0
+test expr-4.17 {string operators} {expr {"0y" < "0x12"}} 1
+test expr-4.18 {string operators} {expr {"." < " "}} 0
+
+# The following tests are non-portable because on some systems "+"
+# and "-" can be parsed as numbers.
+
+test expr-4.19 {string operators} {nonPortable} {expr {"0" == "+"}} 0
+test expr-4.20 {string operators} {nonPortable} {expr {"0" == "-"}} 0
+test expr-4.21 {string operators} {expr {1?"foo":"bar"}} foo
+test expr-4.22 {string operators} {expr {0?"foo":"bar"}} bar
+
+# Operators that aren't legal on string operands.
+
+test expr-5.1 {illegal string operations} {
+ list [catch {expr {-"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-5.2 {illegal string operations} {
+ list [catch {expr {+"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-5.3 {illegal string operations} {
+ list [catch {expr {~"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-5.4 {illegal string operations} {
+ list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-5.5 {illegal string operations} {
+ list [catch {expr {"a"*"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-5.6 {illegal string operations} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-5.7 {illegal string operations} {
+ list [catch {expr {"a"%"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "%"}}
+test expr-5.8 {illegal string operations} {
+ list [catch {expr {"a"+"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-5.9 {illegal string operations} {
+ list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-5.10 {illegal string operations} {
+ list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+test expr-5.11 {illegal string operations} {
+ list [catch {expr {"a">>"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of ">>"}}
+test expr-5.12 {illegal string operations} {
+ list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-5.13 {illegal string operations} {
+ list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+test expr-5.14 {illegal string operations} {
+ list [catch {expr {"a"|"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "|"}}
+test expr-5.15 {illegal string operations} {
+ list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&&"}}
+test expr-5.16 {illegal string operations} {
+ list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "||"}}
+test expr-5.17 {illegal string operations} {
+ list [catch {expr {"a"?4:2}} msg] $msg
+} {1 {can't use non-numeric string as operand of "?"}}
+
+# Check precedence pairwise.
+
+test expr-6.1 {precedence checks} {expr -~3} 4
+test expr-6.2 {precedence checks} {expr -!3} 0
+test expr-6.3 {precedence checks} {expr -~0} 1
+
+test expr-7.1 {precedence checks} {expr 2*4/6} 1
+test expr-7.2 {precedence checks} {expr 24/6*3} 12
+test expr-7.3 {precedence checks} {expr 24/6/2} 2
+
+test expr-8.1 {precedence checks} {expr -2+4} 2
+test expr-8.2 {precedence checks} {expr -2-4} -6
+test expr-8.3 {precedence checks} {expr +2-4} -2
+
+test expr-9.1 {precedence checks} {expr 2*3+4} 10
+test expr-9.2 {precedence checks} {expr 8/2+4} 8
+test expr-9.3 {precedence checks} {expr 8%3+4} 6
+test expr-9.4 {precedence checks} {expr 2*3-1} 5
+test expr-9.5 {precedence checks} {expr 8/2-1} 3
+test expr-9.6 {precedence checks} {expr 8%3-1} 1
+
+test expr-10.1 {precedence checks} {expr 6-3-2} 1
+
+test expr-11.1 {precedence checks} {expr 7+1>>2} 2
+test expr-11.2 {precedence checks} {expr 7+1<<2} 32
+test expr-11.3 {precedence checks} {expr 7>>3-2} 3
+test expr-11.4 {precedence checks} {expr 7<<3-2} 14
+
+test expr-12.1 {precedence checks} {expr 6>>1>4} 0
+test expr-12.2 {precedence checks} {expr 6>>1<2} 0
+test expr-12.3 {precedence checks} {expr 6>>1>=3} 1
+test expr-12.4 {precedence checks} {expr 6>>1<=2} 0
+test expr-12.5 {precedence checks} {expr 6<<1>5} 1
+test expr-12.6 {precedence checks} {expr 6<<1<5} 0
+test expr-12.7 {precedence checks} {expr 5<=6<<1} 1
+test expr-12.8 {precedence checks} {expr 5>=6<<1} 0
+
+test expr-13.1 {precedence checks} {expr 2<3<4} 1
+test expr-13.2 {precedence checks} {expr 0<4>2} 0
+test expr-13.3 {precedence checks} {expr 4>2<1} 0
+test expr-13.4 {precedence checks} {expr 4>3>2} 0
+test expr-13.5 {precedence checks} {expr 4>3>=2} 0
+test expr-13.6 {precedence checks} {expr 4>=3>2} 0
+test expr-13.7 {precedence checks} {expr 4>=3>=2} 0
+test expr-13.8 {precedence checks} {expr 0<=4>=2} 0
+test expr-13.9 {precedence checks} {expr 4>=2<=0} 0
+test expr-13.10 {precedence checks} {expr 2<=3<=4} 1
+
+test expr-14.1 {precedence checks} {expr 1==4>3} 1
+test expr-14.2 {precedence checks} {expr 0!=4>3} 1
+test expr-14.3 {precedence checks} {expr 1==3<4} 1
+test expr-14.4 {precedence checks} {expr 0!=3<4} 1
+test expr-14.5 {precedence checks} {expr 1==4>=3} 1
+test expr-14.6 {precedence checks} {expr 0!=4>=3} 1
+test expr-14.7 {precedence checks} {expr 1==3<=4} 1
+test expr-14.8 {precedence checks} {expr 0!=3<=4} 1
+
+test expr-15.1 {precedence checks} {expr 1==3==3} 0
+test expr-15.2 {precedence checks} {expr 3==3!=2} 1
+test expr-15.3 {precedence checks} {expr 2!=3==3} 0
+test expr-15.4 {precedence checks} {expr 2!=1!=1} 0
+
+test expr-16.1 {precedence checks} {expr 2&3==2} 0
+test expr-16.2 {precedence checks} {expr 1&3!=3} 0
+
+test expr-17.1 {precedence checks} {expr 7&3^0x10} 19
+test expr-17.2 {precedence checks} {expr 7^0x10&3} 7
+
+test expr-18.1 {precedence checks} {expr 7^0x10|3} 23
+test expr-18.2 {precedence checks} {expr 7|0x10^3} 23
+
+test expr-19.1 {precedence checks} {expr 7|3&&1} 1
+test expr-19.2 {precedence checks} {expr 1&&3|7} 1
+test expr-19.3 {precedence checks} {expr 0&&1||1} 1
+test expr-19.4 {precedence checks} {expr 1||1&&0} 1
+
+test expr-20.1 {precedence checks} {expr 1||0?3:4} 3
+test expr-20.2 {precedence checks} {expr 1?0:4||1} 0
+test expr-20.3 {precedence checks} {expr 1?2:0?3:4} 2
+test expr-20.4 {precedence checks} {expr 0?2:0?3:4} 4
+test expr-20.5 {precedence checks} {expr 1?2?3:4:0} 3
+test expr-20.6 {precedence checks} {expr 0?2?3:4:0} 0
+
+# Parentheses.
+
+test expr-21.1 {parenthesization} {expr (2+4)*6} 36
+test expr-21.2 {parenthesization} {expr (1?0:4)||1} 1
+test expr-21.3 {parenthesization} {expr +(3-4)} -1
+
+# Embedded commands and variable names.
+
+set a 16
+test expr-22.1 {embedded variables} {expr {2*$a}} 32
+test expr-22.2 {embedded variables} {
+ set x -5
+ set y 10
+ expr {$x + $y}
+} {5}
+test expr-22.3 {embedded variables} {
+ set x " -5"
+ set y " +10"
+ expr {$x + $y}
+} {5}
+test expr-22.4 {embedded commands and variables} {expr {[set a] - 14}} 2
+test expr-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-23.1 {double quotes} {expr {"abc"}} abc
+test expr-23.2 {double quotes} {
+ set a 189
+ expr {"$a.bc"}
+} 189.bc
+test expr-23.3 {double quotes} {
+ set b2 xyx
+ expr {"$b2$b2$b2.[set b2].[set b2]"}
+} xyxxyxxyx.xyx.xyx
+test expr-23.4 {double quotes} {expr {"11\}\}22"}} 11}}22
+test expr-23.5 {double quotes} {expr {"\*bc"}} {*bc}
+test expr-23.6 {double quotes} {
+ catch {unset bogus__}
+ list [catch {expr {"$bogus__"}} msg] $msg
+} {1 {can't read "bogus__": no such variable}}
+test expr-23.7 {double quotes} {
+ list [catch {expr {"a[error Testing]bc"}} msg] $msg
+} {1 Testing}
+test expr-23.8 {double quotes} {
+ list [catch {expr {"12398712938788234-1298379" != ""}} msg] $msg
+} {0 1}
+
+# Numbers in various bases.
+
+test expr-24.1 {numbers in different bases} {expr 0x20} 32
+test expr-24.2 {numbers in different bases} {expr 015} 13
+
+# Conversions between various data types.
+
+test expr-25.1 {type conversions} {expr 2+2.5} 4.5
+test expr-25.2 {type conversions} {expr 2.5+2} 4.5
+test expr-25.3 {type conversions} {expr 2-2.5} -0.5
+test expr-25.4 {type conversions} {expr 2/2.5} 0.8
+test expr-25.5 {type conversions} {expr 2>2.5} 0
+test expr-25.6 {type conversions} {expr 2.5>2} 1
+test expr-25.7 {type conversions} {expr 2<2.5} 1
+test expr-25.8 {type conversions} {expr 2>=2.5} 0
+test expr-25.9 {type conversions} {expr 2<=2.5} 1
+test expr-25.10 {type conversions} {expr 2==2.5} 0
+test expr-25.11 {type conversions} {expr 2!=2.5} 1
+test expr-25.12 {type conversions} {expr 2>"ab"} 0
+test expr-25.13 {type conversions} {expr {2>" "}} 1
+test expr-25.14 {type conversions} {expr {"24.1a" > 24.1}} 1
+test expr-25.15 {type conversions} {expr {24.1 > "24.1a"}} 0
+test expr-25.16 {type conversions} {expr 2+2.5} 4.5
+test expr-25.17 {type conversions} {expr 2+2.5} 4.5
+test expr-25.18 {type conversions} {expr 2.0e2} 200.0
+test expr-25.19 {type conversions} {expr 2.0e15} 2e+15
+test expr-25.20 {type conversions} {expr 10.0} 10.0
+
+# Various error conditions.
+
+test expr-26.1 {error conditions} {
+ list [catch {expr 2+"a"} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-26.2 {error conditions} {
+ list [catch {expr 2+4*} msg] $msg
+} {1 {syntax error in expression "2+4*"}}
+test expr-26.3 {error conditions} {
+ list [catch {expr 2+4*(} msg] $msg
+} {1 {syntax error in expression "2+4*("}}
+catch {unset _non_existent_}
+test expr-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-26.5 {error conditions} {
+ list [catch {expr {2+$a}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-26.6 {error conditions} {
+ list [catch {expr {2+[set a]}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-26.7 {error conditions} {
+ list [catch {expr {2+(4}} msg] $msg
+} {1 {unmatched parentheses in expression "2+(4"}}
+test expr-26.8 {error conditions} {
+ list [catch {expr 2/0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-26.9 {error conditions} {
+ list [catch {expr 2%0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-26.10 {error conditions} {
+ list [catch {expr 2.0/0.0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-26.11 {error conditions} {
+ list [catch {expr 2#} msg] $msg
+} {1 {syntax error in expression "2#"}}
+test expr-26.12 {error conditions} {
+ list [catch {expr a.b} msg] $msg
+} {1 {syntax error in expression "a.b"}}
+test expr-26.13 {error conditions} {
+ list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-26.14 {error conditions} {
+ list [catch {expr 2:3} msg] $msg
+} {1 {can't have : operator without ? first}}
+test expr-26.15 {error conditions} {
+ list [catch {expr a@b} msg] $msg
+} {1 {syntax error in expression "a@b"}}
+test expr-26.16 {error conditions} {
+ list [catch {expr a[b} msg] $msg
+} {1 {missing close-bracket}}
+test expr-26.17 {error conditions} {
+ list [catch {expr a`b} msg] $msg
+} {1 {syntax error in expression "a`b"}}
+test expr-26.18 {error conditions} {
+ list [catch {expr \"a\"\{b} msg] $msg
+} {1 {missing close-brace}}
+test expr-26.19 {error conditions} {
+ list [catch {expr a} msg] $msg
+} {1 {syntax error in expression "a"}}
+test expr-26.20 {error conditions} {
+ list [catch expr msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+
+# Cancelled evaluation.
+
+test expr-27.1 {cancelled evaluation} {
+ set a 1
+ expr {0&&[set a 2]}
+ set a
+} 1
+test expr-27.2 {cancelled evaluation} {
+ set a 1
+ expr {1||[set a 2]}
+ set a
+} 1
+test expr-27.3 {cancelled evaluation} {
+ set a 1
+ expr {0?[set a 2]:1}
+ set a
+} 1
+test expr-27.4 {cancelled evaluation} {
+ set a 1
+ expr {1?2:[set a 2]}
+ set a
+} 1
+catch {unset x}
+test expr-27.5 {cancelled evaluation} {
+ list [catch {expr {[info exists x] && $x}} msg] $msg
+} {0 0}
+test expr-27.6 {cancelled evaluation} {
+ list [catch {expr {0 && [concat $x]}} msg] $msg
+} {0 0}
+test expr-27.7 {cancelled evaluation} {
+ set one 1
+ list [catch {expr {1 || 1/$one}} msg] $msg
+} {0 1}
+test expr-27.8 {cancelled evaluation} {
+ list [catch {expr {1 || -"string"}} msg] $msg
+} {0 1}
+test expr-27.9 {cancelled evaluation} {
+ list [catch {expr {1 || ("string" * ("x" && "y"))}} msg] $msg
+} {0 1}
+test expr-27.10 {cancelled evaluation} {
+ set x -1.0
+ list [catch {expr {($x > 0) ? round(log($x)) : 0}} msg] $msg
+} {0 0}
+
+# Tcl_ExprBool as used in "if" statements
+
+test expr-28.1 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {2} {set a 2}
+ set a
+} 2
+test expr-28.2 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {0} {set a 2}
+ set a
+} 1
+test expr-28.3 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {1.2} {set a 2}
+ set a
+} 2
+test expr-28.4 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {-1.1} {set a 2}
+ set a
+} 2
+test expr-28.5 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {0.0} {set a 2}
+ set a
+} 1
+test expr-28.6 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"YES"} {set a 2}
+ set a
+} 2
+test expr-28.7 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"no"} {set a 2}
+ set a
+} 1
+test expr-28.8 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"true"} {set a 2}
+ set a
+} 2
+test expr-28.9 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"fAlse"} {set a 2}
+ set a
+} 1
+test expr-28.10 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"on"} {set a 2}
+ set a
+} 2
+test expr-28.11 {Tcl_ExprBoolean usage} {
+ set a 1
+ if {"Off"} {set a 2}
+ set a
+} 1
+test expr-28.12 {Tcl_ExprBool usage} {
+ list [catch {if {"abc"} {}} msg] $msg
+} {1 {expected boolean value but got "abc"}}
+test expr-28.13 {Tcl_ExprBool usage} {
+ list [catch {if {"ogle"} {}} msg] $msg
+} {1 {expected boolean value but got "ogle"}}
+test expr-28.14 {Tcl_ExprBool usage} {
+ list [catch {if {"o"} {}} msg] $msg
+} {1 {expected boolean value but got "o"}}
+
+# Operands enclosed in braces
+
+test expr-29.1 {braces} {expr {{abc}}} abc
+test expr-29.2 {braces} {expr {{00010}}} 8
+test expr-29.3 {braces} {expr {{3.1200000}}} 3.12
+test expr-29.4 {braces} {expr {{a{b}{1 {2 3}}c}}} "a{b}{1 {2 3}}c"
+test expr-29.5 {braces} {
+ list [catch {expr "\{abc"} msg] $msg
+} {1 {missing close-brace}}
+
+# Very long values
+
+test expr-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-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-31.1 {multiple arguments to expr command} {
+ expr 4 + ( 6 *12) -3
+} 73
+test expr-31.2 {multiple arguments to expr command} {
+ list [catch {expr 2 + (3 + 4} msg] $msg
+} {1 {unmatched parentheses in expression "2 + (3 + 4"}}
+test expr-31.3 {multiple arguments to expr command} {
+ list [catch {expr 2 + 3 +} msg] $msg
+} {1 {syntax error in expression "2 + 3 +"}}
+test expr-31.4 {multiple arguments to expr command} {
+ list [catch {expr 2 + 3 )} msg] $msg
+} {1 {syntax error in expression "2 + 3 )"}}
+
+# Math functions
+
+test expr-32.1 {math functions in expressions} {
+ expr acos(0.5)
+} {1.0472}
+test expr-32.2 {math functions in expressions} {
+ expr asin(0.5)
+} {0.523599}
+test expr-32.3 {math functions in expressions} {
+ expr atan(1.0)
+} {0.785398}
+test expr-32.4 {math functions in expressions} {
+ expr atan2(2.0, 2.0)
+} {0.785398}
+test expr-32.5 {math functions in expressions} {
+ expr ceil(1.999)
+} {2.0}
+test expr-32.6 {math functions in expressions} {
+ expr cos(.1)
+} {0.995004}
+test expr-32.7 {math functions in expressions} {
+ expr cosh(.1)
+} {1.005}
+test expr-32.8 {math functions in expressions} {
+ expr exp(1.0)
+} {2.71828}
+test expr-32.9 {math functions in expressions} {
+ expr floor(2.000)
+} {2.0}
+test expr-32.10 {math functions in expressions} {
+ expr floor(2.001)
+} {2.0}
+test expr-32.11 {math functions in expressions} {
+ expr fmod(7.3, 3.2)
+} {0.9}
+test expr-32.12 {math functions in expressions} {
+ expr hypot(3.0, 4.0)
+} {5.0}
+test expr-32.13 {math functions in expressions} {
+ expr log(2.8)
+} {1.02962}
+test expr-32.14 {math functions in expressions} {
+ expr log10(2.8)
+} {0.447158}
+test expr-32.15 {math functions in expressions} {
+ expr pow(2.1, 3.1)
+} {9.97424}
+test expr-32.16 {math functions in expressions} {
+ expr sin(.1)
+} {0.0998334}
+test expr-32.17 {math functions in expressions} {
+ expr sinh(.1)
+} {0.100167}
+test expr-32.18 {math functions in expressions} {
+ expr sqrt(2.0)
+} {1.41421}
+test expr-32.19 {math functions in expressions} {
+ expr tan(0.8)
+} {1.02964}
+test expr-32.20 {math functions in expressions} {
+ expr tanh(0.8)
+} {0.664037}
+test expr-32.21 {math functions in expressions} {
+ expr abs(-1.8)
+} {1.8}
+test expr-32.22 {math functions in expressions} {
+ expr abs(10.0)
+} {10.0}
+test expr-32.23 {math functions in expressions} {
+ expr abs(-4)
+} {4}
+test expr-32.24 {math functions in expressions} {
+ expr abs(66)
+} {66}
+test expr-32.25 {math functions in expressions} {nonPortable} {
+ list [catch {expr abs(0x80000000)} msg] $msg
+} {1 {integer value too large to represent}}
+test expr-32.26 {math functions in expressions} {
+ expr double(1)
+} {1.0}
+test expr-32.27 {math functions in expressions} {
+ expr double(1.1)
+} {1.1}
+test expr-32.28 {math functions in expressions} {
+ expr int(1)
+} {1}
+test expr-32.29 {math functions in expressions} {
+ expr int(1.4)
+} {1}
+test expr-32.30 {math functions in expressions} {
+ expr int(1.6)
+} {1}
+test expr-32.31 {math functions in expressions} {
+ expr int(-1.4)
+} {-1}
+test expr-32.32 {math functions in expressions} {
+ expr int(-1.6)
+} {-1}
+test expr-32.33 {math functions in expressions} {
+ list [catch {expr int(1e60)} msg] $msg
+} {1 {integer value too large to represent}}
+test expr-32.34 {math functions in expressions} {
+ list [catch {expr int(-1e60)} msg] $msg
+} {1 {integer value too large to represent}}
+test expr-32.35 {math functions in expressions} {
+ expr round(1.49)
+} {1}
+test expr-32.36 {math functions in expressions} {
+ expr round(1.51)
+} {2}
+test expr-32.37 {math functions in expressions} {
+ expr round(-1.49)
+} {-1}
+test expr-32.38 {math functions in expressions} {
+ expr round(-1.51)
+} {-2}
+test expr-32.39 {math functions in expressions} {
+ list [catch {expr round(1e60)} msg] $msg
+} {1 {integer value too large to represent}}
+test expr-32.40 {math functions in expressions} {
+ list [catch {expr round(-1e60)} msg] $msg
+} {1 {integer value too large to represent}}
+test expr-32.41 {math functions in expressions} {
+ list [catch {expr pow(1.0 + 3.0 - 2, .8 * 5)} msg] $msg
+} {0 16.0}
+test expr-32.42 {math functions in expressions} {
+ list [catch {expr hypot(5*.8,3)} msg] $msg
+} {0 5.0}
+if $gotT1 {
+ test expr-32.43 {math functions in expressions} {
+ expr 2*T1()
+ } 246
+ test expr-32.44 {math functions in expressions} {
+ expr T2()*3
+ } 1035
+}
+
+test expr-33.1 {conversions and fancy args to math functions} {
+ expr hypot ( 3 , 4 )
+} 5.0
+test expr-33.2 {conversions and fancy args to math functions} {
+ expr hypot ( (2.0+1.0) , 4 )
+} 5.0
+test expr-33.3 {conversions and fancy args to math functions} {
+ expr hypot ( 3 , (3.0 + 1.0) )
+} 5.0
+test expr-33.4 {conversions and fancy args to math functions} {
+ expr cos(acos(0.1))
+} 0.1
+
+test expr-34.1 {errors in math functions} {
+ list [catch {expr func_2(1.0)} msg] $msg
+} {1 {unknown math function "func_2"}}
+test expr-34.2 {errors in math functions} {
+ list [catch {expr func|(1.0)} msg] $msg
+} {1 {syntax error in expression "func|(1.0)"}}
+test expr-34.3 {errors in math functions} {
+ list [catch {expr {hypot("a b", 2.0)}} msg] $msg
+} {1 {argument to math function didn't have numeric value}}
+test expr-34.4 {errors in math functions} {
+ list [catch {expr hypot(1.0 2.0)} msg] $msg
+} {1 {syntax error in expression "hypot(1.0 2.0)"}}
+test expr-34.5 {errors in math functions} {
+ list [catch {expr hypot(1.0, 2.0} msg] $msg
+} {1 {syntax error in expression "hypot(1.0, 2.0"}}
+test expr-34.6 {errors in math functions} {
+ list [catch {expr hypot(1.0 ,} msg] $msg
+} {1 {syntax error in expression "hypot(1.0 ,"}}
+test expr-34.7 {errors in math functions} {
+ list [catch {expr hypot(1.0)} msg] $msg
+} {1 {too few arguments for math function}}
+test expr-34.8 {errors in math functions} {
+ list [catch {expr hypot(1.0, 2.0, 3.0)} msg] $msg
+} {1 {too many arguments for math function}}
+test expr-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-34.10 {errors in math functions} {nonPortable} {
+ 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-34.11 {errors in math functions} {
+ 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-34.12 {errors in math functions} {
+ 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-34.13 {errors in math functions} {
+ list [catch {expr int(1.0e30)} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test expr-34.14 {errors in math functions} {
+ list [catch {expr int(-1.0e30)} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test expr-34.15 {errors in math functions} {
+ list [catch {expr round(1.0e30)} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test expr-34.16 {errors in math functions} {
+ list [catch {expr round(-1.0e30)} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+if $gotT1 {
+ test expr-34.17 {errors in math functions} {
+ list [catch {expr T1(4)} msg] $msg
+ } {1 {syntax error in expression "T1(4)"}}
+}
+
+catch {unset tcl_precision}
+test expr-35.1 {tcl_precision variable} {
+ expr 2.0/3
+} 0.666667
+set tcl_precision 1
+test expr-35.2 {tcl_precision variable} {
+ expr 2.0/3
+} 0.7
+test expr-35.3 {tcl_precision variable} {
+ expr 2.0/3
+} 0.7
+test expr-35.4 {tcl_precision variable} {
+ list [catch {set tcl_precision 0} msg] $msg [expr 2.0/3]
+} {1 {can't set "tcl_precision": improper value for precision} 0.7}
+test expr-35.5 {tcl_precision variable} {
+ list [catch {set tcl_precision 101} msg] $msg [expr 2.0/3]
+} {1 {can't set "tcl_precision": improper value for precision} 0.7}
+test expr-35.6 {tcl_precision variable} {
+ list [catch {set tcl_precision {}} msg] $msg [expr 2.0/3]
+} {1 {can't set "tcl_precision": improper value for precision} 0.7}
+test expr-35.7 {tcl_precision variable} {
+ list [catch {set tcl_precision {1 2 3}} msg] $msg [expr 2.0/3]
+} {1 {can't set "tcl_precision": improper value for precision} 0.7}
+catch {unset tcl_precision}
+test expr-35.8 {tcl_precision variable} {
+ expr 2.0/3
+} 0.666667
+
+test expr-36.1 {ExprLooksLikeInt procedure} {
+ list [catch {expr 0289} msg] $msg
+} {1 {syntax error in expression "0289"}}
+test expr-36.2 {ExprLooksLikeInt procedure} {
+ set x 0289
+ list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-36.3 {ExprLooksLikeInt procedure} {
+ list [catch {expr 0289.1} msg] $msg
+} {0 289.1}
+test expr-36.4 {ExprLooksLikeInt procedure} {
+ set x 0289.1
+ list [catch {expr {$x+1}} msg] $msg
+} {0 290.1}
+test expr-36.5 {ExprLooksLikeInt procedure} {
+ set x { +22}
+ list [catch {expr {$x+1}} msg] $msg
+} {0 23}
+test expr-36.6 {ExprLooksLikeInt procedure} {
+ set x { -22}
+ list [catch {expr {$x+1}} msg] $msg
+} {0 -21}
+test expr-36.7 {ExprLooksLikeInt procedure} {nonPortable unixOnly} {
+ list [catch {expr nan} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-36.8 {ExprLooksLikeInt procedure} {
+ list [catch {expr 78e1} msg] $msg
+} {0 780.0}
+test expr-36.9 {ExprLooksLikeInt procedure} {
+ list [catch {expr 24E1} msg] $msg
+} {0 240.0}
+test expr-36.10 {ExprLooksLikeInt procedure} {nonPortable unixOnly} {
+ list [catch {expr 78e} msg] $msg
+} {1 {syntax error in expression "78e"}}
+
+
+# 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."
+}
diff --git a/contrib/tcl/tests/fhandle.test b/contrib/tcl/tests/fhandle.test
new file mode 100644
index 0000000..18fdb90
--- /dev/null
+++ b/contrib/tcl/tests/fhandle.test
@@ -0,0 +1,63 @@
+# This file tests the functions in tclFHandle.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) 1995-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.
+#
+# SCCS: @(#) fhandle.test 1.3 96/03/26 11:49:04
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+if {[info commands testfhandle] == {}} {
+ puts "This application hasn't been compiled with the \"testfhandle\""
+ puts "command, so I can't test the procedures in tclFHandle.c."
+ return
+}
+
+test fhandle-1.1 {file handle creation/retrieval} {
+ testfhandle get 0 2 3
+ testfhandle get 1 2 3
+ set result [testfhandle compare 0 1]
+ testfhandle free 0
+ set result
+} {equal}
+test fhandle-1.2 {file handle creation/retrieval} {
+ testfhandle get 0 2 3
+ testfhandle get 1 2 4
+ set result [testfhandle compare 0 1]
+ testfhandle free 0
+ set result
+} {notequal}
+test fhandle-1.3 {file handle creation/retrieval} {
+ testfhandle get 0 2 3
+ testfhandle get 1 2 4
+ set result [testfhandle compare 0 1]
+ testfhandle free 0
+ testfhandle free 1
+ set result
+} {notequal}
+test fhandle-1.4 {file handle creation/retrieval} {
+ testfhandle get 0 2 3
+ testfhandle get 1 5 3
+ set result [testfhandle compare 0 1]
+ testfhandle free 0
+ testfhandle free 1
+ set result
+} {notequal}
+test fhandle-1.5 {file handle creation/retrieval} {
+ testfhandle get 0 5 6
+ set result [testfhandle info2 0]
+ testfhandle free 0
+ set result
+} {5 6}
+test fhandle-1.6 {file handle creation/retrieval} {
+ testfhandle get 0 5 6
+ set result [testfhandle info1 0]
+ testfhandle free 0
+ set result
+} {5}
diff --git a/contrib/tcl/tests/fileName.test b/contrib/tcl/tests/fileName.test
new file mode 100644
index 0000000..26e84d9
--- /dev/null
+++ b/contrib/tcl/tests/fileName.test
@@ -0,0 +1,1401 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) fileName.test 1.20 96/04/19 12:36:13
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+if {[info commands testsetplatform] == {}} {
+ puts "This application hasn't been compiled with the \"testsetplatform\""
+ puts "command, so I can't test the filename conversion procedures."
+ return
+}
+
+global env
+set platform [testgetplatform]
+
+test filename-1.1 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype /
+} absolute
+test filename-1.2 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype /foo
+} absolute
+test filename-1.3 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype foo
+} relative
+test filename-1.4 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype c:/foo
+} relative
+test filename-1.5 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype ~
+} absolute
+test filename-1.6 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype ~/foo
+} absolute
+test filename-1.7 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype ~foo
+} absolute
+test filename-1.8 {Tcl_GetPathType: unix} {
+ testsetplatform unix
+ file pathtype ./~foo
+} relative
+
+test filename-2.1 {Tcl_GetPathType: mac, denerate names} {
+ testsetplatform mac
+ file pathtype /
+} relative
+test filename-2.2 {Tcl_GetPathType: mac, denerate names} {
+ testsetplatform mac
+ file pathtype /.
+} relative
+test filename-2.3 {Tcl_GetPathType: mac, denerate names} {
+ testsetplatform mac
+ file pathtype /..
+} relative
+test filename-2.4 {Tcl_GetPathType: mac, denerate names} {
+ testsetplatform mac
+ file pathtype //.//
+} relative
+test filename-2.5 {Tcl_GetPathType: mac, denerate names} {
+ testsetplatform mac
+ file pathtype //.//../.
+} relative
+test filename-2.6 {Tcl_GetPathType: mac, tilde names} {
+ testsetplatform mac
+ file pathtype ~
+} absolute
+test filename-2.7 {Tcl_GetPathType: mac, tilde names} {
+ testsetplatform mac
+ file pathtype ~:
+} absolute
+test filename-2.8 {Tcl_GetPathType: mac, tilde names} {
+ testsetplatform mac
+ file pathtype ~:foo
+} absolute
+test filename-2.9 {Tcl_GetPathType: mac, tilde names} {
+ testsetplatform mac
+ file pathtype ~/
+} absolute
+test filename-2.10 {Tcl_GetPathType: mac, tilde names} {
+ testsetplatform mac
+ file pathtype ~/foo
+} absolute
+test filename-2.11 {Tcl_GetPathType: mac, unix-style names} {
+ testsetplatform mac
+ file pathtype /foo
+} absolute
+test filename-2.12 {Tcl_GetPathType: mac, unix-style names} {
+ testsetplatform mac
+ file pathtype /./foo
+} absolute
+test filename-2.13 {Tcl_GetPathType: mac, unix-style names} {
+ testsetplatform mac
+ file pathtype /..//./foo
+} absolute
+test filename-2.14 {Tcl_GetPathType: mac, unix-style names} {
+ testsetplatform mac
+ file pathtype /foo/bar
+} absolute
+test filename-2.15 {Tcl_GetPathType: mac, unix-style names} {
+ testsetplatform mac
+ file pathtype foo/bar
+} relative
+test filename-2.16 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype :
+} relative
+test filename-2.17 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype :foo
+} relative
+test filename-2.18 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype foo:
+} absolute
+test filename-2.19 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype foo:bar
+} absolute
+test filename-2.20 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype :foo:bar
+} relative
+test filename-2.21 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype ::foo:bar
+} relative
+test filename-2.22 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype ~foo
+} absolute
+test filename-2.23 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype :~foo
+} relative
+test filename-2.24 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype ~foo:
+} absolute
+test filename-2.25 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype foo/bar:
+} absolute
+test filename-2.26 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype /foo:
+} absolute
+test filename-2.27 {Tcl_GetPathType: mac, mac-style names} {
+ testsetplatform mac
+ file pathtype foo
+} relative
+
+test filename-3.1 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype /
+} volumerelative
+test filename-3.2 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype \\
+} volumerelative
+test filename-3.3 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype /foo
+} volumerelative
+test filename-3.4 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype \\foo
+} volumerelative
+test filename-3.5 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype c:/
+} absolute
+test filename-3.6 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype c:\\
+} absolute
+test filename-3.7 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype c:/foo
+} absolute
+test filename-3.8 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype c:\\foo
+} absolute
+test filename-3.9 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype c:
+} volumerelative
+test filename-3.10 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype c:foo
+} volumerelative
+test filename-3.11 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype foo
+} relative
+test filename-3.12 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype //foo/bar
+} absolute
+test filename-3.13 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype ~foo
+} absolute
+test filename-3.14 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype ~
+} absolute
+test filename-3.15 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype ~/foo
+} absolute
+test filename-3.16 {Tcl_GetPathType: windows} {
+ testsetplatform windows
+ file pathtype ./~foo
+} relative
+
+test filename-4.1 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split /
+} {/}
+test filename-4.2 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split /foo
+} {/ foo}
+test filename-4.3 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split /foo/bar
+} {/ foo bar}
+test filename-4.4 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-4.5 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split foo/bar
+} {foo bar}
+test filename-4.6 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ./foo/bar
+} {. foo bar}
+test filename-4.7 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-4.8 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ../foo/bar
+} {.. foo bar}
+test filename-4.9 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split {}
+} {}
+test filename-4.10 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split .
+} {.}
+test filename-4.11 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ../
+} {..}
+test filename-4.12 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ../..
+} {.. ..}
+test filename-4.13 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split //foo
+} {/ foo}
+test filename-4.14 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split foo//bar
+} {foo bar}
+test filename-4.15 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ~foo
+} {~foo}
+test filename-4.16 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ~foo/~bar
+} {~foo ./~bar}
+test filename-4.17 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-4.18 {Tcl_SplitPath: unix} {
+ testsetplatform unix
+ file split foo/bar~/baz
+} {foo bar~ baz}
+
+test filename-5.1 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:b
+} {a: b}
+test filename-5.2 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:b:c
+} {a: b c}
+test filename-5.3 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:b:c:
+} {a: b c}
+test filename-5.4 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:
+} {a:}
+test filename-5.5 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a::
+} {a: ::}
+test filename-5.6 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:::
+} {a: :: ::}
+test filename-5.7 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split :a
+} {a}
+test filename-5.8 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split :a::
+} {a ::}
+test filename-5.9 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split :
+} {:}
+test filename-5.10 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ::
+} {::}
+test filename-5.11 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split :::
+} {:: ::}
+test filename-5.12 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:::b
+} {a: :: :: b}
+test filename-5.13 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /a:b
+} {/a: b}
+test filename-5.14 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~:
+} {~:}
+test filename-5.15 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~/:
+} {~/:}
+test filename-5.16 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~:foo
+} {~: foo}
+test filename-5.17 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~/foo
+} {~: foo}
+test filename-5.18 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~foo:
+} {~foo:}
+test filename-5.19 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:~foo
+} {a: :~foo}
+test filename-5.20 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /
+} {:/}
+test filename-5.21 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a:b/c
+} {a: :b/c}
+test filename-5.22 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /foo
+} {foo:}
+test filename-5.23 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /a/b
+} {a: b}
+test filename-5.24 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /a/b/foo
+} {a: b foo}
+test filename-5.25 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a/b
+} {a b}
+test filename-5.26 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ./foo/bar
+} {: foo bar}
+test filename-5.27 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ../foo/bar
+} {:: foo bar}
+test filename-5.28 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split {}
+} {}
+test filename-5.29 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split .
+} {:}
+test filename-5.30 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ././
+} {: :}
+test filename-5.31 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ././.
+} {: : :}
+test filename-5.32 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ../
+} {::}
+test filename-5.33 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ..
+} {::}
+test filename-5.34 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ../..
+} {:: ::}
+test filename-5.35 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split //foo
+} {foo:}
+test filename-5.36 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split foo//bar
+} {foo bar}
+test filename-5.37 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~foo
+} {~foo:}
+test filename-5.38 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~
+} {~:}
+test filename-5.39 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split foo
+} {foo}
+test filename-5.40 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~/
+} {~:}
+test filename-5.41 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~foo/~bar
+} {~foo: :~bar}
+test filename-5.42 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split ~foo/~bar/~baz
+} {~foo: :~bar :~baz}
+test filename-5.43 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split foo/bar~/baz
+} {foo bar~ baz}
+test filename-5.44 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a/../b
+} {a :: b}
+test filename-5.45 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a/../../b
+} {a :: :: b}
+test filename-5.46 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split a/.././../b
+} {a :: : :: b}
+test filename-5.47 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /../bar
+} {bar:}
+test filename-5.48 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /./bar
+} {bar:}
+test filename-5.49 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split //.//.././bar
+} {bar:}
+test filename-5.50 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split /..
+} {:/..}
+test filename-5.51 {Tcl_SplitPath: mac} {
+ testsetplatform mac
+ file split //.//.././
+} {://.//.././}
+
+test filename-6.1 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /
+} {/}
+test filename-6.2 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /foo
+} {/ foo}
+test filename-6.3 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /foo/bar
+} {/ foo bar}
+test filename-6.4 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-6.5 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split foo/bar
+} {foo bar}
+test filename-6.6 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ./foo/bar
+} {. foo bar}
+test filename-6.7 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-6.8 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ../foo/bar
+} {.. foo bar}
+test filename-6.9 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split {}
+} {}
+test filename-6.10 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split .
+} {.}
+test filename-6.11 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ../
+} {..}
+test filename-6.12 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ../..
+} {.. ..}
+test filename-6.13 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split //foo
+} {/ foo}
+test filename-6.14 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split foo//bar
+} {foo bar}
+test filename-6.15 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.16 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.17 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.18 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split \\\\foo\\bar
+} {//foo/bar}
+test filename-6.19 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split \\\\foo\\bar/baz
+} {//foo/bar baz}
+test filename-6.20 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:/foo
+} {c:/ foo}
+test filename-6.21 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:foo
+} {c: foo}
+test filename-6.22 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:
+} {c:}
+test filename-6.23 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:\\
+} {c:/}
+test filename-6.24 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:/
+} {c:/}
+test filename-6.25 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:/./..
+} {c:/ . ..}
+test filename-6.26 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ~foo
+} {~foo}
+test filename-6.27 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ~foo/~bar
+} {~foo ./~bar}
+test filename-6.28 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-6.29 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split foo/bar~/baz
+} {foo bar~ baz}
+test filename-6.30 {Tcl_SplitPath: win} {
+ testsetplatform win
+ file split c:~foo
+} {c: ./~foo}
+
+test filename-7.1 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join / a
+} {/a}
+test filename-7.2 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join a b
+} {a/b}
+test filename-7.3 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join /a c /b d
+} {/b/d}
+test filename-7.4 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join /
+} {/}
+test filename-7.5 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join a
+} {a}
+test filename-7.6 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join {}
+} {}
+test filename-7.7 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join /a/ b
+} {/a/b}
+test filename-7.8 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join /a// b
+} {/a/b}
+test filename-7.9 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join /a/./../. b
+} {/a/./.././b}
+test filename-7.10 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join ~ a
+} {~/a}
+test filename-7.11 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join ~a ~b
+} {~b}
+test filename-7.12 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join ./~a b
+} {./~a/b}
+test filename-7.13 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join ./~a ~b
+} {~b}
+test filename-7.14 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join ./~a ./~b
+} {./~a/~b}
+test filename-7.15 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join a . b
+} {a/./b}
+test filename-7.16 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join a . ./~b
+} {a/./~b}
+test filename-7.17 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join //a b
+} {/a/b}
+test filename-7.18 {Tcl_JoinPath: unix} {
+ testsetplatform unix
+ file join /// a b
+} {/a/b}
+
+test filename-8.1 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a b
+} {:a:b}
+test filename-8.2 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join :a b
+} {:a:b}
+test filename-8.3 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a b:
+} {b:}
+test filename-8.4 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a: :b
+} {a:b}
+test filename-8.5 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a: :b:
+} {a:b}
+test filename-8.6 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a :: b
+} {:a::b}
+test filename-8.7 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a :: :: b
+} {:a:::b}
+test filename-8.8 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a ::: b
+} {:a:::b}
+test filename-8.9 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a: b:
+} {b:}
+test filename-8.10 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join /a/b
+} {a:b}
+test filename-8.11 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join /a/b c/d
+} {a:b:c:d}
+test filename-8.12 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join /a/b :c:d
+} {a:b:c:d}
+test filename-8.13 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join ~ foo
+} {~:foo}
+test filename-8.14 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join :: ::
+} {:::}
+test filename-8.15 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a: ::
+} {a::}
+test filename-8.16 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a {} b
+} {:a:b}
+test filename-8.17 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a::: b
+} {a:::b}
+test filename-8.18 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a : : :
+} {:a}
+test filename-8.19 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join :
+} {:}
+test filename-8.20 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join : a
+} {:a}
+test filename-8.21 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join a: :b/c
+} {a:b/c}
+test filename-8.22 {Tcl_JoinPath: mac} {
+ testsetplatform mac
+ file join :a :b/c
+} {:a:b/c}
+
+test filename-9.1 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join a b
+} {a/b}
+test filename-9.2 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join /a b
+} {/a/b}
+test filename-9.3 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join /a /b
+} {/b}
+test filename-9.4 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join c: foo
+} {c:foo}
+test filename-9.5 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join c:/ foo
+} {c:/foo}
+test filename-9.6 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join c:\\bar foo
+} {c:/bar/foo}
+test filename-9.7 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join /foo c:bar
+} {c:bar}
+test filename-9.8 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join ///host//share dir
+} {//host/share/dir}
+test filename-9.9 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join ~ foo
+} {~/foo}
+test filename-9.10 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join ~/~foo
+} {~/~foo}
+test filename-9.11 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join ~ ./~foo
+} {~/~foo}
+test filename-9.12 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join / ~foo
+} {~foo}
+test filename-9.13 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join ./a/ b c
+} {./a/b/c}
+test filename-9.14 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join ./~a/ b c
+} {./~a/b/c}
+test filename-9.15 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join // host share path
+} {/host/share/path}
+test filename-9.16 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join foo . bar
+} {foo/./bar}
+test filename-9.17 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join foo .. bar
+} {foo/../bar}
+test filename-9.18 {Tcl_JoinPath: win} {
+ testsetplatform win
+ file join foo/./bar
+} {foo/./bar}
+
+test filename-10.1 {Tcl_TranslateFileName} {
+ testsetplatform unix
+ list [catch {testtranslatefilename foo} msg] $msg
+} {0 foo}
+test filename-10.2 {Tcl_TranslateFileName} {
+ testsetplatform windows
+ list [catch {testtranslatefilename {c:/foo}} msg] $msg
+} {0 {c:\foo}}
+test filename-10.3 {Tcl_TranslateFileName} {
+ testsetplatform windows
+ list [catch {testtranslatefilename {c:/\\foo/}} msg] $msg
+} {0 {c:\foo}}
+test filename-10.4 {Tcl_TranslateFileName} {
+ testsetplatform mac
+ list [catch {testtranslatefilename foo} msg] $msg
+} {0 :foo}
+test filename-10.5 {Tcl_TranslateFileName} {
+ testsetplatform mac
+ list [catch {testtranslatefilename :~foo} msg] $msg
+} {0 :~foo}
+test filename-10.6 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 /home/test/foo}
+test filename-10.7 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ unset env(HOME)
+ testsetplatform unix
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {1 {couldn't find HOME environment variable to expand path}}
+test filename-10.8 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test"
+ testsetplatform unix
+ set result [list [catch {testtranslatefilename ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 /home/test}
+test filename-10.9 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test/"
+ testsetplatform unix
+ set result [list [catch {testtranslatefilename ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 /home/test}
+test filename-10.10 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "/home/test/"
+ testsetplatform unix
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 /home/test/foo}
+test filename-10.11 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "Root:"
+ testsetplatform mac
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 Root:foo}
+test filename-10.12 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "Root:home"
+ testsetplatform mac
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 Root:home:foo}
+test filename-10.13 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "Root:home"
+ testsetplatform mac
+ set result [list [catch {testtranslatefilename ~::foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 Root:home::foo}
+test filename-10.14 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "Root:home"
+ testsetplatform mac
+ set result [list [catch {testtranslatefilename ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 Root:home}
+test filename-10.15 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "Root:home:"
+ testsetplatform mac
+ set result [list [catch {testtranslatefilename ~::foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 Root:home::foo}
+test filename-10.16 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "Root:home::"
+ testsetplatform mac
+ set result [list [catch {testtranslatefilename ~::foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 Root:home:::foo}
+test filename-10.17 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "\\home\\"
+ testsetplatform windows
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 {\home\foo}}
+test filename-10.18 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "\\home\\"
+ testsetplatform windows
+ set result [list [catch {testtranslatefilename ~/foo\\bar} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 {\home\foo\bar}}
+test filename-10.19 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "c:"
+ testsetplatform windows
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 c:foo}
+test filename-10.20 {Tcl_TranslateFileName} {
+ list [catch {testtranslatefilename ~blorp/foo} msg] $msg
+} {1 {user "blorp" doesn't exist}}
+test filename-10.21 {Tcl_TranslateFileName} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) "c:\\"
+ testsetplatform windows
+ set result [list [catch {testtranslatefilename ~/foo} msg] $msg]
+ set env(HOME) $temp
+ set result
+} {0 {c:\foo}}
+test filename-10.22 {Tcl_TranslateFileName} {
+ testsetplatform windows
+ list [catch {testtranslatefilename foo//bar} msg] $msg
+} {0 {foo\bar}}
+
+testsetplatform $platform
+
+test filename-10.23 {Tcl_TranslateFileName} {nonPortable unixOnly} {
+ # this test fails if ~ouster is not /home/ouster
+ list [catch {testtranslatefilename ~ouster} msg] $msg
+} {0 /home/ouster}
+test filename-10.24 {Tcl_TranslateFileName} {nonPortable unixOnly} {
+ # this test fails if ~ouster is not /home/ouster
+ list [catch {testtranslatefilename ~ouster/foo} msg] $msg
+} {0 /home/ouster/foo}
+
+
+test filename-11.1 {Tcl_GlobCmd} {
+ list [catch {glob} msg] $msg
+} {1 {wrong # args: should be "glob ?switches? name ?name ...?"}}
+test filename-11.2 {Tcl_GlobCmd} {
+ list [catch {glob -gorp} msg] $msg
+} {1 {bad switch "-gorp": must be -nocomplain or --}}
+test filename-11.3 {Tcl_GlobCmd} {
+ list [catch {glob -nocomplai} msg] $msg
+} {1 {bad switch "-nocomplai": must be -nocomplain or --}}
+test filename-11.4 {Tcl_GlobCmd} {
+ list [catch {glob -nocomplain} msg] $msg
+} {1 {wrong # args: should be "glob ?switches? name ?name ...?"}}
+test filename-11.5 {Tcl_GlobCmd} {
+ list [catch {glob -nocomplain ~xyqrszzz} msg] $msg
+} {0 {}}
+test filename-11.6 {Tcl_GlobCmd} {
+ list [catch {glob ~xyqrszzz} msg] $msg
+} {1 {user "xyqrszzz" doesn't exist}}
+test filename-11.7 {Tcl_GlobCmd} {
+ list [catch {glob -- -nocomplain} msg] $msg
+} {1 {no files matched glob patterns "-nocomplain"}}
+test filename-11.8 {Tcl_GlobCmd} {
+ list [catch {glob -nocomplain -- -nocomplain} msg] $msg
+} {0 {}}
+test filename-11.9 {Tcl_GlobCmd} {
+ testsetplatform unix
+ list [catch {glob ~\\xyqrszzz/bar} msg] $msg
+} {1 {globbing characters not supported in user names}}
+test filename-11.10 {Tcl_GlobCmd} {
+ testsetplatform unix
+ list [catch {glob -nocomplain ~\\xyqrszzz/bar} msg] $msg
+} {0 {}}
+test filename-11.11 {Tcl_GlobCmd} {
+ testsetplatform unix
+ list [catch {glob ~xyqrszzz\\/\\bar} msg] $msg
+} {1 {user "xyqrszzz" doesn't exist}}
+test filename-11.12 {Tcl_GlobCmd} {
+ testsetplatform unix
+ set home $env(HOME)
+ unset env(HOME)
+ set x [list [catch {glob ~/*} msg] $msg]
+ set env(HOME) $home
+ set x
+} {1 {couldn't find HOME environment variable to expand path}}
+
+testsetplatform $platform
+
+test filename-11.13 {Tcl_GlobCmd} {
+ list [catch {glob ~} msg] $msg
+} [list 0 [list $env(HOME)]]
+
+# The following tests will work on Windows platforms only if MKS
+# toolkit is installed.
+
+catch {
+ set oldhome $env(HOME)
+ set env(HOME) [pwd]
+ removeDirectory globTest
+ makeDirectory globTest
+ makeDirectory globTest/a1
+ makeDirectory globTest/a2
+ makeDirectory globTest/a3
+ makeDirectory globTest/a1/b1
+ makeDirectory globTest/a1/b2
+ makeDirectory globTest/a2/b3
+ close [open globTest/x1.c w]
+ close [open globTest/y1.c w]
+ close [open globTest/z1.c w]
+ close [open globTest/x,z1.c w]
+ close [open "globTest/weird name.c" w]
+ close [open globTest/.1 w]
+ close [open globTest/a1/b1/x2.c w]
+ close [open globTest/a1/b2/y2.c w]
+}
+
+test filename-11.14 {Tcl_GlobCmd} {unixExecs} {
+ list [catch {glob ~/globTest} msg] $msg
+} [list 0 [list [file join $env(HOME) globTest]]]
+test filename-11.15 {Tcl_GlobCmd} {unixExecs} {
+ list [catch {glob ~\\/globTest} msg] $msg
+} [list 0 [list [file join $env(HOME) globTest]]]
+test filename-11.16 {Tcl_GlobCmd} {unixExecs} {
+ list [catch {glob globTest} msg] $msg
+} {0 globTest}
+
+test filename-12.1 {simple globbing} {unixOrPc} {
+ list [catch {glob {}} msg] $msg
+} {0 .}
+test filename-12.2 {simple globbing} {macOnly} {
+ list [catch {glob {}} msg] $msg
+} {0 :}
+test filename-12.3 {simple globbing} {
+ list [catch {glob -nocomplain \{a1,a2\}} msg] $msg
+} {0 {}}
+
+if {$tcl_platform(platform) == "macintosh"} {
+ set globPreResult :globTest:
+} else {
+ 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} {unixExecs} {
+ list [catch {glob globTest\\/x1.c} msg] $msg
+} "0 $globPreResult$x1"
+test filename-12.6 {simple globbing} {unixExecs} {
+ list [catch {glob globTest\\/\\x1.c} msg] $msg
+} "0 $globPreResult$x1"
+
+test filename-13.1 {globbing with brace substitution} {unixExecs} {
+ list [catch {glob globTest/\{\}} msg] $msg
+} "0 $globPreResult"
+test filename-13.2 {globbing with brace substitution} {
+ list [catch {glob globTest/\{} msg] $msg
+} {1 {unmatched open-brace in file name}}
+test filename-13.3 {globbing with brace substitution} {
+ list [catch {glob globTest/\{\\\}} msg] $msg
+} {1 {unmatched open-brace in file name}}
+test filename-13.4 {globbing with brace substitution} {
+ list [catch {glob globTest/\{\\} msg] $msg
+} {1 {unmatched open-brace in file name}}
+test filename-13.5 {globbing with brace substitution} {
+ list [catch {glob globTest/\}} msg] $msg
+} {1 {unmatched close-brace in file name}}
+test filename-13.6 {globbing with brace substitution} {unixExecs} {
+ list [catch {glob globTest/\{\}x1.c} msg] $msg
+} "0 $globPreResult$x1"
+test filename-13.7 {globbing with brace substitution} {unixExecs} {
+ list [catch {glob globTest/\{x\}1.c} msg] $msg
+} "0 $globPreResult$x1"
+test filename-13.8 {globbing with brace substitution} {unixExecs} {
+ list [catch {glob globTest/\{x\{\}\}1.c} msg] $msg
+} "0 $globPreResult$x1"
+test filename-13.9 {globbing with brace substitution} {unixExecs} {
+ list [lsort [catch {glob globTest/\{x,y\}1.c} msg]] $msg
+} [list 0 [list $globPreResult$x1 $globPreResult$y1]]
+test filename-13.10 {globbing with brace substitution} {unixExecs} {
+ list [lsort [catch {glob globTest/\{x,,y\}1.c} msg]] $msg
+} [list 0 [list $globPreResult$x1 $globPreResult$y1]]
+test filename-13.11 {globbing with brace substitution} {unixOrPc unixExecs} {
+ list [lsort [catch {glob globTest/\{x,x\\,z,z\}1.c} msg]] $msg
+} {0 {globTest/x1.c globTest/x,z1.c globTest/z1.c}}
+test filename-13.11 {globbing with brace substitution} {macOnly} {
+ list [lsort [catch {glob globTest/\{x,x\\,z,z\}1.c} msg]] $msg
+} {0 {:globTest:x1.c :globTest:x,z1.c :globTest:z1.c}}
+test filename-13.12 {globbing with brace substitution} {unixExecs} {
+ lsort [glob globTest/{a,b,x,y}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.13 {globbing with brace substitution} {unixOrPc unixExecs} {
+ lsort [glob {globTest/{x1,y2,weird name}.c}]
+} {{globTest/weird name.c} globTest/x1.c}
+test filename-13.13 {globbing with brace substitution} {macOnly} {
+ lsort [glob {globTest/{x1,y2,weird name}.c}]
+} {{:globTest:weird name.c} :globTest:x1.c}
+test filename-13.14 {globbing with brace substitution} {unixOrPc unixExecs} {
+ lsort [glob globTest/{x1.c,a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.14 {globbing with brace substitution} {macOnly} {
+ lsort [glob globTest/{x1.c,a1/*}]
+} {:globTest:a1:b1 :globTest:a1:b2 :globTest:x1.c}
+test filename-13.15 {globbing with brace substitution} {unixOrPc unixExecs} {
+ lsort [glob globTest/{x1.c,{a},a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.15 {globbing with brace substitution} {macOnly} {
+ lsort [glob globTest/{x1.c,{a},a1/*}]
+} {:globTest:a1:b1 :globTest:a1:b2 :globTest:x1.c}
+test filename-13.16 {globbing with brace substitution} {unixOrPc unixExecs} {
+ lsort [glob globTest/{a,x}1/*/{x,y}*]
+} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-13.16 {globbing with brace substitution} {macOnly} {
+ lsort [glob globTest/{a,x}1/*/{x,y}*]
+} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
+test filename-13.17 {globbing with brace substitution} {unixExecs} {
+ list [catch {glob globTest/\{a,x\}1/*/\{} msg] $msg
+} {1 {unmatched open-brace in file name}}
+
+test filename-14.1 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob g*/*.c]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.1 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob g*/*.c]
+} {{:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}
+test filename-14.2 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob globTest/?1.c]
+} {globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.2 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob globTest/?1.c]
+} {:globTest:x1.c :globTest:y1.c :globTest:z1.c}
+test filename-14.3 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob */*/*/*.c]
+} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-14.3 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob */*/*/*.c]
+} {:globTest:a1:b1:x2.c :globTest:a1:b2:y2.c}
+test filename-14.4 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ 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.4 {asterisks, question marks, and brackets} {macOnly} {
+ 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.5 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob globTest/.*]
+} {globTest/. globTest/.. globTest/.1}
+test filename-14.5 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob globTest/.*]
+} {:globTest:.1}
+test filename-14.6 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob globTest/*/*]
+} {globTest/a1/b1 globTest/a1/b2 globTest/a2/b3}
+test filename-14.6 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob globTest/*/*]
+} {:globTest:a1:b1 :globTest:a1:b2 :globTest:a2:b3}
+test filename-14.7 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob {globTest/[xyab]1.*}]
+} {globTest/x1.c globTest/y1.c}
+test filename-14.7 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob {globTest/[xyab]1.*}]
+} {:globTest:x1.c :globTest:y1.c}
+test filename-14.8 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ lsort [glob globTest/*/]
+} {globTest/a1/ globTest/a2/ globTest/a3/}
+test filename-14.8 {asterisks, question marks, and brackets} {macOnly} {
+ lsort [glob globTest/*/]
+} {:globTest:a1: :globTest:a2: :globTest:a3:}
+test filename-14.9 {asterisks, question marks, and brackets} {unixExecs} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) [file join $env(HOME) globTest]
+ set result [list [catch {glob ~/z*} msg] $msg]
+ set env(HOME) $temp
+ set result
+} [list 0 [list [file join $env(HOME) globTest z1.c]]]
+test filename-14.10 {asterisks, question marks, and brackets} {unixExecs unixOrPc} {
+ list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
+} {0 {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}}
+test filename-14.10 {asterisks, question marks, and brackets} {macOnly} {
+ list [catch {lsort [glob globTest/*.c goo/*]} msg] $msg
+} {0 {{:globTest:weird name.c} :globTest:x,z1.c :globTest:x1.c :globTest:y1.c :globTest:z1.c}}
+test filename-14.11 {asterisks, question marks, and brackets} {
+ list [catch {glob -nocomplain goo/*} msg] $msg
+} {0 {}}
+test filename-14.12 {asterisks, question marks, and brackets} {
+ list [catch {glob globTest/*/gorp} msg] $msg
+} {1 {no files matched glob pattern "globTest/*/gorp"}}
+test filename-14.13 {asterisks, question marks, and brackets} {
+ list [catch {glob goo/* x*z foo?q} msg] $msg
+} {1 {no files matched glob patterns "goo/* x*z foo?q"}}
+test filename-14.14 {slash globbing} {unixOrPc} {
+ glob /
+} /
+test filename-14.15 {slash globbing} {pcOnly} {
+ glob {\\}
+} /
+
+# The following tests are only valid for Unix systems.
+
+if {$tcl_platform(platform) == "unix"} {
+ # On some systems, like AFS, "000" protection doesn't prevent
+ # access by owner, so the following test is not portable.
+
+ exec chmod 000 globTest
+ test filename-15.1 {unix specific globbing} {nonPortable} {
+ string tolower [list [catch {glob globTest/*} msg] $msg $errorCode]
+ } {1 {couldn't read directory "globtest": permission denied} {posix eacces {permission denied}}}
+ exec chmod 755 globTest
+
+ test filename-15.2 {unix specific globbing} {nonPortable} {
+ glob ~ouster/.csh*
+ } "/home/ouster/.cshrc"
+ close [open globTest/odd\\\[\]*?\{\}name w]
+ test filename-15.3 {unix specific globbing} {
+ global env
+ set temp $env(HOME)
+ set env(HOME) $env(HOME)/globTest/odd\\\[\]*?\{\}name
+ set result [list [catch {glob ~} msg] $msg]
+ set env(HOME) $temp
+ set result
+ } [list 0 [list [glob ~]/globTest/odd\\\[\]*?\{\}name]]
+ exec rm -f globTest/odd\\\[\]*?\{\}name
+}
+
+# The following tests are only valid for Windows systems.
+
+if {$tcl_platform(platform) == "windows"} {
+ set temp [pwd]
+ cd c:/
+ exec rm -rf globTest
+ catch {
+ exec mkdir globTest
+ close [open globTest/x1.BAT w]
+ close [open globTest/y1.Bat w]
+ close [open globTest/z1.bat w]
+ }
+
+ test filename-16.1 {windows specific globbing} {unixExecs} {
+ lsort [glob globTest/*.bat]
+ } {globTest/x1.BAT globTest/y1.Bat globTest/z1.bat}
+ test filename-16.2 {windows specific globbing} {
+ glob c:
+ } c:
+ test filename-16.3 {windows specific globbing} {unixExecs} {
+ glob c:\\\\
+ } c:/
+ test filename-16.4 {windows specific globbing} {
+ glob c:/
+ } c:/
+ test filename-16.5 {windows specific globbing} {unixExecs} {
+ glob c:*Test
+ } c:globTest
+ test filename-16.6 {windows specific globbing} {unixExecs} {
+ glob c:\\\\*Test
+ } c:/globTest
+ test filename-16.7 {windows specific globbing} {unixExecs} {
+ glob c:/*Test
+ } c:/globTest
+ test filename-16.8 {windows specific globbing} {unixExecs} {
+ lsort [glob c:globTest/*.bat]
+ } {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+ test filename-16.9 {windows specific globbing} {unixExecs} {
+ lsort [glob c:/globTest/*.bat]
+ } {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+ test filename-16.10 {windows specific globbing} {unixExecs} {
+ lsort [glob c:globTest\\\\*.bat]
+ } {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+ test filename-16.11 {windows specific globbing} {unixExecs} {
+ lsort [glob c:\\\\globTest\\\\*.bat]
+ } {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+
+ exec rm -rf globTest
+
+ if $testConfig(nonPortable) {
+ cd //gaspode/d
+ exec rm -rf globTest
+ exec mkdir globTest
+
+ close [open globTest/x1.BAT w]
+ close [open globTest/y1.Bat w]
+ close [open globTest/z1.bat w]
+
+ test filename-16.12 {windows specific globbing} {
+ glob //gaspode/d/*Test
+ } //gaspode/d/globTest
+ test filename-16.13 {windows specific globbing} {
+ glob {\\\\gaspode\\d\\*Test}
+ } //gaspode/d/globTest
+
+ exec rm -rf globTest
+ }
+
+ cd $temp
+}
+
+removeDirectory globTest
+set env(HOME) $oldhome
+
+testsetplatform $platform
+catch {unset oldhome platform temp result}
+concat ""
diff --git a/contrib/tcl/tests/for.test b/contrib/tcl/tests/for.test
new file mode 100644
index 0000000..16d8c9c
--- /dev/null
+++ b/contrib/tcl/tests/for.test
@@ -0,0 +1,211 @@
+# Commands covered: foreach, 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) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) for.test 1.11 96/02/16 08:55:55
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# Basic "foreach" operation.
+
+test for-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 for-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 for-1.3 {basic foreach tests} {catch {foreach} msg} 1
+test for-1.4 {basic foreach tests} {
+ catch {foreach} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test for-1.5 {basic foreach tests} {catch {foreach i} msg} 1
+test for-1.6 {basic foreach tests} {
+ catch {foreach i} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test for-1.7 {basic foreach tests} {catch {foreach i j} msg} 1
+test for-1.8 {basic foreach tests} {
+ catch {foreach i j} msg
+ set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test for-1.9 {basic foreach tests} {catch {foreach i j k l} msg} 1
+test for-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 for-1.11 {basic foreach tests} {
+ set a {}
+ foreach i {} {
+ set a [concat $a $i]
+ }
+ set a
+} {}
+test for-1.11 {foreach errors} {
+ list [catch {foreach {{a}{b}} {1 2 3} {}} msg] $msg
+} {1 {list element in braces followed by "{b}" instead of space}}
+test for-1.12 {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 for-1.13 {foreach errors} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {foreach a {1 2 3} {}} msg] $msg
+} {1 {couldn't set loop variable: "a"}}
+catch {unset a}
+test for-1.14 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {1 2 3 4} {
+ append x $b $a
+ }
+ set x
+} {2143}
+test for-1.15 {parallel foreach tests} {
+ set x {}
+ foreach {a b} {1 2 3 4 5} {
+ append x $b $a
+ }
+ set x
+} {21435}
+test for-1.16 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {4 5 6} {
+ append x $b $a
+ }
+ set x
+} {415263}
+test for-1.17 {parallel foreach tests} {
+ set x {}
+ foreach a {1 2 3} b {4 5 6 7 8} {
+ append x $b $a
+ }
+ set x
+} {41526378}
+test for-1.18 {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 for-1.19 {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 for-1.20 {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}
+
+# Check "continue".
+
+test for-2.1 {continue tests} {catch continue} 4
+test for-2.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 for-2.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 for-2.4 {continue tests} {catch {continue foo} msg} 1
+test for-2.5 {continue tests} {
+ catch {continue foo} msg
+ set msg
+} {wrong # args: should be "continue"}
+
+# Check "break".
+
+test for-3.1 {break tests} {catch break} 3
+test for-3.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 for-3.3 {break tests} {catch {break foo} msg} 1
+test for-3.4 {break tests} {
+ catch {break foo} msg
+ set msg
+} {wrong # args: should be "break"}
+
+# Check "for" and its use of continue and break.
+
+test for-4.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-4.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-4.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-4.4 {for tests} {catch {for 1 2 3} msg} 1
+test for-4.5 {for tests} {
+ catch {for 1 2 3} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-4.6 {for tests} {catch {for 1 2 3 4 5} msg} 1
+test for-4.7 {for tests} {
+ catch {for 1 2 3 4 5} msg
+ set msg
+} {wrong # args: should be "for start test next command"}
+test for-4.8 {for tests} {
+ set a {xyz}
+ for {set i 1} {$i<6} {set i [expr $i+1]} {}
+ set a
+} xyz
+test for-4.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}
diff --git a/contrib/tcl/tests/format.test b/contrib/tcl/tests/format.test
new file mode 100644
index 0000000..3fe4eb5
--- /dev/null
+++ b/contrib/tcl/tests/format.test
@@ -0,0 +1,366 @@
+# 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 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) format.test 1.22 96/02/16 08:55:56
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# The following code is needed because some versions of SCO Unix have
+# a round-off error in sprintf which would cause some of the tests to
+# fail. Someday I hope this code shouldn't be necessary (code added
+# 9/9/91).
+
+set roundOffBug 0
+if {"[format %7.1e 68.514]" == "6.8e+01"} {
+ puts stdout "Note: this system has a sprintf round-off bug, some tests skipped\n"
+ set roundOffBug 1
+}
+
+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} {nonPortable} {
+ format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12
+} { 6 34 16923 -12 -1 0xe 0XC}
+
+# %u output depends on word length, so this test is not portable.
+
+test format-1.3 {integer formatting} {nonPortable} {
+ format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} { 6 34 16923 4294967284 -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} {nonPortable} {
+ format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} { 6 22 421b fffffff4}
+test format-1.8 {integer formatting} {nonPortable} {
+ format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffff4}
+test format-1.9 {integer formatting} {nonPortable} {
+ format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} { 0x6 0x22 0x421b 0xfffffff4}
+test format-1.10 {integer formatting} {nonPortable} {
+ format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6 0x22 0x421b 0xfffffff4 }
+test format-1.11 {integer formatting} {nonPortable} {
+ format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06 042 041033 037777777764 }
+
+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-3.1 {e and f formats} {
+ 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-3.2 {e and f formats} {
+ format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
+} { 3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
+if {!$roundOffBug} {
+ test format-3.3 {e and f formats} {
+ 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-3.4 {e and f formats} {
+ 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-3.5 {e and f formats} {
+ 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-3.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-3.7 {e and f formats} {nonPortable} {
+ 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-3.8 {e and f formats} {
+ format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
+} {-1.0000e+01 -9.99996e+00 9.999960e+00}
+test format-3.9 {e and f formats} {
+ format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-3.10 {e and f formats} {
+ format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
+} { -9.999960 -9.999960 0000000000009.999960}
+test format-3.11 {e and f formats} {
+ format "%-020f %020f" -9.99996 -9.99996 9.99996
+} {-9.999960 -000000000009.999960}
+test format-3.12 {e and f formats} {
+ format "%.0e %#.0e" -9.99996 -9.99996 9.99996
+} {-1e+01 -1.e+01}
+test format-3.13 {e and f formats} {
+ format "%.0f %#.0f" -9.99996 -9.99996 9.99996
+} {-10 -10.}
+test format-3.14 {e and f formats} {
+ format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-3.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-3.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-4.1 {g-format} {
+ format "%.3g" 12341.0
+} {1.23e+04}
+test format-4.2 {g-format} {
+ format "%.3G" 1234.12345
+} {1.23E+03}
+test format-4.3 {g-format} {
+ format "%.3g" 123.412345
+} {123}
+test format-4.4 {g-format} {
+ format "%.3g" 12.3412345
+} {12.3}
+test format-4.5 {g-format} {
+ format "%.3g" 1.23412345
+} {1.23}
+test format-4.6 {g-format} {
+ format "%.3g" 1.23412345
+} {1.23}
+test format-4.7 {g-format} {
+ format "%.3g" .123412345
+} {0.123}
+test format-4.8 {g-format} {
+ format "%.3g" .012341
+} {0.0123}
+test format-4.9 {g-format} {
+ format "%.3g" .0012341
+} {0.00123}
+test format-4.10 {g-format} {
+ format "%.3g" .00012341
+} {0.000123}
+test format-4.11 {g-format} {
+ format "%.3g" .00001234
+} {1.23e-05}
+test format-4.12 {g-format} {
+ format "%.4g" 9999.6
+} {1e+04}
+test format-4.13 {g-format} {
+ format "%.4g" 999.96
+} {1000}
+test format-4.14 {g-format} {
+ format "%.3g" 1.0
+} {1}
+test format-4.15 {g-format} {
+ format "%.3g" .1
+} {0.1}
+test format-4.16 {g-format} {
+ format "%.3g" .01
+} {0.01}
+test format-4.17 {g-format} {
+ format "%.3g" .001
+} {0.001}
+test format-4.19 {g-format} {
+ format "%.3g" .00001
+} {1e-05}
+test format-4.20 {g-format} {
+ format "%#.3g" 1234.0
+} {1.23e+03}
+test format-4.21 {g-format} {
+ format "%#.3G" 9999.5
+} {1.00E+04}
+
+test format-5.1 {floating-point zeroes} {
+ format "%e %f %g" 0.0 0.0 0.0 0.0
+} {0.000000e+00 0.000000 0}
+test format-5.2 {floating-point zeroes} {
+ format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0}
+test format-5.3 {floating-point zeroes} {
+ format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0.000}
+test format-5.4 {floating-point zeroes} {
+ format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
+} {0e+00 0 0}
+test format-5.5 {floating-point zeroes} {
+ format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
+} {0.e+00 0. 0.}
+test format-5.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-5.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-5.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-6.1 {various syntax features} {
+ format "%*.*f" 12 3 12.345678901
+} { 12.346}
+test format-6.2 {various syntax features} {
+ format "%0*.*f" 12 3 12.345678901
+} {00000012.346}
+test format-6.3 {various syntax features} {
+ format "\*\t\\n"
+} {* \n}
+
+test format-7.1 {error conditions} {
+ catch format
+} 1
+test format-7.2 {error conditions} {
+ catch format msg
+ set msg
+} {wrong # args: should be "format formatString ?arg arg ...?"}
+test format-7.3 {error conditions} {
+ catch {format %*d}
+} 1
+test format-7.4 {error conditions} {
+ catch {format %*d} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-7.5 {error conditions} {
+ catch {format %*.*f 12}
+} 1
+test format-7.6 {error conditions} {
+ catch {format %*.*f 12} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-7.7 {error conditions} {
+ catch {format %*.*f 12 3}
+} 1
+test format-7.8 {error conditions} {
+ catch {format %*.*f 12 3} msg
+ set msg
+} {not enough arguments for all format specifiers}
+test format-7.9 {error conditions} {
+ list [catch {format %*d x 3} msg] $msg
+} {1 {expected integer but got "x"}}
+test format-7.10 {error conditions} {
+ list [catch {format %*.*f 2 xyz 3} msg] $msg
+} {1 {expected integer but got "xyz"}}
+test format-7.11 {error conditions} {
+ catch {format %d 2a}
+} 1
+test format-7.12 {error conditions} {
+ catch {format %d 2a} msg
+ set msg
+} {expected integer but got "2a"}
+test format-7.13 {error conditions} {
+ catch {format %c 2x}
+} 1
+test format-7.14 {error conditions} {
+ catch {format %c 2x} msg
+ set msg
+} {expected integer but got "2x"}
+test format-7.15 {error conditions} {
+ catch {format %f 2.1z}
+} 1
+test format-7.16 {error conditions} {
+ catch {format %f 2.1z} msg
+ set msg
+} {expected floating-point number but got "2.1z"}
+test format-7.17 {error conditions} {
+ catch {format ab%}
+} 1
+test format-7.18 {error conditions} {
+ catch {format ab% 12} msg
+ set msg
+} {format string ended in middle of field specifier}
+test format-7.19 {error conditions} {
+ catch {format %q x}
+} 1
+test format-7.20 {error conditions} {
+ catch {format %q x} msg
+ set msg
+} {bad field specifier "q"}
+test format-7.21 {error conditions} {
+ catch {format %d}
+} 1
+test format-7.22 {error conditions} {
+ catch {format %d} msg
+ set msg
+} {not enough arguments for all format specifiers}
+
+test format-8.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 %s} $a $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 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-9.1 {"h" format specifier} {nonPortable} {
+ format %hd 0xffff
+} -1
+test format-9.2 {"h" format specifier} {nonPortable} {
+ format %hx 0x10fff
+} fff
+test format-9.3 {"h" format specifier} {nonPortable} {
+ format %hd 0x10000
+} 0
+
+test format-10.1 {XPG3 %$n specifiers} {
+ format {%2$d %1$d} 4 5
+} {5 4}
+test format-10.2 {XPG3 %$n specifiers} {
+ format {%2$d %1$d %1$d %3$d} 4 5 6
+} {5 4 4 6}
+test format-10.3 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %3$d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-10.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-10.5 {XPG3 %$n specifiers} {
+ list [catch {format {%d %1$d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-10.6 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-10.7 {XPG3 %$n specifiers} {
+ list [catch {format {%2$d %3d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-10.8 {XPG3 %$n specifiers} {
+ format {%2$*d %3$d} 1 10 4
+} { 4 4}
+test format-10.9 {XPG3 %$n specifiers} {
+ format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
+} {abcde 44}
+test format-10.10 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-10.11 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-10.12 {XPG3 %$n specifiers} {
+ list [catch {format {%2$*d} 4 5 6} msg] $msg
+} {0 { 6}}
+
+test format-11.1 {enormous width specifiers} {
+ format "%077777777d" 77777777
+} {0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077777777}
+test format-11.2 {enormous width specifiers} {
+ format "%*d" 123456789 77777777
+} { 77777777}
+test format-11.3 {negative width specifiers} {
+ format "%*d" -47 25
+} {25}
diff --git a/contrib/tcl/tests/get.test b/contrib/tcl/tests/get.test
new file mode 100644
index 0000000..0713861
--- /dev/null
+++ b/contrib/tcl/tests/get.test
@@ -0,0 +1,72 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) get.test 1.5 96/04/09 15:54:33
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test get-1.1 {Tcl_GetInt procedure} {
+ set x 44
+ incr x { 22}
+} {66}
+test get-1.2 {Tcl_GetInt procedure} {
+ set x 44
+ incr x -3
+} {41}
+test get-1.3 {Tcl_GetInt procedure} {
+ set x 44
+ incr x +8
+} {52}
+test get-1.4 {Tcl_GetInt procedure} {
+ set x 44
+ list [catch {incr x foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test get-1.5 {Tcl_GetInt procedure} {
+ set x 44
+ list [catch {incr x {16 }} msg] $msg
+} {0 60}
+test get-1.6 {Tcl_GetInt procedure} {
+ set x 44
+ list [catch {incr x {16 x}} msg] $msg
+} {1 {expected integer but got "16 x"}}
+
+# The following tests are non-portable because they depend on
+# word size.
+
+test get-1.7 {Tcl_GetInt procedure} {nonPortable unixOnly} {
+ set x 44
+ list [catch {incr x 4294967296} 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} {nonPortable} {
+ set x 0
+ list [catch {incr x 4294967294} msg] $msg
+} {0 -2}
+test get-1.8 {Tcl_GetInt procedure} {nonPortable} {
+ set x 0
+ list [catch {incr x +4294967294} msg] $msg
+} {0 -2}
+test get-1.9 {Tcl_GetInt procedure} {nonPortable} {
+ set x 0
+ list [catch {incr x -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} {nonPortable} {
+ list [catch {format %g .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001} msg] $msg $errorCode
+} {1 {floating-point value too small to represent} {ARITH UNDERFLOW {floating-point value too small to represent}}}
diff --git a/contrib/tcl/tests/history.test b/contrib/tcl/tests/history.test
new file mode 100644
index 0000000..d5921b6
--- /dev/null
+++ b/contrib/tcl/tests/history.test
@@ -0,0 +1,386 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) history.test 1.11 96/02/16 08:55:57
+
+if {[info commands history] == ""} {
+ puts stdout "This version of Tcl was built without the history command;\n"
+ puts stdout "history tests will be skipped.\n"
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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}
+
+# "history event"
+
+test history-1.1 {event option} {history event -1} \
+ {set b [format {A test %s} string]}
+test history-1.2 {event option} {history event $num} \
+ {set a 12345}
+test history-1.3 {event option} {history event [expr $num+2]} \
+ {Another test}
+test history-1.4 {event option} {history event set} \
+ {set b [format {A test %s} string]}
+test history-1.5 {event option} {history e "* a*"} \
+ {set a 12345}
+test history-1.6 {event option} {catch {history event *gorp} msg} 1
+test history-1.7 {event option} {
+ catch {history event *gorp} msg
+ set msg
+} {no event matches "*gorp"}
+test history-1.8 {event option} {history event} \
+ {set b [format {A test %s} string]}
+test history-1.9 {event option} {catch {history event 123 456} msg} 1
+test history-1.10 {event option} {
+ catch {history event 123 456} msg
+ set msg
+} {wrong # args: should be "history event ?event?"}
+
+# "history redo"
+
+set a 0
+history redo -2
+test history-2.1 {redo option} {set a} 12345
+set b 0
+history redo
+test history-2.2 {redo option} {set b} {A test string}
+test history-2.3 {redo option} {catch {history redo -3 -4}} 1
+test history-2.4 {redo option} {
+ catch {history redo -3 -4} msg
+ set msg
+} {wrong # args: should be "history redo ?event?"}
+
+# "history add"
+
+history add "set a 444" exec
+test history-3.1 {add option} {set a} 444
+test history-3.2 {add option} {catch {history add "set a 444" execGorp}} 1
+test history-3.3 {add option} {
+ catch {history add "set a 444" execGorp} msg
+ set msg
+} {bad argument "execGorp": should be "exec"}
+test history-3.4 {add option} {catch {history add "set a 444" a} msg} 1
+test history-3.5 {add option} {
+ catch {history add "set a 444" a} msg
+ set msg
+} {bad argument "a": should be "exec"}
+history add "set a 555" e
+test history-3.6 {add option} {set a} 555
+history add "set a 666"
+test history-3.7 {add option} {set a} 555
+test history-3.8 {add option} {catch {history add "set a 666" e f} msg} 1
+test history-3.9 {add option} {
+ catch {history add "set a 666" e f} msg
+ set msg
+} {wrong # args: should be "history add event ?exec?"}
+
+# "history change"
+
+history change "A test value"
+test history-4.1 {change option} {history event [expr {[history n]-1}]} \
+ "A test value"
+history c "Another test" -1
+test history-4.2 {change option} {history e} "Another test"
+test history-4.3 {change option} {history event [expr {[history n]-1}]} \
+ "A test value"
+test history-4.4 {change option} {catch {history change Foo 4 10}} 1
+test history-4.5 {change option} {
+ catch {history change Foo 4 10} msg
+ set msg
+} {wrong # args: should be "history change newValue ?event?"}
+test history-4.6 {change option} {
+ catch {history change Foo [expr {[history n]-4}]}
+} 1
+test history-4.7 {change option} {
+ catch {history change Foo [expr {[history n]-4}]}
+ set msg
+} {wrong # args: should be "history change newValue ?event?"}
+
+# "history info"
+
+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 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 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} {catch {history i 2 3}} 1
+test history-5.4 {info option} {
+ catch {history i 2 3} msg
+ set msg
+} {wrong # args: should be "history info ?count?"}
+test history-5.5 {info option} {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"
+
+history add "foo1"
+history add "foo2"
+history add "foo3"
+history keep 2
+test history-6.1 {keep option} {history event [expr [history n]-1]} foo3
+test history-6.2 {keep option} {history event -1} foo2
+test history-6.3 {keep option} {catch {history event -3}} 1
+test history-6.4 {keep option} {
+ catch {history event -3} msg
+ set msg
+} {event "-3" is too far in the past}
+history k 5
+test history-6.5 {keep option} {history event -1} foo2
+test history-6.6 {keep option} {history event -2} {}
+test history-6.7 {keep option} {history event -3} {}
+test history-6.8 {keep option} {history event -4} {}
+test history-6.9 {keep option} {catch {history event -5}} 1
+test history-6.10 {keep option} {catch {history keep 4 6}} 1
+test history-6.11 {keep option} {
+ catch {history keep 4 6} msg
+ set msg
+} {wrong # args: should be "history keep number"}
+test history-6.12 {keep option} {catch {history keep}} 1
+test history-6.13 {keep option} {
+ catch {history keep} msg
+ set msg
+} {wrong # args: should be "history keep number"}
+test history-6.14 {keep option} {catch {history keep -3}} 1
+test history-6.15 {keep option} {
+ catch {history keep -3} msg
+ set msg
+} {illegal keep count "-3"}
+
+# "history nextid"
+
+set num [history n]
+history add "Testing"
+history add "Testing2"
+test history-7.1 {nextid option} {history event} "Testing"
+test history-7.2 {nextid option} {history next} [expr $num+2]
+test history-7.3 {nextid option} {catch {history nextid garbage}} 1
+test history-7.4 {nextid option} {
+ catch {history nextid garbage} msg
+ set msg
+} {wrong # args: should be "history nextid"}
+
+# "history substitute"
+
+test history-8.1 {substitute option} {
+ history add "set a {test foo test b c test}"
+ history add "Test command 2"
+ set a 0
+ history substitute foo bar -1
+ set a
+} {test bar test b c test}
+test history-8.2 {substitute option} {
+ history add "set a {test foo test b c test}"
+ history add "Test command 2"
+ set a 0
+ history substitute test gorp
+ set a
+} {gorp foo gorp b c gorp}
+test history-8.3 {substitute option} {
+ history add "set a {test foo test b c test}"
+ history add "Test command 2"
+ set a 0
+ history sub " te" to
+ set a
+} {test footost b ctost}
+test history-8.4 {substitute option} {catch {history sub xxx yyy}} 1
+test history-8.5 {substitute option} {
+ catch {history sub xxx yyy} msg
+ set msg
+} {"xxx" doesn't appear in event}
+test history-8.6 {substitute option} {catch {history s a b -10}} 1
+test history-8.7 {substitute option} {
+ catch {history s a b -10} msg
+ set msg
+} {event "-10" is too far in the past}
+test history-8.8 {substitute option} {catch {history s a b -1 20}} 1
+test history-8.9 {substitute option} {
+ catch {history s a b -1 20} msg
+ set msg
+} {wrong # args: should be "history substitute old new ?event?"}
+
+# "history words"
+
+test history-9.1 {words option} {
+ history add {word0 word1 word2 a b c word6}
+ history add foo
+ history words 0-$
+} {word0 word1 word2 a b c word6}
+test history-9.2 {words option} {
+ history add {word0 word1 word2 a b c word6}
+ history add foo
+ history w 2 -1
+} word2
+test history-9.3 {words option} {
+ history add {word0 word1 word2 a b c word6}
+ history add foo
+ history wo $
+} word6
+test history-9.4 {words option} {catch {history w 1--1} msg} 1
+test history-9.5 {words option} {
+ catch {history w 1--1} msg
+ set msg
+} {bad word selector "1--1": should be num-num or pattern}
+test history-9.6 {words option} {
+ history add {word0 word1 word2 a b c word6}
+ history add foo
+ history w w
+} {}
+test history-9.7 {words option} {
+ history add {word0 word1 word2 a b c word6}
+ history add foo
+ history w *2
+} word2
+test history-9.8 {words option} {
+ history add {word0 word1 word2 a b c word6}
+ history add foo
+ history w *or*
+} {word0 word1 word2 word6}
+test history-9.9 {words option} {catch {history words 10}} 1
+test history-9.10 {words option} {
+ catch {history words 10} msg
+ set msg
+} {word selector "10" specified non-existent words}
+test history-9.11 {words option} {catch {history words 1 -1 20}} 1
+test history-9.12 {words option} {
+ catch {history words 1 -1 20} msg
+ set msg
+} {wrong # args: should be "history words num-num/pat ?event?"}
+
+# history revision
+
+test history-10.1 {history revision} {
+ set a 0
+ history a {set a 12345}
+ history a {set a [history e]} exec
+ set a
+} {set a 12345}
+test history-10.2 {history revision} {
+ set a 0
+ history a {set a 12345}
+ history a {set a [history e]} exec
+ history a foo
+ history ev -1
+} {set a {set a 12345}}
+test history-10.3 {history revision} {
+ set a 0
+ history a {set a 12345}
+ history a {set a [history e]} exec
+ history a foo
+ history a {history r -2} exec
+ history a {set a 12345}
+ history ev -1
+} {set a {set a 12345}}
+test history-10.4 {history revision} {
+ history a {set a 12345}
+ history a {history s 123 999} exec
+ history a foo
+ history ev -1
+} {set a 99945}
+test history-10.5 {history revision} {
+ history add {word0 word1 word2 a b c word6}
+ history add {set [history w 3] [list [history w 0] [history w {[ab]}]]} exec
+ set a
+} {word0 {a b}}
+test history-10.6 {history revision} {
+ history add {word0 word1 word2 a b c word6}
+ history add {set [history w 3] [list [history w 0] [history w {[ab]}]]} exec
+ history add foo
+ history ev
+} {set a [list word0 {a b}]}
+test history-10.7 {history revision} {
+ history add {word0 word1 word2 a b c word6}
+ history add {set [history w 3] [list [history w 0] [history w {[ab]}]]} exec
+ history add {format b}
+ history add {word0 word1 word2 a b c word6}
+ set a 0
+ history add {set [history subs b a -2] [list abc [history r -2] [history w 1-3]]} exec
+ history add foo
+ history ev
+} {set [format a] [list abc [format b] {word1 word2 a}]}
+test history-10.8 {history revision} {
+ history add {set a 12345}
+ concat a b c
+ history add {history redo; set b 44} exec
+ history add foo
+ history ev
+} {set a 12345; set b 44}
+test history-10.9 {history revision} {
+ history add {set a 12345}
+ history add {history redo; history change "A simple test"; history subs 45 xx} exec
+ set a
+} 123xx
+test history-10.10 {history revision} {
+ history add {set a 12345}
+ history add {history redo; history change "A simple test"; history subs 45 xx} exec
+ history add foo
+ history e
+} {A simple test}
+test history-10.11 {history revision} {
+ history add {word0 word1 $ a b c word6}
+ history add {set a [history w 4-[history word 2]]} exec
+ set a
+} {b c word6}
+test history-10.12 {history revision} {
+ history add {word0 word1 $ a b c word6}
+ history add {set a [history w 4-[history word 2]]} exec
+ history add foo
+ history e
+} {set a {b c word6}}
+test history-10.13 {history revision} {
+ history add {history word 0} exec
+ history add foo
+ history e
+} {history word 0}
+test history-10.14 {history revision} {
+ history add {set a [history word 0; format c]} exec
+ history add foo
+ history e
+} {set a [history word 0; format c]}
+test history-10.15 {history revision even when nested} {
+ proc x {a b} {history word $a $b}
+ history add {word1 word2 word3 word4}
+ history add {set a [x 1-3 -1]} exec
+ history add foo
+ history e
+} {set a {word2 word3 word4}}
+test history-10.16 {disable history revision in nested history evals} {
+ history add {word1 word2 word3 word4}
+ history add {set a [history words 0]; history add foo; set a [history words 0]} exec
+ history e
+} {set a word1; history add foo; set a [history words 0]}
+
+# miscellaneous
+
+test history-11.1 {miscellaneous} {catch {history gorp} msg} 1
+test history-11.2 {miscellaneous} {
+ catch {history gorp} msg
+ set msg
+} {bad option "gorp": must be add, change, event, info, keep, nextid, redo, substitute, or words}
diff --git a/contrib/tcl/tests/if.test b/contrib/tcl/tests/if.test
new file mode 100644
index 0000000..e5b9ed2
--- /dev/null
+++ b/contrib/tcl/tests/if.test
@@ -0,0 +1,148 @@
+# 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) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) if.test 1.8 96/02/16 08:55:59
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test if-1.1 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} else {set a 2}
+ set a
+} 2
+test if-1.2 {taking proper branch} {
+ set a {}
+ if 1 {set a 1} else {set a 2}
+ set a
+} 1
+test if-1.3 {taking proper branch} {
+ set a {}
+ if 1<2 {set a 1}
+ set a
+} 1
+test if-1.4 {taking proper branch} {
+ set a {}
+ if 1>2 {set a 1}
+ set a
+} {}
+test if-1.5 {taking proper branch} {
+ set a {}
+ if 0 {set a 1} else {}
+ set a
+} {}
+test if-1.5 {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-1.6 {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-1.7 {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-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-2.2 {optional then-else args} {
+ set a 44
+ if 1 then {set a 1} else {set a 2}
+ set a
+} 1
+test if-2.3 {optional then-else args} {
+ set a 44
+ if 0 {set a 1} else {set a 2}
+ set a
+} 2
+test if-2.4 {optional then-else args} {
+ set a 44
+ if 1 {set a 1} else {set a 2}
+ set a
+} 1
+test if-2.5 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} {set a 2}
+ set a
+} 2
+test if-2.6 {optional then-else args} {
+ set a 44
+ if 1 then {set a 1} {set a 2}
+ set a
+} 1
+test if-2.7 {optional then-else args} {
+ set a 44
+ if 0 then {set a 1} else {set a 2}
+ set a
+} 2
+test if-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-3.1 {return value} {
+ if 1 then {set a 22; concat abc}
+} abc
+test if-3.2 {return value} {
+ if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} def
+test if-3.3 {return value} {
+ if 0 then {set a 22; concat abc} else {concat def}
+} def
+test if-3.4 {return value} {
+ if 0 then {set a 22; concat abc}
+} {}
+test if-3.5 {return value} {
+ if 0 then {set a 22; concat abc} elseif 0 {concat def}
+} {}
+
+test if-4.1 {error conditions} {
+ list [catch {if} msg] $msg
+} {1 {wrong # args: no expression after "if" argument}}
+test if-4.2 {error conditions} {
+ list [catch {if {[error "error in condition"]}} msg] $msg
+} {1 {error in condition}}
+test if-4.3 {error conditions} {
+ list [catch {if 2} msg] $msg
+} {1 {wrong # args: no script following "2" argument}}
+test if-4.4 {error conditions} {
+ list [catch {if 2 then} msg] $msg
+} {1 {wrong # args: no script following "then" argument}}
+test if-4.5 {error conditions} {
+ list [catch {if 2 the} msg] $msg
+} {1 {invalid command name "the"}}
+test if-4.6 {error conditions} {
+ list [catch {if 2 then {[error "error in then clause"]}} msg] $msg
+} {1 {error in then clause}}
+test if-4.7 {error conditions} {
+ list [catch {if 0 then foo elseif} msg] $msg
+} {1 {wrong # args: no expression after "elseif" argument}}
+test if-4.8 {error conditions} {
+ list [catch {if 0 then foo elsei} msg] $msg
+} {1 {invalid command name "elsei"}}
+test if-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-4.10 {error conditions} {
+ list [catch {if 0 then foo elseif 0 bar els} msg] $msg
+} {1 {invalid command name "els"}}
+test if-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}}
diff --git a/contrib/tcl/tests/incr.test b/contrib/tcl/tests/incr.test
new file mode 100644
index 0000000..b9b7fba
--- /dev/null
+++ b/contrib/tcl/tests/incr.test
@@ -0,0 +1,88 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) incr.test 1.8 96/02/16 08:56:00
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+catch {unset x}
+
+test incr-1.1 {basic incr operation} {
+ set x 23
+ list [incr x] $x
+} {24 24}
+test incr-1.2 {basic incr operation} {
+ set x 106
+ list [incr x -5] $x
+} {101 101}
+test incr-1.3 {basic incr operation} {
+ set x " -106"
+ list [incr x 1] $x
+} {-105 -105}
+test incr-1.3 {basic incr operation} {
+ set x " +106"
+ list [incr x 1] $x
+} {107 107}
+
+test incr-2.1 {incr errors} {
+ list [catch incr msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-2.2 {incr errors} {
+ list [catch {incr a b c} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-2.3 {incr errors} {
+ catch {unset x}
+ list [catch {incr x} msg] $msg $errorInfo
+} {1 {can't read "x": no such variable} {can't read "x": no such variable
+ while executing
+"incr x"}}
+test incr-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"
+ (reading value of variable to increment)
+ invoked from within
+"incr x"}}
+test incr-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-2.6 {incr errors} {
+ proc readonly args {error "variable is read-only"}
+ set x 123
+ trace var x w readonly
+ list [catch {incr x 1} msg] $msg $errorInfo
+} {1 {can't set "x": variable is read-only} {can't set "x": variable is read-only
+ while executing
+"incr x 1"}}
+catch {unset x}
+test incr-2.7 {incr errors} {
+ set x -
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "-"}}
+test incr-2.8 {incr errors} {
+ set x { - }
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got " - "}}
+test incr-2.9 {incr errors} {
+ set x +
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "+"}}
+test incr-2.10 {incr errors} {
+ set x {20 x}
+ list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "20 x"}}
+
+concat {}
diff --git a/contrib/tcl/tests/info.test b/contrib/tcl/tests/info.test
new file mode 100644
index 0000000..9e8f012
--- /dev/null
+++ b/contrib/tcl/tests/info.test
@@ -0,0 +1,555 @@
+# 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-1995 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) info.test 1.33 96/03/22 12:12:48
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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} {
+ catch {rename t1 {}}
+ list [catch {info args t1} msg] $msg
+} {1 {"t1" isn't a procedure}}
+test info-1.5 {info args option} {
+ list [catch {info args set} msg] $msg
+} {1 {"set" isn't a procedure}}
+
+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} {
+ list [catch {info body set} msg] $msg
+} {1 {"set" isn't a procedure}}
+test info-2.3 {info body option} {
+ list [catch {info args set 1} msg] $msg
+} {1 {wrong # args: should be "info args procname"}}
+
+test info-3.1 {info cmdcount option} {
+ set x [info cmdcount]
+ set y 12345
+ set z [info cm]
+ expr $z-$x
+} 3
+test info-3.2 {info body option} {
+ list [catch {info cmdcount 1} msg] $msg
+} {1 {wrong # args: should be "info cmdcount"}}
+
+test info-4.1 {info commands option} {
+ 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]
+} {1 1 1 1}
+test info-4.2 {info commands option} {
+ proc t1 {} {}
+ rename t1 {}
+ set x [info comm]
+ string match {* t1 *} $x
+} 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} {
+ list [catch {info commands a b} msg] $msg
+} {1 {wrong # args: should be "info commands ?pattern?"}}
+
+test info-5.1 {info complete option} {
+ info complete ""
+} 1
+test info-5.2 {info complete option} {
+ info complete " \n"
+} 1
+test info-5.3 {info complete option} {
+ info complete "abc def"
+} 1
+test info-5.4 {info complete option} {
+ info complete "a b c d e f \t\n"
+} 1
+test info-5.5 {info complete option} {
+ info complete {a b c"d}
+} 1
+test info-5.6 {info complete option} {
+ info complete {a b "c d" e}
+} 1
+test info-5.7 {info complete option} {
+ info complete {a b "c d"}
+} 1
+test info-5.8 {info complete option} {
+ info complete {a b "c d"}
+} 1
+test info-5.9 {info complete option} {
+ info complete {a b "c d}
+} 0
+test info-5.10 {info complete option} {
+ info complete {a b "}
+} 0
+test info-5.11 {info complete option} {
+ info complete {a b "cd"xyz}
+} 1
+test info-5.12 {info complete option} {
+ info complete {a b "c $d() d"}
+} 1
+test info-5.13 {info complete option} {
+ info complete {a b "c $dd("}
+} 0
+test info-5.14 {info complete option} {
+ info complete {a b "c \"}
+} 0
+test info-5.15 {info complete option} {
+ info complete {a b "c [d e f]"}
+} 1
+test info-5.16 {info complete option} {
+ info complete {a b "c [d e f] g"}
+} 1
+test info-5.17 {info complete option} {
+ info complete {a b "c [d e f"}
+} 0
+test info-5.18 {info complete option} {
+ info complete {a {b c d} e}
+} 1
+test info-5.19 {info complete option} {
+ info complete {a {b c d}}
+} 1
+test info-5.20 {info complete option} {
+ info complete "a b\{c d"
+} 1
+test info-5.21 {info complete option} {
+ info complete "a b \{c"
+} 0
+test info-5.22 {info complete option} {
+ info complete "a b \{c{ }"
+} 0
+test info-5.23 {info complete option} {
+ info complete "a b {c d e}xxx"
+} 1
+test info-5.24 {info complete option} {
+ info complete "a b {c \\\{d e}xxx"
+} 1
+test info-5.25 {info complete option} {
+ info complete {a b [ab cd ef]}
+} 1
+test info-5.26 {info complete option} {
+ info complete {a b x[ab][cd][ef] gh}
+} 1
+test info-5.27 {info complete option} {
+ info complete {a b x[ab][cd[ef] gh}
+} 0
+test info-5.28 {info complete option} {
+ info complete {a b x[ gh}
+} 0
+test info-5.29 {info complete option} {
+ info complete {[]]]}
+} 1
+test info-5.30 {info complete option} {
+ info complete {abc x$yyy}
+} 1
+test info-5.31 {info complete option} {
+ info complete "abc x\${abc\[\\d} xyz"
+} 1
+test info-5.32 {info complete option} {
+ info complete "abc x\$\{ xyz"
+} 0
+test info-5.33 {info complete option} {
+ info complete {word $a(xyz)}
+} 1
+test info-5.34 {info complete option} {
+ info complete {word $a(}
+} 0
+test info-5.35 {info complete option} {
+ info complete "set a \\\n"
+} 0
+test info-5.36 {info complete option} {
+ info complete "set a \\n "
+} 1
+test info-5.37 {info complete option} {
+ info complete "set a \\"
+} 1
+test info-5.38 {info complete option} {
+ info complete "foo \\\n\{"
+} 0
+test info-5.39 {info complete option} {
+ info complete " # \{"
+} 1
+test info-5.40 {info complete option} {
+ info complete "foo bar;# \{"
+} 1
+test info-5.41 {info complete option} {
+ info complete "a\nb\n# \{\n# \{\nc\n"
+} 1
+test info-5.42 {info complete option} {
+ info complete "#Incomplete comment\\\n"
+} 0
+test info-5.43 {info complete option} {
+ info complete "#Incomplete comment\\\nBut now it's complete.\n"
+} 1
+test info-5.44 {info complete option} {
+ info complete "# Complete comment\\\\\n"
+} 1
+test info-5.45 {info complete option} {
+ info complete "abc\\\n def"
+} 1
+test info-5.46 {info complete option} {
+ info complete "abc\\\n "
+} 1
+test info-5.47 {info complete option} {
+ info complete "abc\\\n"
+} 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} {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ info d t1 a value
+ set value
+} {}
+test info-6.3 {info default option} {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ info default t1 c value
+} 1
+test info-6.4 {info default option} {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ info default t1 c value
+ set value
+} d
+test info-6.5 {info default option} {
+ proc t1 {a b {c d} {e "long default value"}} {}
+ set value 12345
+ set x [info default t1 e value]
+ list $x $value
+} {1 {long default value}}
+test info-6.6 {info default option} {
+ list [catch {info default a b} msg] $msg
+} {1 {wrong # args: should be "info default procname arg varname"}}
+test info-6.7 {info default option} {
+ list [catch {info default _nonexistent_ a b} msg] $msg
+} {1 {"_nonexistent_" isn't a procedure}}
+test info-6.8 {info default option} {
+ proc t1 {a b} {}
+ list [catch {info default t1 x value} msg] $msg
+} {1 {procedure "t1" doesn't have an argument "x"}}
+test info-6.9 {info default option} {
+ catch {unset a}
+ set a(0) 88
+ proc t1 {a b} {}
+ list [catch {info default t1 a a} msg] $msg
+} {1 {couldn't store default value in variable "a"}}
+test info-6.10 {info default option} {
+ catch {unset a}
+ set a(0) 88
+ proc t1 {{a 18} b} {}
+ list [catch {info default t1 a a} msg] $msg
+} {1 {couldn't store default value in variable "a"}}
+catch {unset a}
+
+test info-7.1 {info exists option} {
+ set value foo
+ info exists value
+} 1
+catch {unset _nonexistent_}
+test info-7.2 {info exists option} {
+ info exists _nonexistent_
+} 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} {
+ proc t1 {x} {
+ global _nonexistent_
+ return [info exists _nonexistent_]
+ }
+ t1 2
+} 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} {
+ catch {unset x}
+ set x(2) 44
+ list [info exists x] [info exists x(1)] [info exists x(2)]
+} {1 0 1}
+catch {unset x}
+test info-7.8 {info exists option} {
+ list [catch {info exists} msg] $msg
+} {1 {wrong # args: should be "info exists varName"}}
+test info-7.9 {info exists option} {
+ list [catch {info exists 1 2} msg] $msg
+} {1 {wrong # args: should be "info exists varName"}}
+
+test info-8.1 {info globals option} {
+ 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]
+} {1 1 1 0}
+test info-8.2 {info globals option} {
+ set _xxx1 1
+ set _xxx2 2
+ lsort [info g _xxx*]
+} {_xxx1 _xxx2}
+test info-8.3 {info globals option} {
+ list [catch {info globals 1 2} msg] $msg
+} {1 {wrong # args: should be "info globals ?pattern?"}}
+
+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} {
+ list [catch {info level 1 2} msg] $msg
+} {1 {wrong # args: should be "info level [number]"}}
+test info-9.6 {info level option} {
+ list [catch {info level 123a} msg] $msg
+} {1 {expected integer but got "123a"}}
+test info-9.7 {info level option} {
+ list [catch {info level 0} msg] $msg
+} {1 {bad level "0"}}
+test info-9.8 {info level option} {
+ proc t1 {} {info level -1}
+ list [catch {t1} msg] $msg
+} {1 {bad level "-1"}}
+test info-9.9 {info level option} {
+ proc t1 {x} {info level $x}
+ list [catch {t1 -3} msg] $msg
+} {1 {bad level "-3"}}
+
+set savedLibrary tcl_library
+test info-10.1 {info library option} {
+ list [catch {info library x} msg] $msg
+} {1 {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} {
+ unset tcl_library
+ list [catch {info library} msg] $msg
+} {1 {no library has been specified for Tcl}}
+set tcl_library $savedLibrary
+
+test info-11.1 {info loaded option} {
+ list [catch {info loaded a b} msg] $msg
+} {1 {wrong # args: should be "info loaded ?interp?"}}
+test info-11.2 {info loaded option} {
+ list [catch {info loaded {}}] [catch {info loaded gorp} msg] $msg
+} {0 1 {couldn't find slave interpreter named "gorp"}}
+
+test info-12.1 {info locals option} {
+ set a 22
+ proc t1 {x y} {
+ set b 13
+ set c testing
+ global a
+ return [info locals]
+ }
+ lsort [t1 23 24]
+} {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} {
+ list [catch {info locals 1 2} msg] $msg
+} {1 {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-13.1 {info nameofexecutable option} {
+ list [catch {info nameofexecutable foo} msg] $msg
+} {1 {wrong # args: should be "info nameofexecutable"}}
+
+test info-14.1 {info patchlevel option} {
+ set a [info patchlevel]
+ regexp {[0-9]+\.[0-9]+([p[0-9]+)?} $a
+} 1
+test info-14.2 {info patchlevel option} {
+ list [catch {info patchlevel a} msg] $msg
+} {1 {wrong # args: should be "info patchlevel"}}
+test info-14.3 {info patchlevel option} {
+ set t $tcl_patchLevel
+ unset tcl_patchLevel
+ set result [list [catch {info patchlevel} msg] $msg]
+ set tcl_patchLevel $t
+ set result
+} {1 {can't read "tcl_patchLevel": no such variable}}
+
+test info-15.1 {info procs option} {
+ proc t1 {} {}
+ proc t2 {} {}
+ set x " [info procs] "
+ list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+ [string match {* _undefined_ *} $x]
+} {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} {
+ list [catch {info procs 2 3} msg] $msg
+} {1 {wrong # args: should be "info procs ?pattern?"}}
+
+test info-16.1 {info script option} {
+ list [catch {info script x} msg] $msg
+} {1 {wrong # args: should be "info script"}}
+test info-16.2 {info script option} {
+ file tail [info sc]
+} info.test
+removeFile gorp.info
+makeFile "info script\n" gorp.info
+test info-16.3 {info script option} {
+ list [source gorp.info] [file tail [info script]]
+} {gorp.info 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}
+removeFile gorp.info
+
+test info-17.1 {info sharedlibextension option} {
+ list [catch {info sharedlibextension foo} msg] $msg
+} {1 {wrong # args: should be "info sharedlibextension"}}
+
+test info-18.1 {info tclversion option} {
+ set x [info tclversion]
+ scan $x "%d.%d%c" a b c
+} 2
+test info-18.2 {info tclversion option} {
+ list [catch {info t 2} msg] $msg
+} {1 {wrong # args: should be "info tclversion"}}
+test info-18.3 {info tclversion option} {
+ set t $tcl_version
+ unset tcl_version
+ set result [list [catch {info tclversion} msg] $msg]
+ set tcl_version $t
+ set result
+} {1 {can't read "tcl_version": no such variable}}
+
+test info-19.1 {info vars option} {
+ set a 1
+ set b 2
+ proc t1 {x y} {
+ global a b
+ set c 33
+ return [info vars]
+ }
+ lsort [t1 18 19]
+} {a b c x y}
+test info-19.2 {info vars option} {
+ set xxx1 1
+ set xxx2 2
+ proc t1 {xxa y} {
+ global xxx1 xxx2
+ set c 33
+ return [info vars x*]
+ }
+ lsort [t1 18 19]
+} {xxa xxx1 xxx2}
+test info-19.3 {info vars option} {
+ lsort [info vars]
+} [lsort [info globals]]
+test info-19.4 {info vars option} {
+ list [catch {info vars a b} msg] $msg
+} {1 {wrong # args: should be "info vars ?pattern?"}}
+
+test info-20.1 {miscellaneous error conditions} {
+ list [catch {info} msg] $msg
+} {1 {wrong # args: should be "info option ?arg arg ...?"}}
+test info-20.2 {miscellaneous error conditions} {
+ list [catch {info gorp} msg] $msg
+} {1 {bad option "gorp": should be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
+test info-20.3 {miscellaneous error conditions} {
+ list [catch {info c} msg] $msg
+} {1 {bad option "c": should be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
+test info-20.4 {miscellaneous error conditions} {
+ list [catch {info l} msg] $msg
+} {1 {bad option "l": should be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
+test info-20.5 {miscellaneous error conditions} {
+ list [catch {info s} msg] $msg
+} {1 {bad option "s": should be args, body, cmdcount, commands, complete, default, exists, globals, hostname, level, library, loaded, locals, nameofexecutable, patchlevel, procs, script, sharedlibextension, tclversion, or vars}}
diff --git a/contrib/tcl/tests/interp.test b/contrib/tcl/tests/interp.test
new file mode 100644
index 0000000..c82b901
--- /dev/null
+++ b/contrib/tcl/tests/interp.test
@@ -0,0 +1,570 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) interp.test 1.24 96/03/27 10:23:29
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
+
+proc equiv {x} {return $x}
+
+# Part 0: Check out options for interp command
+test interp-1.1 {options for interp command} {
+ list [catch {interp} msg] $msg
+} {1 {wrong # args: should be "interp cmd ?arg ...?"}}
+test interp-1.2 {options for interp command} {
+ list [catch {interp frobox} msg] $msg
+} {1 {bad option "frobox": should be alias, aliases, create, delete, exists, eval, issafe, share, slaves, target or transfer}}
+test interp-1.3 {options for interp command} {
+ interp delete
+} ""
+test interp-1.4 {options for interp command} {
+ list [catch {interp delete foo bar} msg] $msg
+} {1 {interpreter named "foo" not found}}
+test interp-1.5 {options for interp command} {
+ list [catch {interp exists foo bar} msg] $msg
+} {1 {wrong # args: should be "interp exists ?path?"}}
+#
+# test interp-0.6 was removed
+#
+test interp-1.6 {options for interp command} {
+ list [catch {interp slaves foo bar zop} msg] $msg
+} {1 {wrong # args: should be "interp slaves ?path?"}}
+test interp-1.7 {options for interp command} {
+ list [catch {interp hello} msg] $msg
+} {1 {bad option "hello": should be alias, aliases, create, delete, exists, eval, issafe, share, slaves, target or transfer}}
+test interp-1.8 {options for interp command} {
+ list [catch {interp -froboz} msg] $msg
+} {1 {bad option "-froboz": should be alias, aliases, create, delete, exists, eval, issafe, share, slaves, target or transfer}}
+test interp-1.9 {options for interp command} {
+ list [catch {interp -froboz -safe} msg] $msg
+} {1 {bad option "-froboz": should be alias, aliases, create, delete, exists, eval, issafe, share, slaves, target or transfer}}
+test interp-1.10 {options for interp command} {
+ list [catch {interp target} msg] $msg
+} {1 {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": should be -safe}}
+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}
+
+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} {
+ list [catch {interp slaves a b c} msg] $msg
+} {1 {wrong # args: should be "interp slaves ?path?"}}
+test interp-3.5 {testing interp exists and interp slaves} {
+ list [catch {interp exists a b c} msg] $msg
+} {1 {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} {
+ list [catch {interp slaves a b c} msg] $msg
+} {1 {wrong # args: should be "interp slaves ?path?"}}
+test interp-3.9 {testing interp exists and interp slaves} {
+ interp create {a a2} -safe
+ interp slaves a
+} {a2}
+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} {
+ interp delete a
+} ""
+test interp-4.2 {testing interp delete} {
+ list [catch {interp delete nonexistent} msg] $msg
+} {1 {interpreter named "nonexistent" not found}}
+test interp-4.3 {testing interp delete} {
+ list [catch {interp delete x y z} msg] $msg
+} {1 {interpreter named "x" not found}}
+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}
+ interp slaves a
+} ""
+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} {
+ interp create c1
+ interp create c2
+ list [catch {interp delete c1 c2 c3} msg] $msg
+} {1 {interpreter named "c3" not found}}
+
+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} {
+ list [catch {a eval foo} msg] $msg
+} {1 {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} {
+ list [catch {interp eval {a x2} foo} msg] $msg
+} {1 {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} {
+ a aliases
+} {foo bar}
+
+# Part 7: testing basic alias invocation
+test interp-8.1 {testing basic alias invocation} {
+ a eval foo s1 s2 s3
+} {seen in master: {s1 s2 s3}}
+test interp-8.2 {testing basic alias invocation} {
+ a eval bar s1 s2 s3
+} {seen in master: {a1 a2 a3 s1 s2 s3}}
+
+# Part 8: Testing aliases for non-existent targets
+test interp-9.1 {testing aliases for non-existent targets} {
+ a alias zop nonexistent-command-in-master
+ list [catch {a eval zop} msg] $msg
+} {1 {aliased target "nonexistent-command-in-master" for "zop" not found}}
+test interp-9.2 {testing aliases for non-existent targets} {
+ proc nonexistent-command-in-master {} {return i_exist!}
+ a eval zop
+} i_exist!
+
+if {[info command nonexistent-command-in-master] != ""} {
+ rename nonexistent-command-in-master {}
+}
+
+# Recreate interpreter b..
+if {![interp exists b]} {
+ interp create b
+}
+
+# Part 9: Aliasing between interpreters
+test interp-10.1 {testing aliasing between interpreters} {
+ interp alias a a_alias b b_alias 1 2 3
+} a_alias
+test interp-10.2 {testing aliasing between interpreters} {
+ b eval {proc b_alias {args} {return [list got $args]}}
+ a eval a_alias a b c
+} {got {1 2 3 a b c}}
+test interp-10.3 {testing aliasing between interpreters} {
+ b eval {rename b_alias {}}
+ list [catch {a eval a_alias a b c} msg] $msg
+} {1 {aliased target "b_alias" for "a_alias" not found}}
+test interp-10.4 {testing aliasing between interpreters} {
+ a aliases
+} {foo zop bar a_alias}
+test interp-10.5 {testing aliasing between interpreters} {
+ interp delete b
+ a aliases
+} {foo zop bar}
+
+# Recreate interpreter b..
+if {![interp exists b]} {
+ interp create b
+}
+
+test interp-10.6 {testing aliasing between interpreters} {
+ 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} {
+ 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 {}
+ equiv $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} {
+ a alias boo no_command
+ interp target a boo
+} ""
+test interp-11.4 {testing interp target} {
+ interp create x1
+ x1 eval interp create x2
+ x1 eval x2 eval interp create x3
+ 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} {
+ 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}}
+
+# Part 11: testing "interp issafe"
+test interp-12.1 {testing interp issafe} {
+ interp issafe
+} 0
+test interp-12.2 {testing interp issafe} {
+ interp issafe a
+} 0
+test interp-12.3 {testing interp issafe} {
+ interp create {a x3} -safe
+ interp issafe {a x3}
+} 1
+test interp-12.4 {testing interp issafe} {
+ 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} {
+ a issafe
+} 0
+test interp-13.2 {testing foo issafe} {
+ a eval x3 issafe
+} 1
+test interp-13.3 {testing foo issafe} {
+ a eval x3 eval foo issafe
+} 1
+
+# part 13: testing interp aliases
+test interp-14.1 {testing interp aliases} {
+ interp aliases
+} ""
+test interp-14.2 {testing interp aliases} {
+ interp aliases a
+} {boo foo zop bar a_command}
+test interp-14.3 {testing interp aliases} {
+ interp alias {a x3} froboz "" puts
+ interp aliases {a x3}
+} froboz
+
+test interp-15.1 {testing file sharing} {
+ 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} {
+ set f [open foo w]
+ interp share "" $f z
+ z eval puts $f hello
+ z eval close $f
+ close $f
+} ""
+test interp-15.3 {testing file sharing} {
+ 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} {
+ set f [open foo w]
+ interp share "" $f xsafe
+ xsafe eval puts $f hello
+ xsafe eval close $f
+ close $f
+} ""
+test interp-15.5 {testing file sharing} {
+ 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} {
+ set f [open foo w]
+ interp share "" $f xsafe
+ set x [list [catch [list xsafe eval gets $f] msg] $msg]
+ close $f
+ string compare [string tolower $x] \
+ [list 1 [format "channel \"%s\" wasn't opened for reading" $f]]
+} 0
+test interp-15.7 {testing file transferring} {
+ set f [open foo w]
+ interp transfer "" $f xsafe
+ xsafe eval puts $f hello
+ xsafe eval close $f
+} ""
+test interp-15.8 {testing file transferring} {
+ set f [open foo 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]]
+} 0
+removeFile foo
+
+#
+# Torture tests for interpreter deletion order
+#
+proc kill {} {interp delete xxx}
+
+test interp-15.9 {testing deletion order} {
+ interp create xxx
+ xxx alias kill kill
+ list [catch {xxx eval kill} msg] $msg
+} {0 {}}
+test interp-16.1 {testing deletion order} {
+ 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} {
+ 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} {
+ 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} {
+ 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
+} ""
+
+#
+# Alias loop prevention testing.
+#
+
+test interp-16.5 {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.1 {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.2 {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.3 {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 "b": would create a loop}}
+test interp-17.4 {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 "l2": 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.
+#
+
+if {[info commands testinterpdelete] != ""} {
+ test interp-17.5 {testing Tcl_DeleteInterp vs slaves} {
+ list [catch {testinterpdelete} msg] $msg
+ } {1 {wrong # args: should be "testinterpdelete path"}}
+ test interp-18.1 {testing Tcl_DeleteInterp vs slaves} {
+ catch {interp delete a}
+ interp create a
+ testinterpdelete a
+ } ""
+ test interp-18.2 {testing Tcl_DeleteInterp vs slaves} {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ testinterpdelete {a b}
+ } ""
+ test interp-18.3 {testing Tcl_DeleteInterp vs slaves} {
+ catch {interp delete a}
+ interp create a
+ interp create {a b}
+ testinterpdelete a
+ } ""
+ test interp-18.4 {testing Tcl_DeleteInterp vs slaves} {
+ 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.5 {testing Tcl_DeleteInterp vs slaves} {
+ 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.6 {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.7 {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}}
+}
+
+foreach i [interp slaves] {
+ interp delete $i
+}
diff --git a/contrib/tcl/tests/io.test b/contrib/tcl/tests/io.test
new file mode 100644
index 0000000..60b75cd
--- /dev/null
+++ b/contrib/tcl/tests/io.test
@@ -0,0 +1,4341 @@
+# 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-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.
+#
+# "@(#) io.test 1.75 96/04/18 09:58:51"
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+removeFile test1
+removeFile pipe
+
+# These tests are disabled until we decide what to do with "unsupported0".
+#
+#test io-1.7 {unsupported0 command} {
+# removeFile test1
+# set f1 [open iocmd.test]
+# set f2 [open test1 w]
+# unsupported0 $f1 $f2
+# close $f1
+# catch {close $f2}
+# set s1 [file size io.test]
+# set s2 [file size test1]
+# set x ok
+# if {"$s1" != "$s2"} {
+# set x broken
+# }
+# set x
+#} ok
+#test io-1.8 {unsupported0 command} {
+# removeFile test1
+# set f1 [open io.test]
+# set f2 [open test1 w]
+# unsupported0 $f1 $f2 40
+# close $f1
+# close $f2
+# file size test1
+#} 40
+#test io-1.9 {unsupported0 command} {
+# removeFile test1
+# set f1 [open io.test]
+# set f2 [open test1 w]
+# unsupported0 $f1 $f2 -1
+# close $f1
+# close $f2
+# set x ok
+# set s1 [file size io.test]
+# set s2 [file size test1]
+# if {$s1 != $s2} {
+# set x broken
+# }
+# set x
+#} ok
+#test io-1.10 {unsupported0 command} {unixOrPc} {
+# removeFile pipe
+# removeFile test1
+# set f1 [open pipe w]
+# puts $f1 {puts ready}
+# puts $f1 {gets stdin}
+# puts $f1 {set f1 [open io.test r]}
+# puts $f1 {puts [read $f1 100]}
+# puts $f1 {close $f1}
+# close $f1
+# set f1 [open "|$tcltest pipe" r+]
+# gets $f1
+# puts $f1 ready
+# flush $f1
+# set f2 [open test1 w]
+# set c [unsupported0 $f1 $f2 40]
+# catch {close $f1}
+# close $f2
+# set s1 [file size test1]
+# set x ok
+# if {$s1 != "40"} {
+# set x broken
+# }
+# list $c $x
+#} {40 ok}
+
+# Test standard handle management. The functions tested are
+# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
+# also testing channel table management.
+
+if {$tcl_platform(platform) == "macintosh"} {
+ set consoleFileNames [list console0 console1 console2]
+} else {
+ set consoleFileNames [lsort [testchannel open]]
+}
+test io-1.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
+ 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-1.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}
+test io-1.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {unixOrPc} {
+ set f [open test1 w]
+ puts $f {
+ close stdin
+ close stdout
+ close stderr
+ set f [open test1 r]
+ set f2 [open test2 w]
+ set f3 [open test3 w]
+ puts stdout [gets stdin]
+ puts stdout out
+ puts stderr err
+ close $f
+ close $f2
+ close $f3
+ }
+ close $f
+ set result [eval exec $tcltest test1]
+ set f [open test2 r]
+ set f2 [open test3 r]
+ lappend result [read $f] [read $f2]
+ close $f
+ close $f2
+ set result
+} {{
+out
+} {err
+}}
+# This test relies on the fact that the smallest available fd is used first.
+test io-1.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {unixOnly} {
+ set f [open test1 w]
+ puts $f { close stdin
+ close stdout
+ close stderr
+ set f [open test1 r]
+ set f2 [open test2 w]
+ set f3 [open test3 w]
+ puts stdout [gets stdin]
+ puts stdout $f2
+ puts stderr $f3
+ close $f
+ close $f2
+ close $f3
+ }
+ close $f
+ set result [eval exec $tcltest test1]
+ set f [open test2 r]
+ set f2 [open test3 r]
+ lappend result [read $f] [read $f2]
+ close $f
+ close $f2
+ set result
+} {{ close stdin
+file1
+} {file2
+}}
+catch {interp delete z}
+test io-1.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-1.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-1.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"}}
+
+# Must add test function for testing Tcl_CreateCloseHandler and
+# Tcl_DeleteCloseHandler.
+
+# Test channel table management. The functions tested are
+# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
+# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
+
+test io-3.1 {GetChannelTable, DeleteChannelTable on std handles} {
+ interp create x
+ set l ""
+ lappend l [testchannel refcount stdin]
+ x eval {eof stdin}
+ lappend l [testchannel refcount stdin]
+ interp delete x
+ lappend l [testchannel refcount stdin]
+ set l
+} {2 2 1}
+test io-3.2 {GetChannelTable, DeleteChannelTable on std handles} {
+ interp create x
+ set l ""
+ lappend l [testchannel refcount stdout]
+ x eval {eof stdout}
+ lappend l [testchannel refcount stdout]
+ interp delete x
+ lappend l [testchannel refcount stdout]
+ set l
+} {2 2 1}
+test io-3.3 {GetChannelTable, DeleteChannelTable on std handles} {
+ interp create x
+ set l ""
+ lappend l [testchannel refcount stderr]
+ x eval {eof stderr}
+ lappend l [testchannel refcount stderr]
+ interp delete x
+ lappend l [testchannel refcount stderr]
+ set l
+} {2 2 1}
+test io-3.4 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
+ removeFile test1
+ set l ""
+ set f [open 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-3.5 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
+ removeFile test1
+ set l ""
+ set f [open 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-3.6 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {
+ removeFile test1
+ set l ""
+ set f [open 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-3.7 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+ eof stdin
+} 0
+test io-3.6 {testing Tcl_GetChannel, user opened handle} {
+ removeFile test1
+ set f [open test1 w]
+ set x [eof $f]
+ close $f
+ set x
+} 0
+test io-3.8 {Tcl_GetChannel, channel not found} {
+ list [catch {eof file34} msg] $msg
+} {1 {can not find channel named "file34"}}
+test io-3.9 {Tcl_CreateChannel, insertion into channel table} {
+ removeFile test1
+ set f [open 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 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-4.1 {Tcl_GetChannelName} {
+ removeFile test1
+ set f [open test1 w]
+ set n [testchannel name $f]
+ close $f
+ string compare $n $f
+} 0
+test io-4.2 {Tcl_GetChannelType} {
+ removeFile test1
+ set f [open test1 w]
+ set t [testchannel type $f]
+ close $f
+ string compare $t file
+} 0
+test io-4.3 {Tcl_GetChannelFile, input} {
+ set f [open io.test r]
+ gets $f
+ set l ""
+ lappend l [testchannel inputbuffered $f]
+ lappend l [tell $f]
+ close $f
+ set l
+} {4022 74}
+test io-4.4 {Tcl_GetChannelFile, output} {
+ removeFile test1
+ set f [open 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
+ removeFile test1
+ set l
+} {6 6 0 6}
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test io-5.1 {FlushChannel, no output buffered} {
+ removeFile test1
+ set f [open test1 w]
+ flush $f
+ set s [file size test1]
+ close $f
+ set s
+} 0
+test io-5.2 {FlushChannel, some output buffered} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ puts $f hello
+ lappend l [file size test1]
+ flush $f
+ lappend l [file size test1]
+ close $f
+ lappend l [file size test1]
+ set l
+} {0 6 6}
+test io-5.3 {FlushChannel, implicit flush on close} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ set l ""
+ puts $f hello
+ lappend l [file size test1]
+ close $f
+ lappend l [file size test1]
+ set l
+} {0 6}
+test io-5.4 {FlushChannel, implicit flush when buffer fills} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ fconfigure $f -buffersize 60
+ set l ""
+ lappend l [file size test1]
+ for {set i 0} {$i < 12} {incr i} {
+ puts $f hello
+ }
+ lappend l [file size test1]
+ flush $f
+ lappend l [file size test1]
+ close $f
+ set l
+} {0 60 72}
+test io-5.5 {FlushChannel, implicit flush when buffer fills and on close} {unixOrPc} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -buffersize 60 -eofchar {}
+ set l ""
+ lappend l [file size test1]
+ for {set i 0} {$i < 12} {incr i} {
+ puts $f hello
+ }
+ lappend l [file size test1]
+ close $f
+ lappend l [file size test1]
+ set l
+} {0 60 72}
+test io-5.6 {FlushChannel, async flushing, async close} {unixOrPc asyncPipeClose} {
+ removeFile pipe
+ removeFile output
+ set f [open pipe w]
+ puts $f {
+ set f [open output w]
+ 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 output w]
+ close $f
+ set f [open "|$tcltest pipe" w]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size output] < 65536) && ($counter < 1000)} {
+ incr counter
+ after 20
+ update
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} ok
+
+# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
+
+test io-6.1 {CloseChannel called when all references are dropped} {
+ removeFile test1
+ set f [open 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-6.2 {CloseChannel called when all references are dropped} {
+ removeFile test1
+ set f [open 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 test1 r]
+ set l [gets $f]
+ close $f
+ set l
+} abcdef
+test io-6.3 {CloseChannel, not called before output queue is empty} {unixOrPc asyncPipeClose tempNotPc nonPortable} {
+ removeFile pipe
+ removeFile output
+ set f [open 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 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 output w]
+ close $f
+ set f [open "|$tcltest pipe" r+]
+ fconfigure $f -blocking off -eofchar {}
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size output] < 20480) && ($counter < 1000)} {
+ incr counter
+ after 20
+ update
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+ #
+ # Wait for the flush to finish
+ #
+ catch {vwait x}
+ set result
+} ok
+test io-6.4 {Tcl_Close} {
+ removeFile test1
+ set l ""
+ lappend l [lsort [testchannel open]]
+ set f [open test1 w]
+ lappend l [lsort [testchannel open]]
+ close $f
+ lappend l [lsort [testchannel open]]
+ set x [list $consoleFileNames \
+ [lsort [eval list $consoleFileNames $f]] \
+ $consoleFileNames]
+ string compare $l $x
+} 0
+test io-6.5 {Tcl_Close vs standard handles} {unixOnly} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ close stdin
+ puts [testchannel open]
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ set l [gets $f]
+ close $f
+ set l
+} {file1 file2}
+
+# Test output on channels. The functions tested are Tcl_Write
+# and Tcl_Flush.
+
+test io-7.1 {Tcl_Write, channel not writable} {
+ list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-7.2 {Tcl_Write, empty string} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f ""
+ close $f
+ file size test1
+} 0
+test io-7.3 {Tcl_Write, nonempty string} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f hello
+ close $f
+ file size test1
+} 5
+test io-7.4 {Tcl_Write, buffering in full buffering mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -buffering full -eofchar {}
+ puts $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ close $f
+ set l
+} {6 0 0 6}
+test io-7.5 {Tcl_Write, buffering in line buffering mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -buffering line -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ close $f
+ set l
+} {5 0 0 11}
+test io-7.6 {Tcl_Write, buffering in no buffering mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -buffering none -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ close $f
+ set l
+} {0 5 0 11}
+test io-7.7 {Tcl_Flush, full buffering} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -buffering full -eofchar {}
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ close $f
+ set l
+} {5 0 11 0 0 11}
+test io-7.8 {Tcl_Flush, full buffering} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -buffering line
+ puts -nonewline $f hello
+ set l ""
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ puts $f hello
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ flush $f
+ lappend l [testchannel outputbuffered $f]
+ lappend l [file size test1]
+ close $f
+ set l
+} {5 0 0 5 0 11 0 11}
+test io-7.9 {Tcl_Flush, channel not writable} {
+ list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-7.10 {Tcl_Write, looping and buffering} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set f2 [open io.test r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts $f1 [gets $f2]
+ }
+ close $f2
+ close $f1
+ file size test1
+} 439
+test io-7.11 {Tcl_Write, no newline, implicit flush} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -eofchar {}
+ set f2 [open io.test r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts -nonewline $f1 [gets $f2]
+ }
+ close $f1
+ close $f2
+ file size test1
+} 429
+test io-7.12 {Tcl_Write on a pipe} {unixOrPc} {
+ removeFile test1
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {
+ set f1 [open io.test r]
+ for {set x 0} {$x < 10} {incr x} {
+ puts [gets $f1]
+ }
+ }
+ close $f1
+ set f1 [open "|$tcltest pipe" r]
+ set f2 [open io.test 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-7.13 {Tcl_Write to a pipe, line buffered} {unixOrPc} {
+ removeFile test1
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {
+ puts [gets stdin]
+ puts [gets stdin]
+ }
+ close $f1
+ set y ok
+ set f1 [open "|$tcltest pipe" r+]
+ fconfigure $f1 -buffering line
+ set f2 [open io.test 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-7.14 {Tcl_Write, buffering and implicit flush at close} {
+ removeFile test3
+ set f [open test3 w]
+ puts -nonewline $f "Text1"
+ puts -nonewline $f " Text 2"
+ puts $f " Text 3"
+ close $f
+ set f [open test3 r]
+ set x [gets $f]
+ close $f
+ set x
+} {Text1 Text 2 Text 3}
+test io-7.15 {Tcl_Flush, channel not open for writing} {
+ removeFile test1
+ set fd [open test1 w]
+ close $fd
+ set fd [open 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-7.16 {Tcl_Flush on pipe opened only for reading} {unixOrPc unixExecs} {
+ set fd [open "|cat io.test" 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-7.17 {Tcl_Write buffers, then Tcl_Flush flushes} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ set x [file size test1]
+ close $f1
+ set x
+} 18
+test io-7.18 {Tcl_Write and Tcl_Flush intermixed} {
+ removeFile test1
+ set x ""
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ lappend x [file size test1]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size test1]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size test1]
+ close $f1
+ set x
+} {18 24 30}
+test io-7.19 {Explicit and implicit flushes} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set x ""
+ puts $f1 hello
+ puts $f1 hello
+ puts $f1 hello
+ flush $f1
+ lappend x [file size test1]
+ puts $f1 hello
+ flush $f1
+ lappend x [file size test1]
+ puts $f1 hello
+ close $f1
+ lappend x [file size test1]
+ set x
+} {18 24 30}
+test io-7.20 {Implicit flush when buffer is full} {
+ removeFile test1
+ set f1 [open 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 test1]
+ for {set x 0} {$x < 100} {incr x} {
+ puts $f1 $line
+ }
+ lappend z [file size test1]
+ close $f1
+ lappend z [file size test1]
+ set z
+} {4096 12288 12600}
+test io-7.21 {Tcl_Flush to pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open 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 "|$tcltest pipe" r+]
+ puts $f1 hello
+ flush $f1
+ set x [gets $f1]
+ catch {close $f1}
+ set x
+} "read 6 characters"
+test io-7.22 {Tcl_Flush called at other end of pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open 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 "|$tcltest 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-7.23 {Tcl_Flush and line buffering at end of pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {
+ puts hello
+ puts hello
+ gets stdin
+ puts bye
+ }
+ close $f1
+ set f1 [open "|$tcltest 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-7.24 {Tcl_Write and Tcl_Flush move end of file} {
+ set f [open test3 w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ set f2 [open test3]
+ set x {}
+ lappend x [read -nonewline $f2]
+ close $f2
+ flush $f
+ set f2 [open test3]
+ lappend x [read -nonewline $f2]
+ close $f2
+ close $f
+ set x
+} {{} {Line 1
+Line 2}}
+test io-7.25 {Implicit flush with Tcl_Flush to command pipelines} {unixOrPc unixExecs} {
+ removeFile test3
+ set f [open "| cat | cat > test3" w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ close $f
+ after 100
+ set f [open test3 r]
+ set x [read $f]
+ close $f
+ set x
+} {Line 1
+Line 2
+}
+test io-7.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {unixOrPc unixExecs} {
+ set f [open "| cat -u" r+]
+ puts $f "Line1"
+ flush $f
+ set x [gets $f]
+ close $f
+ set x
+} {Line1}
+test io-7.27 {Tcl_Flush on closed pipeline} {unixOrPc tempNotPc} {
+ removeFile pipe
+ set f [open pipe w]
+ puts $f {exit}
+ close $f
+ set f [open "|$tcltest 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-7.28 {Tcl_Write, lf mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ flush $f
+ set s [file size test1]
+ close $f
+ set s
+} 21
+test io-7.29 {Tcl_Write, cr mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ close $f
+ file size test1
+} 21
+test io-7.30 {Tcl_Write, crlf mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf -eofchar {}
+ puts $f hello\nthere\nand\nhere
+ close $f
+ file size test1
+} 25
+test io-7.31 {Tcl_Write, background flush} {unixOrPc} {
+ removeFile pipe
+ removeFile output
+ set f [open pipe w]
+ puts $f {set f [open 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 output w]
+ close $f
+ set f [open "|$tcltest pipe" r+]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size output] < 65536) && ($counter < 1000)} {
+ incr counter
+ after 5
+ update
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} ok
+test io-7.32 {Tcl_Write, background flush to slow reader} {unixOrPc asyncPipeClose} {
+ removeFile pipe
+ removeFile output
+ set f [open pipe w]
+ puts $f {set f [open 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 output w]
+ close $f
+ set f [open "|$tcltest pipe" r+]
+ fconfigure $f -blocking off
+ puts -nonewline $f $x
+ close $f
+ set counter 0
+ while {([file size output] < 65536) && ($counter < 1000)} {
+ incr counter
+ after 20
+ update
+ }
+ if {$counter == 1000} {
+ set result probably_broken
+ } else {
+ set result ok
+ }
+} ok
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test io-8.1 {Tcl_Write lf, Tcl_Read lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-8.2 {Tcl_Write lf, Tcl_Read cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-8.3 {Tcl_Write lf, Tcl_Read crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-8.4 {Tcl_Write cr, Tcl_Read cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation cr
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-8.5 {Tcl_Write cr, Tcl_Read lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation lf
+ set x [read $f]
+ close $f
+ set x
+} "hello\rthere\rand\rhere\r"
+test io-8.6 {Tcl_Write cr, Tcl_Read crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\rthere\rand\rhere\r"
+test io-8.7 {Tcl_Write crlf, Tcl_Read crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation crlf
+ set x [read $f]
+ close $f
+ set x
+} "hello\nthere\nand\nhere\n"
+test io-8.8 {Tcl_Write crlf, Tcl_Read lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-8.9 {Tcl_Write crlf, Tcl_Read cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-8.10 {Tcl_Write lf, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-8.11 {Tcl_Write cr, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-8.12 {Tcl_Write crlf, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open test1 r]
+ set c [read $f]
+ set x [fconfigure $f -translation]
+ close $f
+ list $c $x
+} {{hello
+there
+and
+here
+} auto}
+
+test io-8.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
+ removeFile test1
+ set f [open 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 test1 r]
+ fconfigure $f -translation auto
+ set c [read $f]
+ close $f
+ string length $c
+} [expr 700*15+1]
+
+test io-8.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
+ removeFile test1
+ set f [open 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 test1 r]
+ fconfigure $f -translation crlf
+ set c [read $f]
+ close $f
+ string length $c
+} [expr 700*15+1]
+
+test io-8.15 {Tcl_Write mixed, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-8.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+ close $f
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-8.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {pcOnly} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -eofchar \x1a -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation auto
+ set c [read $f]
+ close $f
+ set c
+} {hello
+there
+and
+here
+}
+test io-8.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open 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-8.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open 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-8.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open 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-8.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation cr -eofchar {}
+ set l ""
+ set x [gets $f]
+ lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs"]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 1 {} 1}
+test io-8.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cghi\nqrs" 26]
+ puts $f $s
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation crlf -eofchar {}
+ set l ""
+ set x [gets $f]
+ lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs"]
+ lappend l [eof $f]
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {0 1 {} 1}
+test io-8.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open 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-8.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open 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-8.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open 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-8.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open 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-8.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open 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-8.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ set c [format abc\ndef\n%cqrs\ntuv 26]
+ puts $f $c
+ close $f
+ set f [open 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-9.1 {Tcl_Write lf, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.2 {Tcl_Write cr, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.3 {Tcl_Write crlf, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.4 {Tcl_Write lf, Tcl_Gets lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.5 {Tcl_Write lf, Tcl_Gets cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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
+} {20 21 cr 1 {} 21 cr 1}
+test io-9.6 {Tcl_Write lf, Tcl_Gets crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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
+} {20 21 crlf 1 {} 21 crlf 1}
+test io-9.7 {Tcl_Write cr, Tcl_Gets cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.8 {Tcl_Write cr, Tcl_Gets lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.9 {Tcl_Write cr, Tcl_Gets crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.10 {Tcl_Write crlf, Tcl_Gets crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.11 {Tcl_Write crlf, Tcl_Gets cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.12 {Tcl_Write crlf, Tcl_Gets lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ puts $f hello\nthere\nand\nhere
+ close $f
+ set f [open 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-9.13 {binary mode is synonym of lf mode} {
+ removeFile test1
+ set f [open 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-9.15 {Tcl_Write mixed, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts $f hello\nthere\rand\r\nhere
+ close $f
+ set f [open 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-9.16 {Tcl_Write mixed, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\r
+ close $f
+ set f [open 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-9.17 {Tcl_Write mixed, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\n
+ close $f
+ set f [open 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-9.18 {Tcl_Write mixed, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+ close $f
+ set f [open 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-9.19 {Tcl_Write ^Z at end, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "hello\nthere\nand\rhere\n\%c" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.20 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -eofchar \x1a -translation lf
+ puts $f hello\nthere\nand\rhere
+ close $f
+ set f [open 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-9.21 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.22 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.25 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.27 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.29 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.31 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf -eofchar {}
+ set s [format "abc\ndef\n%cqrs\ntuv" 26]
+ puts $f $s
+ close $f
+ set f [open 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-9.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
+ removeFile test1
+ set f [open 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 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 io-9.33 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
+ removeFile test1
+ set f [open 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 < 256} {incr i} {
+ puts $f $line
+ }
+ close $f
+ set f [open test1 r]
+ fconfigure $f -translation auto
+ set c ""
+ while {[gets $f line] >= 0} {
+ append c $line\n
+ }
+ close $f
+ string length $c
+} [expr 256*15+1]
+
+
+# Test Tcl_Read and buffering.
+
+test io-10.1 {Tcl_Read, channel not readable} {
+ list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test io-10.2 {Tcl_Read, zero byte count} {
+ read stdin 0
+} ""
+test io-10.3 {Tcl_Read, negative byte count} {
+ set f [open io.test r]
+ set l [list [catch {read $f -1} msg] $msg]
+ close $f
+ set l
+} {1 {bad argument "-1": should be "nonewline"}}
+test io-10.4 {Tcl_Read, positive byte count} {
+ set f [open io.test r]
+ set x [read $f 1024]
+ set s [string length $x]
+ unset x
+ close $f
+ set s
+} 1024
+test io-10.5 {Tcl_Read, multiple buffers} {
+ set f [open io.test r]
+ fconfigure $f -buffersize 100
+ set x [read $f 1024]
+ set s [string length $x]
+ unset x
+ close $f
+ set s
+} 1024
+test io-10.6 {Tcl_Read, very large read} {
+ set f1 [open io.test r]
+ set z [read $f1 1000000]
+ close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size io.test]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-10.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open io.test 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-10.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+ set f1 [open io.test r]
+ fconfigure $f1 -blocking off
+ set z [read $f1 1000000]
+ close $f1
+ set x ok
+ set l [string length $z]]
+ set z [file size io.test]]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-10.9 {Tcl_Read, read to end of file} {
+ set f1 [open io.test r]
+ set z [read $f1]
+ close $f1
+ set l [string length $z]
+ set x ok
+ set z [file size io.test]
+ if {$z != $l} {
+ set x broken
+ }
+ set x
+} ok
+test io-10.10 {Tcl_Read from a pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|$tcltest pipe" r+]
+ puts $f1 hello
+ flush $f1
+ set x [read $f1]
+ close $f1
+ set x
+} "hello\n"
+test io-10.11 {Tcl_Read from a pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {puts [gets stdin]}
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|$tcltest 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-10.12 {Tcl_Read, -nonewline} {
+ removeFile test1
+ set f1 [open test1 w]
+ puts $f1 hello
+ puts $f1 bye
+ close $f1
+ set f1 [open test1 r]
+ set c [read -nonewline $f1]
+ close $f1
+ set c
+} {hello
+bye}
+test io-10.13 {Tcl_Read, -nonewline} {
+ removeFile test1
+ set f1 [open test1 w]
+ puts $f1 hello
+ puts $f1 bye
+ close $f1
+ set f1 [open test1 r]
+ set c [read -nonewline $f1]
+ close $f1
+ list [string length $c] $c
+} {9 {hello
+bye}}
+test io-10.14 {Tcl_Read, reading in small chunks} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open 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-10.15 {Tcl_Read, asking for more input than available} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open test1]
+ set x [read $f 100]
+ close $f
+ set x
+} {Two lines: this one
+and this one
+}
+test io-10.16 {Tcl_Read, read to end of file with -nonewline} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open test1]
+ set x [read -nonewline $f]
+ close $f
+ set x
+} {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test io-11.1 {Tcl_Gets, reading what was written} {
+ removeFile test1
+ set f1 [open test1 w]
+ set y "first line"
+ puts $f1 $y
+ close $f1
+ set f1 [open test1 r]
+ set x [gets $f1]
+ set z ok
+ if {"$x" != "$y"} {
+ set z broken
+ }
+ close $f1
+ set z
+} ok
+test io-11.2 {Tcl_Gets into variable} {
+ set f1 [open io.test 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-11.3 {Tcl_Gets from pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {puts [gets stdin]}
+ close $f1
+ set f1 [open "|$tcltest 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-11.4 {Tcl_Gets with long line} {
+ removeFile test3
+ set f [open 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 test3]
+ set x [gets $f]
+ close $f
+ set x
+} {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-11.5 {Tcl_Gets with long line} {
+ set f [open test3]
+ set x [gets $f y]
+ close $f
+ list $x $y
+} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-11.6 {Tcl_Gets and end of file} {
+ removeFile test3
+ set f [open test3 w]
+ puts -nonewline $f "Test1\nTest2"
+ close $f
+ set f [open 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-11.7 {Tcl_Gets and bad variable} {
+ set f [open test3 w]
+ puts $f "Line 1"
+ puts $f "Line 2"
+ close $f
+ catch {unset x}
+ set x 24
+ set f [open 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-11.8 {Tcl_Gets, exercising double buffering} {
+ set f [open 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 test3 r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 100} {incr y} {gets $f}
+ close $f
+ set y
+} 100
+test io-11.9 {Tcl_Gets, exercising double buffering} {
+ set f [open 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 test3 r]
+ fconfigure $f -translation lf
+ for {set y 0} {$y < 200} {incr y} {gets $f}
+ close $f
+ set y
+} 200
+test io-11.10 {Tcl_Gets, exercising double buffering} {
+ set f [open 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 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-12.1 {Tcl_Seek to current position at start of file} {
+ set f1 [open io.test r]
+ seek $f1 0 current
+ set c [tell $f1]
+ close $f1
+ set c
+} 0
+test io-12.2 {Tcl_Seek to offset from start} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open test1 r]
+ seek $f1 10 start
+ set c [tell $f1]
+ close $f1
+ set c
+} 10
+test io-12.3 {Tcl_Seek to end of file} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open test1 r]
+ seek $f1 0 end
+ set c [tell $f1]
+ close $f1
+ set c
+} 54
+test io-12.4 {Tcl_Seek to offset from end of file} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open test1 r]
+ seek $f1 -10 end
+ set c [tell $f1]
+ close $f1
+ set c
+} 44
+test io-12.5 {Tcl_Seek to offset from current position} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open test1 r]
+ seek $f1 10 current
+ seek $f1 10 current
+ set c [tell $f1]
+ close $f1
+ set c
+} 20
+test io-12.6 {Tcl_Seek to offset from end of file} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open test1 r]
+ seek $f1 -10 end
+ set c [tell $f1]
+ set r [read $f1]
+ close $f1
+ list $c $r
+} {44 {rstuvwxyz
+}}
+test io-12.7 {Tcl_Seek to offset from end of file, then to current position} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open 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-12.8 {Tcl_Seek on pipes: not supported} {unixOrPc} {
+ set f1 [open "|$tcltest" 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-12.9 {Tcl_Seek, testing buffered input flushing} {
+ removeFile test3
+ set f [open test3 w]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ close $f
+ set f [open 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}
+test io-12.10 {Tcl_Seek testing flushing of buffered input} {
+ set f [open test3 w]
+ fconfigure $f -translation lf
+ puts $f xyz\n123
+ close $f
+ set f [open 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-12.11 {Tcl_Seek testing flushing of buffered output} {
+ set f [open test3 w]
+ puts $f xyz\n123
+ close $f
+ set f [open test3 w+]
+ puts $f xyzzy
+ seek $f 2
+ set x [gets $f]
+ close $f
+ list $x [viewFile test3]
+} "zzy xyzzy"
+test io-12.12 {Tcl_Seek testing combination of write, seek back and read} {
+ set f [open test3 w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyz\n123
+ close $f
+ set f [open 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-12.13 {Tcl_Tell at start of file} {
+ removeFile test1
+ set f1 [open test1 w]
+ set p [tell $f1]
+ close $f1
+ set p
+} 0
+test io-12.14 {Tcl_Tell after seek to end of file} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open test1 r]
+ seek $f1 0 end
+ set c1 [tell $f1]
+ close $f1
+ set c1
+} 54
+test io-12.15 {Tcl_Tell combined with seeking} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ puts $f1 "abcdefghijklmnopqrstuvwxyz"
+ close $f1
+ set f1 [open 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-12.16 {Tcl_tell on pipe: always -1} {unixOrPc} {
+ set f1 [open "|$tcltest" r+]
+ set c [tell $f1]
+ close $f1
+ set c
+} -1
+test io-12.17 {Tcl_Tell on pipe: always -1} {unixOrPc} {
+ set f1 [open "|$tcltest" r+]
+ puts $f1 {puts hello}
+ flush $f1
+ set c [tell $f1]
+ gets $f1
+ close $f1
+ set c
+} -1
+test io-12.18 {Tcl_Tell combined with seeking and reading} {
+ removeFile test2
+ set f [open test2 w]
+ fconfigure $f -translation lf -eofchar {}
+ puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+ close $f
+ set f [open 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-12.19 {Tcl_Tell combined with opening in append mode} {
+ set f [open test3 w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ puts $f "abcdefghijklmnopqrstuvwxyz"
+ close $f
+ set f [open test3 a]
+ set c [tell $f]
+ close $f
+ set c
+} 54
+test io-12.20 {Tcl_Tell combined with writing} {
+ set f [open 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 Tcl_Eof
+
+test io-13.1 {Tcl_Eof} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f hello
+ puts $f hello
+ close $f
+ set f [open 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-13.2 {Tcl_Eof with pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {gets stdin}
+ puts $f1 {puts hello}
+ close $f1
+ set f1 [open "|$tcltest 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-13.3 {Tcl_Eof with pipe} {unixOrPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {gets stdin}
+ puts $f1 {puts hello}
+ close $f1
+ set f1 [open "|$tcltest 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-13.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ fconfigure $f -blocking off
+ set l ""
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {{} 1}
+test io-13.5 {Tcl_Eof, eof detection on nonblocking pipe} {unixOrPc} {
+ removeFile pipe
+ set f [open pipe w]
+ puts $f {
+ exit
+ }
+ close $f
+ set f [open "|$tcltest pipe" r]
+ set l ""
+ lappend l [gets $f]
+ lappend l [eof $f]
+ close $f
+ set l
+} {{} 1}
+test io-13.6 {Tcl_Eof, eof char, lf write, auto read} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size test1]
+ set f [open 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-13.7 {Tcl_Eof, eof char, lf write, lf read} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size test1]
+ set f [open 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-13.8 {Tcl_Eof, eof char, cr write, auto read} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size test1]
+ set f [open 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-13.9 {Tcl_Eof, eof char, cr write, cr read} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size test1]
+ set f [open 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-13.10 {Tcl_Eof, eof char, crlf write, auto read} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size test1]
+ set f [open 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-13.11 {Tcl_Eof, eof char, crlf write, crlf read} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf -eofchar \x1a
+ puts $f abc\ndef
+ close $f
+ set s [file size test1]
+ set f [open 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-13.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
+ removeFile test1
+ set f [open 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 test1]
+ set f [open 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-13.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
+ removeFile test1
+ set f [open 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 test1]
+ set f [open 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-13.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
+ removeFile test1
+ set f [open 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 test1]
+ set f [open 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-13.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
+ removeFile test1
+ set f [open 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 test1]
+ set f [open 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-13.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
+ removeFile test1
+ set f [open 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 test1]
+ set f [open 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-13.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
+ removeFile test1
+ set f [open 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 test1]
+ set f [open 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-14.1 {Tcl_InputBlocked on nonblocking pipe} {unixOrPc tempNotPc} {
+ set f1 [open "|$tcltest" 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-14.2 {Tcl_InputBlocked on blocking pipe} {unixOrPc tempNotPc} {
+ set f1 [open "|$tcltest" 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-14.3 {Tcl_InputBlocked vs files, short read} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open 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-14.4 {Tcl_InputBlocked vs files, event driven read} {
+ proc in {f} {
+ global l
+ lappend l [read $f 3]
+ if {[eof $f]} {lappend l eof; close $f}
+ }
+ removeFile test1
+ set f [open test1 w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open test1 r]
+ set l ""
+ fileevent $f readable [list in $f]
+ update
+ set l
+} {abc def ghi jkl mno {p
+} eof}
+test io-14.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open 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-14.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles} {
+ proc in {f} {
+ global l
+ lappend l [read $f 3]
+ if {[eof $f]} {lappend l eof; close $f}
+ }
+ removeFile test1
+ set f [open test1 w]
+ puts $f abcdefghijklmnop
+ close $f
+ set f [open test1 r]
+ fconfigure $f -blocking off
+ set l ""
+ fileevent $f readable [list in $f]
+ update
+ set l
+} {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test io-15.1 {Tcl_InputBuffered} {
+ set f [open io.test 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-15.2 {Tcl_InputBuffered, test input flushing on seek} {
+ set f [open io.test 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-16.1 {Tcl_GetChannelBufferSize, default buffer size} {
+ set f [open io.test r]
+ set s [fconfigure $f -buffersize]
+ close $f
+ set s
+} 4096
+test io-16.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
+ set f [open io.test 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 4096 4096 4096 100000 4096}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test io-17.1 {Tcl_GetChannelOption} {
+ removeFile test1
+ set f1 [open test1 w]
+ set x [fconfigure $f1 -blocking]
+ close $f1
+ set x
+} 1
+#
+# Test 17.2 was removed.
+#
+test io-17.3 {Tcl_GetChannelOption} {
+ removeFile test1
+ set f1 [open test1 w]
+ set x [fconfigure $f1 -buffering]
+ close $f1
+ set x
+} full
+test io-17.4 {Tcl_GetChannelOption} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -buffering line
+ set x [fconfigure $f1 -buffering]
+ close $f1
+ set x
+} line
+test io-17.5 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
+ removeFile test1
+ set f1 [open 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-17.6 {Tcl_GetChannelOption, invariance} {
+ removeFile test1
+ set f1 [open 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-17.7 {Tcl_SetChannelOption, multiple options} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -buffering line
+ puts $f1 hello
+ puts $f1 bye
+ set x [file size test1]
+ close $f1
+ set x
+} 10
+test io-17.8 {Tcl_SetChannelOption, buffering, translation} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf
+ puts $f1 hello
+ puts $f1 bye
+ set x ""
+ fconfigure $f1 -buffering line
+ lappend x [file size test1]
+ puts $f1 really_bye
+ lappend x [file size test1]
+ close $f1
+ set x
+} {0 21}
+test io-17.9 {Tcl_SetChannelOption, different buffering options} {
+ removeFile test1
+ set f1 [open test1 w]
+ set l ""
+ fconfigure $f1 -translation lf -buffering none -eofchar {}
+ puts -nonewline $f1 hello
+ lappend l [file size test1]
+ puts -nonewline $f1 hello
+ lappend l [file size test1]
+ fconfigure $f1 -buffering full
+ puts -nonewline $f1 hello
+ lappend l [file size test1]
+ fconfigure $f1 -buffering none
+ lappend l [file size test1]
+ puts -nonewline $f1 hello
+ lappend l [file size test1]
+ close $f1
+ lappend l [file size test1]
+ set l
+} {5 10 10 10 20 20}
+test io-17.10 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
+ removeFile test1
+ set f1 [open test1 w]
+ close $f1
+ set f1 [open 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-17.11 {Tcl_SetChannelOption, blocking mode} {unixOrPc tempNotPc} {
+ removeFile pipe
+ set f1 [open pipe w]
+ puts $f1 {gets stdin}
+ puts $f1 {after 100}
+ puts $f1 {puts hi}
+ puts $f1 {gets stdin}
+ close $f1
+ set x ""
+ set f1 [open "|$tcltest pipe" r+]
+ fconfigure $f1 -blocking off -buffering line
+ lappend x [fconfigure $f1 -blocking]
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ puts $f1 hello
+ lappend x [gets $f1]
+ lappend x [fblocked $f1]
+ puts $f1 bye
+ 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-17.12 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -buffersize -10
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 4096
+test io-17.13 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -buffersize 10000000
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 4096
+test io-17.14 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -buffersize 40000
+ set x [fconfigure $f -buffersize]
+ close $f
+ set x
+} 40000
+
+test io-18.1 {POSIX open access modes: RDWR} {
+ removeFile test3
+ set f [open test3 w]
+ puts $f xyzzy
+ close $f
+ set f [open test3 RDWR]
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [gets $f]
+ close $f
+ set f [open test3 r]
+ lappend x [gets $f]
+ close $f
+ set x
+} {zzy abzzy}
+test io-18.2 {POSIX open access modes: CREAT} {unixOnly} {
+ removeFile test3
+ set f [open test3 {WRONLY CREAT} 0600]
+ file stat test3 stats
+ set x [format "0%o" [expr $stats(mode)&0777]]
+ puts $f "line 1"
+ close $f
+ set f [open test3 r]
+ lappend x [gets $f]
+ close $f
+ set x
+} {0600 {line 1}}
+test io-18.3 {POSIX open access modes: CREAT} {unixOnly nonPortable} {
+ # This test only works if your umask is 2, like ouster's.
+ removeFile test3
+ set f [open test3 {WRONLY CREAT}]
+ close $f
+ file stat test3 stats
+ format "0%o" [expr $stats(mode)&0777]
+} 0664
+test io-18.4 {POSIX open access modes: CREAT} {
+ removeFile test3
+ set f [open test3 w]
+ fconfigure $f -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open test3 {WRONLY CREAT}]
+ fconfigure $f -eofchar {}
+ puts -nonewline $f "ab"
+ close $f
+ set f [open test3 r]
+ set x [gets $f]
+ close $f
+ set x
+} abzzy
+test io-18.5 {POSIX open access modes: APPEND} {
+ removeFile test3
+ set f [open test3 w]
+ fconfigure $f -translation lf -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open test3 {WRONLY APPEND}]
+ fconfigure $f -translation lf
+ puts $f "new line"
+ seek $f 0
+ puts $f "abc"
+ close $f
+ set f [open 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-18.6 {POSIX open access modes: EXCL} {
+ removeFile test3
+ set f [open test3 w]
+ puts $f xyzzy
+ close $f
+ set msg [list [catch {open test3 {WRONLY CREAT EXCL}} msg] $msg]
+ regsub " already " $msg " " msg
+ string tolower $msg
+} {1 {couldn't open "test3": file exists}}
+test io-18.7 {POSIX open access modes: EXCL} {
+ removeFile test3
+ set f [open test3 {WRONLY CREAT EXCL}]
+ fconfigure $f -eofchar {}
+ puts $f "A test line"
+ close $f
+ viewFile test3
+} {A test line}
+test io-18.8 {POSIX open access modes: TRUNC} {
+ removeFile test3
+ set f [open test3 w]
+ puts $f xyzzy
+ close $f
+ set f [open test3 {WRONLY TRUNC}]
+ puts $f abc
+ close $f
+ set f [open test3 r]
+ set x [gets $f]
+ close $f
+ set x
+} abc
+test io-18.9 {POSIX open access modes: NONBLOCK} {nonPortable} {
+ removeFile test3
+ set f [open test3 {WRONLY NONBLOCK CREAT}]
+ puts $f "NONBLOCK test"
+ close $f
+ set f [open test3 r]
+ set x [gets $f]
+ close $f
+ set x
+} {NONBLOCK test}
+test io-18.10 {POSIX open access modes: RDONLY} {
+ set f [open test1 w]
+ puts $f "two lines: this one"
+ puts $f "and this"
+ close $f
+ set f [open 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-18.11 {POSIX open access modes: RDONLY} {
+ removeFile test3
+ string tolower [list [catch {open test3 RDONLY} msg] $msg]
+} {1 {couldn't open "test3": no such file or directory}}
+test io-18.12 {POSIX open access modes: WRONLY} {
+ removeFile test3
+ string tolower [list [catch {open test3 WRONLY} msg] $msg]
+} {1 {couldn't open "test3": no such file or directory}}
+test io-18.13 {POSIX open access modes: WRONLY} {
+ makeFile xyzzy test3
+ set f [open 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-18.14 {POSIX open access modes: RDWR} {
+ removeFile test3
+ string tolower [list [catch {open test3 RDWR} msg] $msg]
+} {1 {couldn't open "test3": no such file or directory}}
+test io-18.15 {POSIX open access modes: RDWR} {
+ makeFile xyzzy test3
+ set f [open test3 RDWR]
+ puts -nonewline $f "ab"
+ seek $f 0 current
+ set x [gets $f]
+ close $f
+ lappend x [viewFile test3]
+} {zzy abzzy}
+if {![file exists ~/_test_] && [file writable ~]} {
+ test io-18.16 {tilde substitution in open} {
+ set f [open ~/_test_ w]
+ puts $f "Some text"
+ close $f
+ set x [file exists [file join $env(HOME) _test_]]
+ removeFile [file join $env(HOME) _test_]
+ set x
+ } 1
+}
+test io-18.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-19.1 {Tcl_FileeventCmd: errors} {
+ list [catch {fileevent foo} msg] $msg
+} {1 {wrong # args: must be "fileevent channelId event ?script?}}
+test io-19.2 {Tcl_FileeventCmd: errors} {
+ list [catch {fileevent foo bar baz q} msg] $msg
+} {1 {wrong # args: must be "fileevent channelId event ?script?}}
+test io-19.3 {Tcl_FileeventCmd: errors} {
+ list [catch {fileevent gorp readable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-19.4 {Tcl_FileeventCmd: errors} {
+ list [catch {fileevent gorp writable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-19.5 {Tcl_FileeventCmd: errors} {
+ 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 f [open foo w+]
+
+test io-20.1 {Tcl_FileeventCmd: creating, deleting, querying} {
+ list [fileevent $f readable] [fileevent $f writable]
+} {{} {}}
+test io-20.2 {Tcl_FileeventCmd: replacing} {
+ 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 fileevent on a pipe
+#
+
+if {($tcl_platform(platform) != "macintosh") && \
+ ($testConfig(unixExecs) == 1)} {
+
+catch {set f2 [open {|cat -u} r+]}
+catch {set f3 [open {|cat -u} r+]}
+
+test io-21.1 {Tcl_FileeventCmd: creating, deleting, querying} {
+ 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-21.2 {Tcl_FileeventCmd: deleting when many present} {
+ 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]
+} {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}
+
+test io-22.1 {FileEventProc procedure: normal read event} {
+ fileevent $f2 readable {
+ set x [gets $f2]; fileevent $f2 readable {}
+ }
+ puts $f2 text; flush $f2
+ after 200
+ set x initial
+ update
+ set x
+} {text}
+test io-22.2 {FileEventProc procedure: error in read event} {
+ proc bgerror args {
+ global x
+ set x $args
+ }
+ fileevent $f2 readable {error bogus}
+ puts $f2 text; flush $f2
+ after 200
+ set x initial
+ update
+ rename bgerror {}
+ list $x [fileevent $f2 readable]
+} {bogus {}}
+test io-22.3 {FileEventProc procedure: normal write event} {
+ fileevent $f2 writable {
+ lappend x "triggered"
+ incr count -1
+ if {$count <= 0} {
+ fileevent $f2 writable {}
+ }
+ }
+ set x initial
+ set count 3
+ update
+ set x
+} {initial triggered triggered triggered}
+test io-22.4 {FileEventProc procedure: eror in write event} {
+ proc bgerror args {
+ global x
+ set x $args
+ }
+ fileevent $f2 writable {error bad-write}
+ set x initial
+ update
+ rename bgerror {}
+ list $x [fileevent $f2 writable]
+} {bad-write {}}
+test io-22.5 {FileEventProc procedure: end of file} {unixOrPc unixExecs} {
+ set f4 [open {|cat << foo} r]
+ fileevent $f4 readable {
+ if {[gets $f4 line] < 0} {
+ lappend x eof
+ fileevent $f4 readable {}
+ } else {
+ lappend x $line
+ }
+ }
+ after 200
+ set x initial
+ update
+ close $f4
+ set x
+} {initial foo eof}
+
+catch {close $f2}
+catch {close $f3}
+
+} # Closes if {($platform(platform) != "macintosh") && \
+ # ($testConfig(unixExecs) == 1)} clause
+
+close $f
+makeFile "foo bar" foo
+test io-23.1 {DeleteFileEvent, cleanup on close} {
+ set f [open foo r]
+ fileevent $f readable {
+ lappend x "binding triggered: \"[gets $f]\""
+ fileevent $f readable {}
+ }
+ close $f
+ set x initial
+ update
+ set x
+} {initial}
+test io-23.2 {DeleteFileEvent, cleanup on close} {
+ set f [open foo r]
+ set f2 [open foo r]
+ fileevent $f readable {
+ lappend x "f triggered: \"[gets $f]\""
+ fileevent $f readable {}
+ }
+ fileevent $f2 readable {
+ lappend x "f2 triggered: \"[gets $f2]\""
+ fileevent $f2 readable {}
+ }
+ close $f
+ set x initial
+ update
+ close $f2
+ set x
+} {initial {f2 triggered: "foo bar"}}
+
+test io-23.3 {DeleteFileEvent, cleanup on close} {
+ set f [open foo r]
+ set f2 [open foo r]
+ set f3 [open 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}
+
+if {[info commands testfevent] == ""} {
+ break
+}
+
+test io-24.1 {Tcl event loop vs multiple interpreters} {
+ testfevent create
+ testfevent cmd {
+ set f [open foo r]
+ set x "no event"
+ fileevent $f readable {
+ set x "f triggered: [gets $f]"
+ fileevent $f readable {}
+ }
+ }
+ update
+ testfevent cmd {close $f}
+ list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test io-24.2 {Tcl event loop vs multiple interpreters} {
+ testfevent create
+ testfevent cmd {
+ set x 0
+ after 100 {set x triggered}
+ vwait x
+ set x
+ }
+} {triggered}
+test io-24.3 {Tcl event loop vs multiple interpreters} {
+ 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-25.1 {fileevent vs multiple interpreters} {
+ set f [open foo r]
+ set f2 [open foo r]
+ set f3 [open 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-25.2 {deleting fileevent on interpreter delete} {
+ set f [open foo r]
+ set f2 [open foo r]
+ set f3 [open foo r]
+ set f4 [open 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-25.3 {deleting fileevent on interpreter delete} {
+ set f [open foo r]
+ set f2 [open foo r]
+ set f3 [open foo r]
+ set f4 [open 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-25.4 {file events on shared files and multiple interpreters} {
+ set f [open foo r]
+ set f2 [open 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-25.5 {file events on shared files, deleting file events} {
+ set f [open 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-25.6 {file events on shared files, deleting file events} {
+ set f [open 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} {}}
+
+test io-26.1 {testing readability conditions} {
+ set f [open bar w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open bar r]
+ fileevent $f readable [list consume $f]
+ proc consume {f} {
+ global x l
+ lappend l called
+ if {[eof $f]} {
+ close $f
+ set x done
+ } else {
+ gets $f
+ }
+ }
+ set l ""
+ set x not_done
+ vwait x
+ list $x $l
+} {done {called called called called called called called}}
+test io-26.2 {testing readability conditions} {nonBlockFiles} {
+ set f [open bar w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open bar r]
+ fileevent $f readable [list consume $f]
+ fconfigure $f -blocking off
+ proc consume {f} {
+ global x l
+ lappend l called
+ if {[eof $f]} {
+ close $f
+ set x done
+ } else {
+ gets $f
+ }
+ }
+ set l ""
+ set x not_done
+ vwait x
+ list $x $l
+} {done {called called called called called called called}}
+test io-26.3 {testing readability conditions} {unixOnly nonBlockFiles} {
+ set f [open bar w]
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ puts $f abcdefg
+ close $f
+ set f [open my_script w]
+ puts $f {
+ proc copy_slowly {f} {
+ while {![eof $f]} {
+ puts [gets $f]
+ after 200
+ }
+ close $f
+ }
+ }
+ close $f
+ set f [open |$tcltest r+]
+ fileevent $f readable [list consume $f]
+ fconfigure $f -buffering line
+ fconfigure $f -blocking off
+ proc consume {f} {
+ global x l
+ if {[eof $f]} {
+ set x done
+ } else {
+ gets $f
+ lappend l [fblocked $f]
+ gets $f
+ lappend l [fblocked $f]
+ }
+ }
+ set l ""
+ set x not_done
+ puts $f {source my_script}
+ puts $f {set f [open bar r]}
+ puts $f {copy_slowly $f}
+ puts $f {exit}
+ vwait x
+ close $f
+ list $x $l
+} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test io-26.4 {lf write, testing readability, ^Z termination, auto read mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.5 {lf write, testing readability, ^Z in middle, auto read mode} {
+ removeFile test1
+ set f [open 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} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.6 {cr write, testing readability, ^Z termination, auto read mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.7 {cr write, testing readability, ^Z in middle, auto read mode} {
+ removeFile test1
+ set f [open 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} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.8 {crlf write, testing readability, ^Z termination, auto read mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -translation auto -eofchar \x1a
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.9 {crlf write, testing readability, ^Z in middle, auto read mode} {
+ removeFile test1
+ set f [open 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} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation auto
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.10 {lf write, testing readability, ^Z in middle, lf read mode} {
+ removeFile test1
+ set f [open 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} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation lf
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.11 {lf write, testing readability, ^Z termination, lf read mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation lf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -translation lf -eofchar \x1a
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.12 {cr write, testing readability, ^Z in middle, cr read mode} {
+ removeFile test1
+ set f [open 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} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation cr
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.13 {cr write, testing readability, ^Z termination, cr read mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation cr
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -translation cr -eofchar \x1a
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {
+ removeFile test1
+ set f [open 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} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -eofchar \x1a -translation crlf
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+test io-26.15 {crlf write, testing readability, ^Z termi, crlf read mode} {
+ removeFile test1
+ set f [open test1 w]
+ fconfigure $f -translation crlf
+ set c [format "abc\ndef\n%c" 26]
+ puts -nonewline $f $c
+ close $f
+ proc consume {f} {
+ global c x l
+ if {[eof $f]} {
+ set x done
+ close $f
+ } else {
+ lappend l [gets $f]
+ incr c
+ }
+ }
+ set c 0
+ set l ""
+ set f [open test1 r]
+ fconfigure $f -translation crlf -eofchar \x1a
+ fileevent $f readable [list consume $f]
+ vwait x
+ list $c $l
+} {3 {abc def {}}}
+
+test io-27.1 {testing handler deletion} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ testchannelevent $f add readable [list delhandler $f]
+ proc delhandler {f} {
+ global z
+ set z called
+ testchannelevent $f delete 0
+ }
+ set z not_called
+ update
+ close $f
+ set z
+} called
+test io-27.2 {testing handler deletion with multiple handlers} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ testchannelevent $f add readable [list delhandler $f 1]
+ testchannelevent $f add readable [list delhandler $f 0]
+ proc delhandler {f i} {
+ global 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-27.3 {testing handler deletion with multiple handlers} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ testchannelevent $f add readable [list notcalled $f 1]
+ testchannelevent $f add readable [list delhandler $f 0]
+ set z ""
+ proc notcalled {f i} {
+ global z
+ lappend z "notcalled was called!! $f $i"
+ }
+ proc delhandler {f i} {
+ global 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-27.4 {testing handler deletion vs reentrant calls} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ testchannelevent $f add readable [list delrecursive $f]
+ proc delrecursive {f} {
+ global z u
+ if {"$u" == "recursive"} {
+ testchannelevent $f delete 0
+ lappend z "delrecursive deleting recursive"
+ } else {
+ lappend z "delrecursive calling recursive"
+ set u recursive
+ update
+ }
+ }
+ set u toplevel
+ set z ""
+ update
+ close $f
+ string compare [string tolower $z] \
+ {{delrecursive calling recursive} {delrecursive deleting recursive}}
+} 0
+test io-27.5 {testing handler deletion vs reentrant calls} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ testchannelevent $f add readable [list notcalled $f]
+ testchannelevent $f add readable [list del $f]
+ proc notcalled {f} {
+ global z
+ lappend z "notcalled was called!! $f"
+ }
+ proc del {f} {
+ global z u
+ 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-27.6 {testing handler deletion vs reentrant calls} {
+ removeFile test1
+ set f [open test1 w]
+ close $f
+ set f [open test1 r]
+ testchannelevent $f add readable [list second $f]
+ testchannelevent $f add readable [list first $f]
+ proc first {f} {
+ global u 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} {
+ global u 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
+
+removeFile script
+removeFile output
+removeFile test1
+removeFile pipe
+removeFile my_script
+removeFile foo
+removeFile bar
+
+set x ""
+unset x
diff --git a/contrib/tcl/tests/ioCmd.test b/contrib/tcl/tests/ioCmd.test
new file mode 100644
index 0000000..18eb5ec
--- /dev/null
+++ b/contrib/tcl/tests/ioCmd.test
@@ -0,0 +1,394 @@
+# Commands covered: open, close, gets, read, puts, seek, tell, eof, flush,
+# fblocked, fconfigure, open, channel
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# "@(#) iocmd.test 1.37 96/04/12 11:44:23"
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+removeFile test1
+removeFile pipe
+
+set executable [list [info nameofexecutable]]
+
+#test iocmd-1.0 {copyfile command} {
+# list [catch {copyfile a b c d e f} msg] $msg
+#} {1 {wrong # args: should be "copyfile inChanId outChanId ?chunkSize?"}}
+#test iocmd-1.1 {copyfile command} {
+# list [catch {copyfile f1} msg] $msg
+#} {1 {wrong # args: should be "copyfile inChanId outChanId ?chunkSize?"}}
+#test iocmd-1.2 {copyfile command} {
+# list [catch {copyfile f1 f2} msg] $msg
+#} {1 {can not find channel named "f1"}}
+#test iocmd-1.3 {copyfile command} {
+# list [catch {copyfile stdin f2} msg] $msg
+#} {1 {can not find channel named "f2"}}
+#test iocmd-1.4 {copyfile command} {
+# list [catch {copyfile stdin stdout booboo} msg] $msg
+#} {1 {expected integer but got "booboo"}}
+#test iocmd-1.5 {copyfile command} {
+# list [catch {copyfile stdout stdin} msg] $msg
+#} {1 {channel "stdout" wasn't opened for reading}}
+#test iocmd-1.6 {copyfile command} {
+# list [catch {copyfile stdin stdin} msg] $msg
+#} {1 {channel "stdin" wasn't opened for writing}}
+
+test iocmd-2.1 {puts command} {
+ list [catch {puts} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-2.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-2.3 {puts command} {
+ list [catch {puts froboz -nonewline kablooie} msg] $msg
+} {1 {bad argument "kablooie": should be "nonewline"}}
+test iocmd-2.4 {puts command} {
+ list [catch {puts froboz hello} msg] $msg
+} {1 {can not find channel named "froboz"}}
+test iocmd-2.5 {puts command} {
+ list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+test iocmd-3.0 {flush command} {
+ list [catch {flush} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-3.1 {flush command} {
+ list [catch {flush a b c d e} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-3.3 {flush command} {
+ list [catch {flush foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-3.4 {flush command} {
+ list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+test iocmd-4.0 {gets command} {
+ list [catch {gets} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-4.1 {gets command} {
+ list [catch {gets a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-4.2 {gets command} {
+ list [catch {gets aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-4.2 {gets command} {
+ list [catch {gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+
+test iocmd-5.0 {read command} {
+ list [catch {read} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"}}
+test iocmd-5.1 {read command} {
+ list [catch {read a b c d e f g h} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"}}
+test iocmd-5.2 {read command} {
+ list [catch {read aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-5.3 {read command} {
+ list [catch {read -nonewline} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"}}
+test iocmd-5.4 {read command} {
+ list [catch {read -nonew file4} msg] $msg $errorCode
+} {1 {can not find channel named "-nonew"} NONE}
+test iocmd-5.5 {read command} {
+ list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-5.6 {read command} {
+ list [catch {read -nonewline stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-5.23 {read command with incorrect combination of arguments} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open test1]
+ set x [list [catch {read -nonewline $f 20 z} msg] $msg $errorCode]
+ close $f
+ set x
+} {1 {wrong # args: should be "read channelId ?numBytes?" or "read ?-nonewline? channelId"} NONE}
+test iocmd-5.24 {read command} {
+ list [catch {read stdin foo} msg] $msg $errorCode
+} {1 {bad argument "foo": should be "nonewline"} NONE}
+test iocmd-5.25 {read command} {
+ list [catch {read file107} msg] $msg $errorCode
+} {1 {can not find channel named "file107"} NONE}
+test iocmd-5.26 {read command} {
+ set f [open 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-5.27 {read command} {
+ set f [open test1]
+ set x [list [catch {read $f 12z} msg] $msg $errorCode]
+ close $f
+ set x
+} {1 {expected integer but got "12z"} NONE}
+
+test iocmd-6.0 {seek command} {
+ list [catch {seek} msg] $msg
+} {1 {wrong # args: should be "seek channelId offset ?origin?"}}
+test iocmd-6.1 {seek command} {
+ list [catch {seek a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "seek channelId offset ?origin?"}}
+test iocmd-6.2 {seek command} {
+ list [catch {seek stdin gugu} msg] $msg
+} {1 {expected integer but got "gugu"}}
+test iocmd-6.3 {seek command} {
+ list [catch {seek stdin 100 gugu} msg] $msg
+} {1 {bad origin "gugu": should be start, current, or end}}
+
+test iocmd-7.0 {tell command} {
+ list [catch {tell} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-7.1 {tell command} {
+ list [catch {tell a b c d e} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-7.2 {tell command} {
+ list [catch {tell aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+
+test iocmd-8.0 {close command} {
+ list [catch {close} msg] $msg
+} {1 {wrong # args: should be "close channelId"}}
+test iocmd-8.1 {close command} {
+ list [catch {close a b c d e} msg] $msg
+} {1 {wrong # args: should be "close channelId"}}
+test iocmd-8.2 {close command} {
+ list [catch {close aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+
+test iocmd-9.0 {fconfigure command} {
+ list [catch {fconfigure} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?optionName? ?value? ?optionName value?..."}}
+test iocmd-9.1 {fconfigure command} {
+ list [catch {fconfigure a b c d e f} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?optionName? ?value? ?optionName value?..."}}
+test iocmd-9.2 {fconfigure command} {
+ list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+test iocmd-9.3 {fconfigure command} {
+ removeFile test1
+ set f1 [open test1 w]
+ set x [list [catch {fconfigure $f1 froboz} msg] $msg]
+ close $f1
+ set x
+} {1 {bad option "froboz": must be -blocking, -buffering, -buffersize, -eofchar, -translation, or a channel type specific option}}
+test iocmd-9.4 {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-9.4 {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-9.5 {fconfigure command} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -eofchar {}
+ set x [fconfigure $f1]
+ close $f1
+ set x
+} {-blocking 1 -buffering full -buffersize 4096 -eofchar {} -translation lf}
+test iocmd-9.6 {fconfigure command} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
+ -eofchar {}
+ set x ""
+ lappend x [fconfigure $f1 -buffering]
+ lappend x [fconfigure $f1]
+ close $f1
+ set x
+} {line {-blocking 1 -buffering line -buffersize 3030 -eofchar {} -translation lf}}
+test iocmd-9.7 {fconfigure command} {
+ removeFile test1
+ set f1 [open test1 w]
+ fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
+ -eofchar {}
+ set x [fconfigure $f1]
+ close $f1
+ set x
+} {-blocking 1 -buffering none -buffersize 4040 -eofchar {} -translation lf}
+test iocmd-9.8 {fconfigure command} {
+ list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+test iocmd-9.9 {fconfigure command} {
+ list [catch {fconfigure stdout -froboz blarfo} msg] $msg
+} {1 {bad option "-froboz": should be -blocking, -buffering, -buffersize, -eofchar, -translation, or channel type specific option}}
+test iocmd-9.10 {fconfigure command} {
+ list [catch {fconfigure stdout -b blarfo} msg] $msg
+} {1 {bad option "-b": should be -blocking, -buffering, -buffersize, -eofchar, -translation, or channel type specific option}}
+test iocmd-9.11 {fconfigure command} {
+ list [catch {fconfigure stdout -buffer blarfo} msg] $msg
+} {1 {bad option "-buffer": should be -blocking, -buffering, -buffersize, -eofchar, -translation, or channel type specific option}}
+test iocmd-9.12 {fconfigure command} {
+ fconfigure stdin -buffers
+} 4096
+
+test iocmd-10.1 {eof command} {
+ list [catch {eof} msg] $msg $errorCode
+} {1 {wrong # args: should be "eof channelId"} NONE}
+test iocmd-10.2 {eof command} {
+ list [catch {eof a b} msg] $msg $errorCode
+} {1 {wrong # args: should be "eof channelId"} NONE}
+test iocmd-10.3 {eof command} {
+ catch {close file100}
+ list [catch {eof file100} msg] $msg $errorCode
+} {1 {can not find channel named "file100"} NONE}
+
+test iocmd-11.0 {fblocked command} {
+ list [catch {fblocked} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-11.1 {fblocked command} {
+ list [catch {fblocked a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-11.2 {fblocked command} {
+ list [catch {fblocked file1000} msg] $msg
+} {1 {can not find channel named "file1000"}}
+test iocmd-11.3 {fblocked command} {
+ list [catch {fblocked stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-11.4 {fblocked command} {
+ fblocked stdin
+} 0
+
+test iocmd-12.1 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| cat < test1 > test3" w} msg] $msg $errorCode
+} {1 {can't write input to command: standard input was redirected} NONE}
+test iocmd-12.2 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| echo > test3" r} msg] $msg $errorCode
+} {1 {can't read output from command: standard output was redirected} NONE}
+test iocmd-12.3 {I/O to command pipelines} {unixOrPc unixExecs} {
+ list [catch {open "| echo > test3" r+} msg] $msg $errorCode
+} {1 {can't read output from command: standard output was redirected} NONE}
+
+test iocmd-13.1 {POSIX open access modes: RDONLY} {
+ removeFile test1
+ set f [open test1 w]
+ puts $f "Two lines: this one"
+ puts $f "and this one"
+ close $f
+ set f [open 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-13.2 {POSIX open access modes: RDONLY} {
+ removeFile test3
+ string tolower [list [catch {open test3 RDONLY} msg] $msg]
+} {1 {couldn't open "test3": no such file or directory}}
+test iocmd-13.3 {POSIX open access modes: WRONLY} {
+ removeFile test3
+ string tolower [list [catch {open test3 WRONLY} msg] $msg]
+} {1 {couldn't open "test3": no such file or directory}}
+#
+# Test 13.4 relies on assigning the same channel name twice.
+#
+test iocmd-13.4 {POSIX open access modes: WRONLY} {unixOnly} {
+ removeFile test3
+ set f [open test3 w]
+ fconfigure $f -eofchar {}
+ puts $f xyzzy
+ close $f
+ set f [open 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 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-13.5 {POSIX open access modes: RDWR} {
+ removeFile test3
+ string tolower [list [catch {open test3 RDWR} msg] $msg]
+} {1 {couldn't open "test3": no such file or directory}}
+test iocmd-13.15 {POSIX open access modes: errors} {
+ concat [catch {open 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 test3 \"FOO \\{BAR BAZ\"\""
+test iocmd-13.16 {POSIX open access modes: errors} {
+ list [catch {open test3 {FOO BAR BAZ}} msg] $msg
+} {1 {invalid access mode "FOO": must be RDONLY, WRONLY, RDWR, APPEND, CREAT EXCL, NOCTTY, NONBLOCK, or TRUNC}}
+test iocmd-13.17 {POSIX open access modes: errors} {
+ list [catch {open test3 {TRUNC CREAT}} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+
+test iocmd-14.1 {errors in open command} {
+ list [catch {open} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-14.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-14.3 {errors in open command} {
+ list [catch {open test1 x} msg] $msg
+} {1 {illegal access mode "x"}}
+test iocmd-14.4 {errors in open command} {
+ list [catch {open test1 rw} msg] $msg
+} {1 {illegal access mode "rw"}}
+test iocmd-14.5 {errors in open command} {
+ list [catch {open test1 r+1} msg] $msg
+} {1 {illegal access mode "r+1"}}
+test iocmd-14.6 {errors in open command} {
+ string tolower [list [catch {open _non_existent_} msg] $msg $errorCode]
+} {1 {couldn't open "_non_existent_": no such file or directory} {posix enoent {no such file or directory}}}
+
+test iocmd-15.1 {file id parsing errors} {
+ list [catch {eof gorp} msg] $msg $errorCode
+} {1 {can not find channel named "gorp"} NONE}
+test iocmd-15.2 {file id parsing errors} {
+ list [catch {eof filex} msg] $msg
+} {1 {can not find channel named "filex"}}
+test iocmd-15.3 {file id parsing errors} {
+ list [catch {eof file12a} msg] $msg
+} {1 {can not find channel named "file12a"}}
+test iocmd-15.4 {file id parsing errors} {
+ list [catch {eof file123} msg] $msg
+} {1 {can not find channel named "file123"}}
+test iocmd-15.5 {file id parsing errors} {
+ list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-15.6 {file id parsing errors} {
+ list [catch {eof stdin} msg] $msg
+} {0 0}
+test iocmd-15.7 {file id parsing errors} {
+ list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-15.8 {file id parsing errors} {
+ list [catch {eof stderr} msg] $msg
+} {0 0}
+test iocmd-15.9 {file id parsing errors} {
+ list [catch {eof stderr1} msg] $msg
+} {1 {can not find channel named "stderr1"}}
+set f [open test1]
+close $f
+set expect "1 {can not find channel named \"$f\"}"
+test iocmd-15.10 {file id parsing errors} {
+ list [catch {eof $f} msg] $msg
+} $expect
+
+removeFile test1
+removeFile test2
+removeFile test3
+removeFile pipe
+removeFile output
+set x ""
+set x
diff --git a/contrib/tcl/tests/join.test b/contrib/tcl/tests/join.test
new file mode 100644
index 0000000..4023de2
--- /dev/null
+++ b/contrib/tcl/tests/join.test
@@ -0,0 +1,38 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) join.test 1.6 96/02/16 08:56:02
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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?"} NONE}
+test join-2.2 {join errors} {
+ list [catch {join a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} NONE}
+test join-2.3 {join errors} {
+ list [catch {join "a \{ c" 111} msg] $msg $errorCode
+} {1 {unmatched open brace in list} NONE}
diff --git a/contrib/tcl/tests/license.terms b/contrib/tcl/tests/license.terms
new file mode 100644
index 0000000..3dcd816
--- /dev/null
+++ b/contrib/tcl/tests/license.terms
@@ -0,0 +1,32 @@
+This software is copyrighted by the Regents of the University of
+California, Sun Microsystems, Inc., and other parties. The following
+terms apply to all files associated with the software unless explicitly
+disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+RESTRICTED RIGHTS: Use, duplication or disclosure by the government
+is subject to the restrictions as set forth in subparagraph (c) (1) (ii)
+of the Rights in Technical Data and Computer Software Clause as DFARS
+252.227-7013 and FAR 52.227-19.
diff --git a/contrib/tcl/tests/lindex.test b/contrib/tcl/tests/lindex.test
new file mode 100644
index 0000000..66ff3ac
--- /dev/null
+++ b/contrib/tcl/tests/lindex.test
@@ -0,0 +1,74 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) lindex.test 1.5 96/02/16 08:56:03
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test lindex-1.1 {basic tests} {
+ lindex {a b c} 0} a
+test lindex-1.2 {basic tests} {
+ lindex {a {b c d} x} 1} {b c d}
+test lindex-1.3 {basic tests} {
+ lindex {a b\ c\ d x} 1} {b c d}
+test lindex-1.4 {basic tests} {
+ lindex {a b c} 3} {}
+test lindex-1.5 {basic tests} {
+ list [catch {lindex {a b c} -1} msg] $msg
+} {0 {}}
+test lindex-1.6 {basic tests} {
+ lindex {a b c d} end
+} d
+test lindex-1.7 {basic tests} {
+ lindex {a b c d} 100
+} {}
+test lindex-1.8 {basic tests} {
+ lindex {a} e
+} a
+test lindex-1.9 {basic tests} {
+ lindex {} end
+} {}
+test lindex-1.10 {basic tests} {
+ lindex {a b c d} 3
+} d
+
+test lindex-2.1 {error conditions} {
+ list [catch {lindex msg} msg] $msg
+} {1 {wrong # args: should be "lindex list index"}}
+test lindex-2.2 {error conditions} {
+ list [catch {lindex 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "lindex list index"}}
+test lindex-2.3 {error conditions} {
+ list [catch {lindex 1 2a2} msg] $msg
+} {1 {expected integer but got "2a2"}}
+test lindex-2.4 {error conditions} {
+ list [catch {lindex "a \{" 2} msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-2.5 {error conditions} {
+ list [catch {lindex {a {b c}d e} 2} msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-2.6 {error conditions} {
+ list [catch {lindex {a "b c"def ghi} 2} msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-3.1 {quoted elements} {
+ lindex {a "b c" d} 1
+} {b c}
+test lindex-3.2 {quoted elements} {
+ lindex {"{}" b c} 0
+} {{}}
+test lindex-3.3 {quoted elements} {
+ lindex {ab "c d \" x" y} 1
+} {c d " x}
+test lindex-3.4 {quoted elements} {
+ lindex {a b {c d "e} {f g"}} 2
+} {c d "e}
diff --git a/contrib/tcl/tests/link.test b/contrib/tcl/tests/link.test
new file mode 100644
index 0000000..570a6ee
--- /dev/null
+++ b/contrib/tcl/tests/link.test
@@ -0,0 +1,230 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) link.test 1.10 96/02/16 08:56:05
+
+if {[info commands testlink] == {}} {
+ puts "This application hasn't been compiled with the \"testlink\""
+ puts "command, so I can't test Tcl_LinkVar et al."
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+foreach i {int real bool string} {
+ catch {unset $i}
+}
+test link-1.1 {reading C variables from Tcl} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 1 1 1 1
+ list $int $real $bool $string
+} {43 1.23 1 NULL}
+test link-1.2 {reading C variables from Tcl} {
+ testlink delete
+ testlink create 1 1 1 1
+ testlink set -3 2 0 "A long string with spaces"
+ list $int $real $bool $string $int $real $bool $string
+} {-3 2.0 0 {A long string with spaces} -3 2.0 0 {A long string with spaces}}
+
+test link-2.1 {writing C variables from Tcl} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 1 1 1 1
+ set int "00721"
+ set real -8e13
+ set bool true
+ set string abcdef
+ concat [testlink get] $int $real $bool $string
+} {465 -8e+13 1 abcdef 00721 -8e13 true abcdef}
+test link-2.2 {writing bad values into variables} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 1 1 1 1
+ list [catch {set int 09a} msg] $msg $int
+} {1 {can't set "int": variable must have integer value} 43}
+test link-2.3 {writing bad values into variables} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 1 1 1 1
+ list [catch {set real 1.x3} msg] $msg $real
+} {1 {can't set "real": variable must have real value} 1.23}
+test link-2.4 {writing bad values into variables} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 1 1 1 1
+ list [catch {set bool gorp} msg] $msg $bool
+} {1 {can't set "bool": variable must have boolean value} 1}
+
+test link-3.1 {read-only variables} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 0 1 1 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
+} {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}
+test link-3.2 {read-only variables} {
+ testlink delete
+ testlink set 43 1.23 4 -
+ testlink create 1 0 0 1
+ 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
+} {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}}
+
+test link-4.1 {unsetting linked variables} {
+ testlink delete
+ testlink set -6 -2.1 0 stringValue
+ testlink create 1 1 1 1
+ unset int real bool string
+ list [catch {set int} msg] $msg [catch {set real} msg] $msg \
+ [catch {set bool} msg] $msg [catch {set string} msg] $msg
+} {0 -6 0 -2.1 0 0 0 stringValue}
+test link-4.2 {unsetting linked variables} {
+ testlink delete
+ testlink set -6 -2.1 0 stringValue
+ testlink create 1 1 1 1
+ unset int real bool string
+ set int 102
+ set real 16
+ set bool true
+ set string newValue
+ testlink get
+} {102 16.0 1 newValue}
+
+test link-5.1 {unlinking variables} {
+ testlink delete
+ testlink set -6 -2.1 0 stringValue
+ testlink delete
+ set int xx1
+ set real qrst
+ set bool bogus
+ set string 12345
+ testlink get
+} {-6 -2.1 0 stringValue}
+test link-5.2 {unlinking variables} {
+ testlink delete
+ testlink set -6 -2.1 0 stringValue
+ testlink create 1 1 1 1
+ testlink delete
+ testlink set 25 14.7 7 -
+ list $int $real $bool $string
+} {-6 -2.1 0 stringValue}
+
+test link-6.1 {errors in setting up link} {
+ testlink delete
+ catch {unset int}
+ set int(44) 1
+ list [catch {testlink create 1 1 1 1} msg] $msg
+} {1 {can't set "int": variable is array}}
+catch {unset int}
+
+test link-7.1 {access to linked variables via upvar} {
+ proc x {} {
+ upvar int y
+ unset y
+ }
+ testlink delete
+ testlink create 1 0 0 0
+ testlink set 14 {} {} {}
+ x
+ list [catch {set int} msg] $msg
+} {0 14}
+test link-7.2 {access to linked variables via upvar} {
+ proc x {} {
+ upvar int y
+ return [set y]
+ }
+ testlink delete
+ testlink create 1 0 0 0
+ testlink set 0 {} {} {}
+ set int
+ testlink set 23 {} {} {}
+ x
+ list [x] $int
+} {23 23}
+test link-7.3 {access to linked variables via upvar} {
+ proc x {} {
+ upvar int y
+ set y 44
+ }
+ testlink delete
+ testlink create 0 0 0 0
+ testlink set 11 {} {} {}
+ list [catch x msg] $msg $int
+} {1 {can't set "y": linked variable is read-only} 11}
+test link-7.4 {access to linked variables via upvar} {
+ proc x {} {
+ upvar int y
+ set y abc
+ }
+ testlink delete
+ testlink create 1 1 1 1
+ testlink set -4 {} {} {}
+ list [catch x msg] $msg $int
+} {1 {can't set "y": variable must have integer value} -4}
+test link-7.5 {access to linked variables via upvar} {
+ proc x {} {
+ upvar real y
+ set y abc
+ }
+ testlink delete
+ testlink create 1 1 1 1
+ testlink set -4 16.3 {} {}
+ list [catch x msg] $msg $real
+} {1 {can't set "y": variable must have real value} 16.3}
+test link-7.6 {access to linked variables via upvar} {
+ proc x {} {
+ upvar bool y
+ set y abc
+ }
+ testlink delete
+ testlink create 1 1 1 1
+ testlink set -4 16.3 1 {}
+ list [catch x msg] $msg $bool
+} {1 {can't set "y": variable must have boolean value} 1}
+
+test link-8.1 {Tcl_UpdateLinkedVar procedure} {
+ proc x args {
+ global x int real bool string
+ lappend x $args $int $real $bool $string
+ }
+ set x {}
+ testlink create 1 1 1 1
+ testlink set 14 -2.0 0 xyzzy
+ trace var int w x
+ testlink update 32 4.0 3 abcd
+ trace vdelete int w x
+ set x
+} {{int {} w} 32 -2.0 0 xyzzy}
+test link-8.2 {Tcl_UpdateLinkedVar procedure} {
+ proc x args {
+ global x int real bool string
+ lappend x $args $int $real $bool $string
+ }
+ set x {}
+ testlink create 1 1 1 1
+ testlink set 14 -2.0 0 xyzzy
+ testlink delete
+ trace var int w x
+ testlink update 32 4.0 6 abcd
+ trace vdelete int w x
+ set x
+} {}
+
+testlink delete
+foreach i {int real bool string} {
+ catch {unset $i}
+}
diff --git a/contrib/tcl/tests/linsert.test b/contrib/tcl/tests/linsert.test
new file mode 100644
index 0000000..a77a907
--- /dev/null
+++ b/contrib/tcl/tests/linsert.test
@@ -0,0 +1,86 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) linsert.test 1.8 96/02/16 08:56:07
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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-2.1 {linsert errors} {
+ list [catch linsert msg] $msg
+} {1 {wrong # args: should be "linsert list index element ?element ...?"}}
+test linsert-2.2 {linsert errors} {
+ list [catch {linsert a b} msg] $msg
+} {1 {wrong # args: should be "linsert list index element ?element ...?"}}
+test linsert-2.3 {linsert errors} {
+ list [catch {linsert a 12x 2} msg] $msg
+} {1 {expected integer but got "12x"}}
+test linsert-2.4 {linsert errors} {
+ list [catch {linsert \{ 12 2} msg] $msg
+} {1 {unmatched open brace in list}}
diff --git a/contrib/tcl/tests/list.test b/contrib/tcl/tests/list.test
new file mode 100644
index 0000000..e901391
--- /dev/null
+++ b/contrib/tcl/tests/list.test
@@ -0,0 +1,73 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) list.test 1.20 96/02/16 08:56:09
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# 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} {}
+
+# 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 1
+proc lcheck {a b c} {
+ global num d
+ set d [list $a $b $c]
+ test list-2.$num {what goes in must come out} {lindex $d 0} $a
+ set num [expr $num+1]
+ test list-2.$num {what goes in must come out} {lindex $d 1} $b
+ set num [expr $num+1]
+ test list-2.$num {what goes in must come out} {lindex $d 2} $c
+ set num [expr $num+1]
+}
+lcheck a b c
+lcheck "a b" c\td e\nf
+lcheck {{a b}} {} { }
+lcheck \$ \$ab ab\$
+lcheck \; \;ab ab\;
+lcheck \[ \[ab ab\[
+lcheck \\ \\ab ab\\
+lcheck {"} {"ab} {ab"}
+lcheck {a b} { ab} {ab }
+lcheck a{ a{b \{ab
+lcheck a} a}b }ab
+lcheck a\\} {a \}b} {a \{c}
+lcheck xyz \\ 1\\\n2
+lcheck "{ab}\\" "{ab}xy" abc
+
+concat {}
diff --git a/contrib/tcl/tests/llength.test b/contrib/tcl/tests/llength.test
new file mode 100644
index 0000000..badfd17
--- /dev/null
+++ b/contrib/tcl/tests/llength.test
@@ -0,0 +1,35 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) llength.test 1.4 96/02/16 08:56:11
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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}}
diff --git a/contrib/tcl/tests/load.test b/contrib/tcl/tests/load.test
new file mode 100644
index 0000000..331e3b7
--- /dev/null
+++ b/contrib/tcl/tests/load.test
@@ -0,0 +1,147 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: %Z% %M% %I% %E% %U%
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+
+if {$tcl_platform(platform) == "macintosh"} {
+ puts "can't run dynamic library tests on macintosh machines"
+ return
+}
+set ext [info sharedlibextension]
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+if ![file readable [file join $testDir pkga$ext]] {
+ puts "libraries in $testDir haven't been compiled: skipping tests"
+ return
+}
+
+if [string match *pkga* [info loaded]] {
+ puts "load tests have already been run once: skipping (can't rerun)"
+ return
+}
+
+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 {couldn't find slave interpreter named "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} {
+ load [file join $testDir pkga$ext]
+ list [pkga_eq abc def] [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} {
+ 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} {
+ list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg
+} {1 {couldn't find procedure Foo_Init}}
+test load-2.4 {loading with no _SafeInit procedure} {
+ 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 [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} {
+ 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 [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
+} {0 {}}
+test load-4.2 {reloading package into same interpreter} {
+ list [catch {load [file join $testDir pkga$ext] pkgb} msg] $msg
+} "1 {file \"[file join $testDir pkga$ext\"] is already loaded for package \"Pkga\"}"
+
+# On some platforms, like SunOS 4.1.3, these tests can't be run because
+# they cause the process to exit.
+
+test load-5.1 {errors loading file} {nonPortable} {
+ catch {load foo foo}
+} {1}
+
+if {[info command teststaticpkg] != ""} {
+ test load-6.1 {Tcl_StaticPackage procedure, static packages} {
+ set x "not loaded"
+ teststaticpkg Test 1 0
+ load {} Test
+ load {} Test child
+ list [set x] [child eval set x]
+ } {loaded loaded}
+ test load-6.2 {Tcl_StaticPackage procedure, static packages} {
+ 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-6.3 {Tcl_StaticPackage procedure, static packages} {
+ set x "not loaded"
+ teststaticpkg More 0 1
+ load {} More
+ set x
+ } {not loaded}
+
+ test load-7.1 {TclGetLoadedPackages procedure} {
+ info loaded
+ } "{{} More} {{} Another} {{} Test} {[file join $testDir pkge$ext] Pkge} {[file join $testDir pkgb$ext] Pkgb} {[file join $testDir pkga$ext] Pkga} {{} Tcltest}"
+ test load-7.2 {TclGetLoadedPackages procedure} {
+ list [catch {info loaded gorp} msg] $msg
+ } {1 {couldn't find slave interpreter named "gorp"}}
+ test load-7.3 {TclGetLoadedPackages procedure} {
+ list [info loaded {}] [info loaded child]
+ } "{{{} More} {{} Another} {{} Test} {[file join $testDir pkga$ext] Pkga} {{} Tcltest}} {{{} Test} {[file join $testDir pkgb$ext] Pkgb}}"
+ test load-7.4 {TclGetLoadedPackages procedure} {
+ load [file join $testDir pkgb$ext] pkgb
+ list [info loaded {}] [lsort [info commands pkgb_*]]
+ } "{{[file join $testDir pkgb$ext] Pkgb} {{} More} {{} Another} {{} Test} {[file join $testDir pkga$ext] Pkga} {{} Tcltest}} {pkgb_sub pkgb_unsafe}"
+ interp delete child
+}
diff --git a/contrib/tcl/tests/lrange.test b/contrib/tcl/tests/lrange.test
new file mode 100644
index 0000000..43d92e2
--- /dev/null
+++ b/contrib/tcl/tests/lrange.test
@@ -0,0 +1,77 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) lrange.test 1.5 96/02/16 08:56:13
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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 e
+} {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" e 3
+} d
+test lrange-1.14 {range of list elements} {
+ lrange "a b c d" end 2
+} {}
+
+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 {expected integer but got "b"}}
+test lrange-2.4 {error conditions} {
+ list [catch {lrange a 0 enigma} msg] $msg
+} {1 {expected integer or "end" but got "enigma"}}
+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}}
diff --git a/contrib/tcl/tests/lreplace.test b/contrib/tcl/tests/lreplace.test
new file mode 100644
index 0000000..95c14c0
--- /dev/null
+++ b/contrib/tcl/tests/lreplace.test
@@ -0,0 +1,111 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) lreplace.test 1.12 96/02/16 08:56:14
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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-2.1 {lreplace errors} {
+ list [catch lreplace msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element element ...?"}}
+test lreplace-2.2 {lreplace errors} {
+ list [catch {lreplace a b} msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element element ...?"}}
+test lreplace-2.3 {lreplace errors} {
+ list [catch {lreplace x a 10} msg] $msg
+} {1 {bad index "a": must be integer or "end"}}
+test lreplace-2.4 {lreplace errors} {
+ list [catch {lreplace x 10 x} msg] $msg
+} {1 {bad index "x": must be integer or "end"}}
+test lreplace-2.5 {lreplace errors} {
+ list [catch {lreplace x 10 1x} msg] $msg
+} {1 {bad index "1x": must be integer or "end"}}
+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}}
diff --git a/contrib/tcl/tests/lsearch.test b/contrib/tcl/tests/lsearch.test
new file mode 100644
index 0000000..95df872
--- /dev/null
+++ b/contrib/tcl/tests/lsearch.test
@@ -0,0 +1,67 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) lsearch.test 1.5 96/02/16 08:56:15
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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} {
+ list [catch {lsearch -regexp {xyz bbcc *bc*} *bc*} msg] $msg
+} {1 {couldn't compile regular expression pattern: ?+* follows nothing}}
+test lsearch-2.4 {search modes} {
+ lsearch -regexp {b.x ^bc xy bcx} ^bc
+} 3
+test lsearch-2.5 {search modes} {
+ lsearch -glob {xyz bbcc *bc*} *bc*
+} 1
+test lsearch-2.6 {search modes} {
+ lsearch -glob {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.7 {search modes} {
+ list [catch {lsearch -glib {b.x bx xy bcx} b.x} msg] $msg
+} {1 {bad search mode "-glib": must be -exact, -glob, or -regexp}}
+
+test lsearch-3.1 {lsearch errors} {
+ list [catch lsearch msg] $msg
+} {1 {wrong # args: should be "lsearch ?mode? list pattern"}}
+test lsearch-3.2 {lsearch errors} {
+ list [catch {lsearch a} msg] $msg
+} {1 {wrong # args: should be "lsearch ?mode? list pattern"}}
+test lsearch-3.3 {lsearch errors} {
+ list [catch {lsearch a b c} msg] $msg
+} {1 {bad search mode "a": must be -exact, -glob, or -regexp}}
+test lsearch-3.4 {lsearch errors} {
+ list [catch {lsearch a b c d} msg] $msg
+} {1 {wrong # args: should be "lsearch ?mode? list pattern"}}
+test lsearch-3.5 {lsearch errors} {
+ list [catch {lsearch "\{" b} msg] $msg
+} {1 {unmatched open brace in list}}
diff --git a/contrib/tcl/tests/lsort.test b/contrib/tcl/tests/lsort.test
new file mode 100644
index 0000000..907dfbf
--- /dev/null
+++ b/contrib/tcl/tests/lsort.test
@@ -0,0 +1,126 @@
+# Commands covered: lsort
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) lsort.test 1.8 96/02/16 08:56:17
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test lsort-1.1 {lsort command} {
+ lsort {abdeq ab 1 ac a}
+} {1 a ab abdeq ac}
+test lsort-1.2 {lsort command} {
+ lsort -decreasing {abdeq ab 1 ac a}
+} {ac abdeq ab a 1}
+test lsort-1.3 {lsort command} {
+ lsort -increasing {abdeq ab 1 ac a}
+} {1 a ab abdeq ac}
+test lsort-1.4 {lsort command} {
+ lsort {{one long element}}
+} {{one long element}}
+test lsort-1.5 {lsort command} {
+ lsort {}
+} {}
+test lsort-1.6 {lsort with characters needing backslashes} {
+ lsort {$ \\ [] \{}
+} {{$} {[]} \\ \{}
+
+test lsort-2.1 {lsort -integer} {
+ lsort -integer -inc {1 180 62 040 180 -42 33 0x40}
+} {-42 1 040 33 62 0x40 180 180}
+test lsort-2.2 {lsort -integer} {
+ lsort -int -dec {1 180 62 040 180 -42 33 0x40}
+} {180 180 0x40 62 33 040 1 -42}
+test lsort-2.3 {lsort -integer} {
+ list [catch {lsort -integer {xxx 180.2 62 040 180 -42 33 0x40}} msg] $msg $errorInfo
+} {1 {expected integer but got "xxx"} {expected integer but got "xxx"
+ (converting list element from string to integer)
+ invoked from within
+"lsort -integer {xxx 180.2 62 040 180 -42 33 0x40}"}}
+test lsort-2.4 {lsort -integer} {
+ list [catch {lsort -integer {1 180.2 62 040 180 -42 33 0x40}} msg] $msg $errorInfo
+} {1 {expected integer but got "180.2"} {expected integer but got "180.2"
+ (converting list element from string to integer)
+ invoked from within
+"lsort -integer {1 180.2 62 040 180 -42 33 0x40}"}}
+
+test lsort-3.1 {lsort -real} {
+ lsort -real {1 180.1 62 040 180 -42.7 33}
+} {-42.7 1 33 040 62 180 180.1}
+test lsort-3.2 {lsort -real} {
+ lsort -r -d {1 180.1 62 040 180 -42.7 33}
+} {180.1 180 62 040 33 1 -42.7}
+test lsort-3.3 {lsort -real} {
+ list [catch {lsort -real -inc {xxx 20 62 180 -42.7 33}} msg] $msg $errorInfo
+} {1 {expected floating-point number but got "xxx"} {expected floating-point number but got "xxx"
+ (converting list element from string to real)
+ invoked from within
+"lsort -real -inc {xxx 20 62 180 -42.7 33}"}}
+test lsort-3.4 {lsort -real} {
+ list [catch {lsort -real -inc {1 0x40 62 180 -42.7 33}} msg] $msg $errorInfo
+} {1 {expected floating-point number but got "0x40"} {expected floating-point number but got "0x40"
+ (converting list element from string to real)
+ invoked from within
+"lsort -real -inc {1 0x40 62 180 -42.7 33}"}}
+
+proc lsort1 {a b} {
+ expr {2*([string match x* $a] - [string match x* $b])
+ + [string match *y $a] - [string match *y $b]}
+}
+proc lsort2 {a b} {
+ error "comparison error"
+}
+proc lsort3 {a b} {
+ concat "foobar"
+}
+
+test lsort-4.1 {lsort -command} {
+ lsort -command lsort1 {xxx yyy abc {xx y}}
+} {abc yyy xxx {xx y}}
+test lsort-4.2 {lsort -command} {
+ lsort -command lsort1 -dec {xxx yyy abc {xx y}}
+} {{xx y} xxx yyy abc}
+test lsort-4.3 {lsort -command} {
+ list [catch {lsort -command lsort2 -dec {1 1 1 1}} msg] $msg $errorInfo
+} {1 {comparison error} {comparison error
+ while executing
+"error "comparison error""
+ (procedure "lsort2" line 2)
+ invoked from within
+"lsort2 1 1"
+ (user-defined comparison command)
+ invoked from within
+"lsort -command lsort2 -dec {1 1 1 1}"}}
+test lsort-4.4 {lsort -command} {
+ list [catch {lsort -command lsort3 -dec {1 2 3 4}} msg] $msg $errorInfo
+} {1 {comparison command returned non-numeric result} {comparison command returned non-numeric result
+ while executing
+"lsort -command lsort3 -dec {1 2 3 4}"}}
+test lsort-4.5 {lsort -command} {
+ list [catch {lsort -command {xxx yyy xxy abc}} msg] $msg
+} {1 {"-command" must be followed by comparison command}}
+
+test lsort-5.1 {lsort errors} {
+ list [catch lsort msg] $msg
+} {1 {wrong # args: should be "lsort ?-ascii? ?-integer? ?-real? ?-increasing? ?-decreasing? ?-command string? list"}}
+test lsort-5.2 {lsort errors} {
+ list [catch {lsort a b} msg] $msg
+} {1 {bad switch "a": must be -ascii, -integer, -real, -increasing -decreasing, or -command}}
+test lsort-5.3 {lsort errors} {
+ list [catch {lsort "\{"} msg] $msg
+} {1 {unmatched open brace in list}}
+test lsort-5.4 {lsort errors} {
+ list [catch {lsort -in {1 180.0 040 62 180 -42.7 33}} msg] $msg
+} {1 {bad switch "-in": must be -ascii, -integer, -real, -increasing -decreasing, or -command}}
+test lsort-5.5 {lsort errors: disallow recursion} {
+ proc x args {lsort {a b c}}
+ list [catch {lsort -command x {3 7}} msg] $msg
+} {1 {can't invoke "lsort" recursively}}
diff --git a/contrib/tcl/tests/misc.test b/contrib/tcl/tests/misc.test
new file mode 100644
index 0000000..b53759d
--- /dev/null
+++ b/contrib/tcl/tests/misc.test
@@ -0,0 +1,70 @@
+# 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 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) misc.test 1.5 96/02/16 08:56:18
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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 {}
+ list [catch tstProc msg] $msg $errorInfo
+} [list 1 {missing close-brace for variable name} \
+[format {missing close-brace for variable name
+ while executing
+"winfo name $%szz)
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus comment
+ # this is a bogus commen ..."
+ (parsing index for array "a")
+ invoked from within
+"set tst $a([winfo name $%szz)
+ # 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"} \{ \{]]
diff --git a/contrib/tcl/tests/parse.test b/contrib/tcl/tests/parse.test
new file mode 100644
index 0000000..fa1c6f5
--- /dev/null
+++ b/contrib/tcl/tests/parse.test
@@ -0,0 +1,520 @@
+# Commands covered: set (plus basic command syntax). Also tests
+# the procedures in the file tclParse.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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) parse.test 1.34 96/03/02 14:29:03
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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 parse-1.1 {basic argument parsing} {
+ set arg1 {}
+ fourArgs a b c d
+ list $arg1 $arg2 $arg3 $arg4
+} {a b c d}
+test parse-1.2 {basic argument parsing} {
+ set arg1 {}
+ eval "fourArgs 123\v4\f56\r7890"
+ list $arg1 $arg2 $arg3 $arg4
+} {123 4 56 7890}
+
+# Quotes.
+
+test parse-2.1 {quotes and variable-substitution} {
+ getArgs "a b c" d
+ set argv
+} {{a b c} d}
+test parse-2.2 {quotes and variable-substitution} {
+ set a 101
+ getArgs "a$a b c"
+ set argv
+} {{a101 b c}}
+test parse-2.3 {quotes and variable-substitution} {
+ set argv "xy[format xabc]"
+ set argv
+} {xyxabc}
+test parse-2.4 {quotes and variable-substitution} {
+ set argv "xy\t"
+ set argv
+} xy\t
+test parse-2.5 {quotes and variable-substitution} {
+ set argv "a b c
+d e f"
+ set argv
+} a\ b\tc\nd\ e\ f
+test parse-2.6 {quotes and variable-substitution} {
+ set argv a"bcd"e
+ set argv
+} {a"bcd"e}
+
+# Braces.
+
+test parse-3.1 {braces} {
+ getArgs {a b c} d
+ set argv
+} "{a b c} d"
+test parse-3.2 {braces} {
+ set a 101
+ set argv {a$a b c}
+ set b [string index $argv 1]
+ set b
+} {$}
+test parse-3.3 {braces} {
+ set argv {a[format xyz] b}
+ string length $argv
+} 15
+test parse-3.4 {braces} {
+ set argv {a\nb\}}
+ string length $argv
+} 6
+test parse-3.5 {braces} {
+ set argv {{{{}}}}
+ set argv
+} "{{{}}}"
+test parse-3.6 {braces} {
+ set argv a{{}}b
+ set argv
+} "a{{}}b"
+test parse-3.7 {braces} {
+ set a [format "last]"]
+ set a
+} {last]}
+
+# Command substitution.
+
+test parse-4.1 {command substitution} {
+ set a [format xyz]
+ set a
+} xyz
+test parse-4.2 {command substitution} {
+ set a a[format xyz]b[format q]
+ set a
+} axyzbq
+test parse-4.3 {command substitution} {
+ set a a[
+set b 22;
+format %s $b
+
+]b
+ set a
+} a22b
+
+# Variable substitution.
+
+test parse-5.1 {variable substitution} {
+ set a 123
+ set b $a
+ set b
+} 123
+test parse-5.2 {variable substitution} {
+ set a 345
+ set b x$a.b
+ set b
+} x345.b
+test parse-5.3 {variable substitution} {
+ set _123z xx
+ set b $_123z^
+ set b
+} xx^
+test parse-5.4 {variable substitution} {
+ set a 78
+ set b a${a}b
+ set b
+} a78b
+test parse-5.5 {variable substitution} {catch {$_non_existent_} msg} 1
+test parse-5.6 {variable substitution} {
+ catch {$_non_existent_} msg
+ set msg
+} {can't read "_non_existent_": no such variable}
+test parse-5.7 {array variable substitution} {
+ catch {unset a}
+ set a(xyz) 123
+ set b $a(xyz)foo
+ set b
+} 123foo
+test parse-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 parse-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 parse-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 parse-5.11 {array variable substitution} {
+ set b a$!
+ set b
+} {a$!}
+test parse-5.12 {array variable substitution} {
+ set b a$()
+ set b
+} {a$()}
+catch {unset a}
+test parse-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 parse-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}
+
+# Backslash substitution.
+
+set errNum 1
+proc bsCheck {char num} {
+ global errNum
+ test parse-6.$errNum {backslash substitution} {
+ scan $char %c value
+ set value
+ } $num
+ set errNum [expr $errNum+1]
+}
+
+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
+bsCheck \8a 8
+bsCheck \14 12
+bsCheck \141 97
+bsCheck \340 224
+bsCheck b\0 98
+bsCheck \x 120
+bsCheck \xa 10
+bsCheck \x41 65
+bsCheck \x541 65
+
+test parse-6.1 {backslash substitution} {
+ set a "\a\c\n\]\}"
+ string length $a
+} 5
+test parse-6.2 {backslash substitution} {
+ set a {\a\c\n\]\}}
+ string length $a
+} 10
+test parse-6.3 {backslash substitution} {
+ set a "abc\
+def"
+ set a
+} {abc def}
+test parse-6.4 {backslash substitution} {
+ set a {abc\
+def}
+ set a
+} {abc def}
+test parse-6.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 parse-6.6 {backslash substitution} {
+ eval "concat abc\\"
+} "abc\\"
+test parse-6.7 {backslash substitution} {
+ eval "concat \\\na"
+} "a"
+test parse-6.8 {backslash substitution} {
+ eval "concat x\\\n a"
+} "x a"
+test parse-6.9 {backslash substitution} {
+ eval "concat \\x"
+} "x"
+test parse-6.10 {backslash substitution} {
+ eval "list a b\\\nc d"
+} {a b c d}
+test parse-6.11 {backslash substitution} {
+ eval "list a \"b c\"\\\nd e"
+} {a {b c} d e}
+
+# Semi-colon.
+
+test parse-7.1 {semi-colons} {
+ set b 0
+ getArgs a;set b 2
+ set argv
+} a
+test parse-7.2 {semi-colons} {
+ set b 0
+ getArgs a;set b 2
+ set b
+} 2
+test parse-7.3 {semi-colons} {
+ getArgs a b ; set b 1
+ set argv
+} {a b}
+test parse-7.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 parse-8.1 {result initialization} {concat abc} abc
+test parse-8.2 {result initialization} {concat abc; proc foo {} {}} {}
+test parse-8.3 {result initialization} {concat abc; proc foo {} $a} {}
+test parse-8.4 {result initialization} {proc foo {} [concat abc]} {}
+test parse-8.5 {result initialization} {concat abc; } abc
+test parse-8.6 {result initialization} {
+ eval {
+ concat abc
+}} abc
+test parse-8.7 {result initialization} {} {}
+test parse-8.8 {result initialization} {concat abc; ; ;} abc
+
+# Syntax errors.
+
+test parse-9.1 {syntax errors} {catch "set a \{bcd" msg} 1
+test parse-9.2 {syntax errors} {
+ catch "set a \{bcd" msg
+ set msg
+} {missing close-brace}
+test parse-9.3 {syntax errors} {catch {set a "bcd} msg} 1
+test parse-9.4 {syntax errors} {
+ catch {set a "bcd} msg
+ set msg
+} {missing "}
+test parse-9.5 {syntax errors} {catch {set a "bcd"xy} msg} 1
+test parse-9.6 {syntax errors} {
+ catch {set a "bcd"xy} msg
+ set msg
+} {extra characters after close-quote}
+test parse-9.7 {syntax errors} {catch "set a {bcd}xy" msg} 1
+test parse-9.8 {syntax errors} {
+ catch "set a {bcd}xy" msg
+ set msg
+} {extra characters after close-brace}
+test parse-9.9 {syntax errors} {catch {set a [format abc} msg} 1
+test parse-9.10 {syntax errors} {
+ catch {set a [format abc} msg
+ set msg
+} {missing close-bracket}
+test parse-9.11 {syntax errors} {catch gorp-a-lot msg} 1
+test parse-9.12 {syntax errors} {
+ catch gorp-a-lot msg
+ set msg
+} {invalid command name "gorp-a-lot"}
+test parse-9.13 {syntax errors} {
+ set a [concat {a}\
+ {b}]
+ set a
+} {a b}
+test parse-9.14 {syntax errors} {
+ list [catch {eval \$x[format "%01000d" 0](} msg] $msg $errorInfo
+} {1 {missing )} {missing )
+ (parsing index for array "x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
+ invoked from within
+"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ..."
+ ("eval" body line 1)
+ invoked from within
+"eval \$x[format "%01000d" 0]("}}
+
+# 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 parse-10.1 {long values} {
+ string length $a
+} 214
+test parse-10.2 {long values} {
+ llength $a
+} 43
+test parse-1a1.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 parse-10.3 {long values} {
+ set b "$a"
+ set b
+} $a
+test parse-10.4 {long values} {
+ set b [set a]
+ set b
+} $a
+test parse-10.5 {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 parse-10.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]
+ llength $b
+} 43
+test parse-10.7 {long values} {
+ set b
+} $a
+test parse-10.8 {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
+ set i [expr $i+1]
+ test parse-10.9 {long values} {
+ set j
+ } $test
+}
+test parse-10.10 {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 parse-11.1 {comments} {
+ set a old
+ eval { # set a new}
+ set a
+} {old}
+test parse-11.2 {comments} {
+ set a old
+ eval " # set a new\nset a new"
+ set a
+} {new}
+test parse-11.3 {comments} {
+ set a old
+ eval " # set a new\\\nset a new"
+ set a
+} {old}
+test parse-11.4 {comments} {
+ set a old
+ eval " # set a new\\\\\nset a new"
+ set a
+} {new}
+
+test parse-12.1 {comments at the end of a bracketed script} {
+ set x "[
+expr 1+1
+# skip this!
+]"
+} {2}
+
+if {[info command testwordend] == "testwordend"} {
+ test parse-13.1 {TclWordEnd procedure} {
+ testwordend " \n abc"
+ } {c}
+ test parse-13.2 {TclWordEnd procedure} {
+ testwordend " \\\n"
+ } {}
+ test parse-13.3 {TclWordEnd procedure} {
+ testwordend " \\\n "
+ } { }
+ test parse-13.4 {TclWordEnd procedure} {
+ testwordend {"abc"}
+ } {"}
+ test parse-13.5 {TclWordEnd procedure} {
+ testwordend {{xyz}}
+ } \}
+ test parse-13.6 {TclWordEnd procedure} {
+ testwordend {{a{}b{}\}} xyz}
+ } "\} xyz"
+ test parse-13.7 {TclWordEnd procedure} {
+ testwordend {abc[this is a]def ghi}
+ } {f ghi}
+ test parse-13.8 {TclWordEnd procedure} {
+ testwordend "puts\\\n\n "
+ } "s\\\n\n "
+ test parse-13.9 {TclWordEnd procedure} {
+ testwordend "puts\\\n "
+ } "s\\\n "
+ test parse-13.10 {TclWordEnd procedure} {
+ testwordend "puts\\\n xyz"
+ } "s\\\n xyz"
+ test parse-13.11 {TclWordEnd procedure} {
+ testwordend {a$x.$y(a long index) foo}
+ } ") foo"
+ test parse-13.12 {TclWordEnd procedure} {
+ testwordend {abc; def}
+ } {; def}
+ test parse-13.13 {TclWordEnd procedure} {
+ testwordend {abc def}
+ } {c def}
+ test parse-13.14 {TclWordEnd procedure} {
+ testwordend {abc def}
+ } {c def}
+ test parse-13.15 {TclWordEnd procedure} {
+ testwordend "abc\ndef"
+ } "c\ndef"
+ test parse-13.16 {TclWordEnd procedure} {
+ testwordend "abc"
+ } {c}
+}
+
+test parse-14.1 {TclScriptEnd procedure} {
+ info complete {puts [
+ expr 1+1
+ #this is a comment ]}
+} {0}
+test parse-14.2 {TclScriptEnd procedure} {
+ info complete "abc\\\n"
+} {0}
+test parse-14.3 {TclScriptEnd procedure} {
+ info complete "abc\\\\\n"
+} {1}
+test parse-14.4 {TclScriptEnd procedure} {
+ info complete "xyz \[abc \{abc\]"
+} {0}
+test parse-14.5 {TclScriptEnd procedure} {
+ info complete "xyz \[abc"
+} {0}
diff --git a/contrib/tcl/tests/pid.test b/contrib/tcl/tests/pid.test
new file mode 100644
index 0000000..1f6e039
--- /dev/null
+++ b/contrib/tcl/tests/pid.test
@@ -0,0 +1,52 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) pid.test 1.12 96/04/12 11:14:43
+
+# If pid is not defined just return with no error
+# Some platforms may not have the pid command implemented
+if {[info commands pid] == ""} {
+ puts "pid is not implemented for this machine"
+ return
+}
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+catch {removeFile test1}
+
+test pid-1.1 {pid command} {
+ regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
+} 1
+test pid-1.2 {pid command} {unixOrPc unixExecs} {
+ set f [open {| echo foo | cat >test1} w]
+ set pids [pid $f]
+ close $f
+ catch {removeFile test1}
+ list [llength $pids] [regexp {^[0-9]+$} [lindex $pids 0]] \
+ [regexp {^[0-9]+$} [lindex $pids 1]] \
+ [expr {[lindex $pids 0] == [lindex $pids 1]}]
+} {2 1 1 0}
+test pid-1.3 {pid command} {
+ set f [open test1 w]
+ set pids [pid $f]
+ close $f
+ set pids
+} {}
+test pid-1.4 {pid command} {
+ list [catch {pid a b} msg] $msg
+} {1 {wrong # args: should be "pid ?channelId?"}}
+test pid-1.5 {pid command} {
+ list [catch {pid gorp} msg] $msg
+} {1 {can not find channel named "gorp"}}
+
+catch {removeFile test1}
+concat {}
diff --git a/contrib/tcl/tests/pkg.test b/contrib/tcl/tests/pkg.test
new file mode 100644
index 0000000..66c1658
--- /dev/null
+++ b/contrib/tcl/tests/pkg.test
@@ -0,0 +1,549 @@
+# Commands covered: pkg
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) pkg.test 1.6 96/03/20 10:50:27
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+eval package forget [package names]
+package unknown {}
+set oldPath auto_path
+set auto_path ""
+
+test pkg-1.1 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+} {}
+test pkg-1.2 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+ list [catch {package provide t 2.2} msg] $msg
+} {1 {conflicting versions provided for package "t": 2.3, then 2.2}}
+test pkg-1.3 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+ list [catch {package provide t 2.4} msg] $msg
+} {1 {conflicting versions provided for package "t": 2.3, then 2.4}}
+test pkg-1.4 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+ list [catch {package provide t 3.3} msg] $msg
+} {1 {conflicting versions provided for package "t": 2.3, then 3.3}}
+test pkg-1.5 {Tcl_PkgProvide procedure} {
+ package forget t
+ package provide t 2.3
+ package provide t 2.3
+} {}
+
+test pkg-2.1 {Tcl_PkgRequire procedure, picking best version} {
+ package forget t
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ set x xxx
+ package require t
+ set x
+} {3.4}
+test pkg-2.2 {Tcl_PkgRequire procedure, picking best version} {
+ package forget t
+ 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"
+ }
+ set x xxx
+ package require t
+ set x
+} {3.5}
+test pkg-2.3 {Tcl_PkgRequire procedure, picking best version} {
+ package forget t
+ foreach i {3.5 2.1 2.3} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ set x xxx
+ package require t 2.2
+ set x
+} {2.3}
+test pkg-2.4 {Tcl_PkgRequire procedure, picking best version} {
+ package forget t
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ set x xxx
+ package require -exact t 2.3
+ set x
+} {2.3}
+test pkg-2.5 {Tcl_PkgRequire procedure, picking best version} {
+ package forget t
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i; package provide t $i"
+ }
+ set x xxx
+ package require t 2.1
+ set x
+} {2.4}
+test pkg-2.6 {Tcl_PkgRequire procedure, can't find suitable version} {
+ package forget t
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ list [catch {package require t 2.5} msg] $msg
+} {1 {can't find package t 2.5}}
+test pkg-2.7 {Tcl_PkgRequire procedure, can't find suitable version} {
+ package forget t
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ list [catch {package require t 4.1} msg] $msg
+} {1 {can't find package t 4.1}}
+test pkg-2.8 {Tcl_PkgRequire procedure, can't find suitable version} {
+ package forget t
+ package unknown {}
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ list [catch {package require -exact t 1.3} msg] $msg
+} {1 {can't find package t 1.3}}
+test pkg-2.9 {Tcl_PkgRequire procedure, can't find suitable version} {
+ package forget t
+ package unknown {}
+ list [catch {package require t} msg] $msg
+} {1 {can't find package t}}
+test pkg-2.10 {Tcl_PkgRequire procedure, error in ifneeded script} {
+ package forget t
+ package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test"}
+ list [catch {package require t 2.1} msg] $msg $errorInfo
+} {1 {ifneeded test} {ifneeded test
+ while executing
+"error "ifneeded test""
+ ("package ifneeded" script)
+ invoked from within
+"package require t 2.1"}}
+test pkg-2.11 {Tcl_PkgRequire procedure, ifneeded script doesn't provide package} {
+ package forget t
+ package ifneeded t 2.1 "set x invoked"
+ set x xxx
+ list [catch {package require t 2.1} msg] $msg $x
+} {1 {can't find package t 2.1} invoked}
+test pkg-2.12 {Tcl_PkgRequire procedure, self-deleting script} {
+ package forget t
+ package ifneeded t 1.2 "package forget t; set x 1.2; package provide t 1.2"
+ set x xxx
+ package require t 1.2
+ set x
+} {1.2}
+test pkg-2.13 {Tcl_PkgRequire procedure, "package unknown" support} {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ package provide [lindex $args 0] [lindex $args 1]
+ }
+ package forget t
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package unknown pkgUnknown
+ set x xxx
+ package require -exact t 1.5
+ package unknown {}
+ set x
+} {t 1.5 -exact}
+test pkg-2.14 {Tcl_PkgRequire procedure, "package unknown" support} {
+ proc pkgUnknown args {
+ package ifneeded t 1.2 "set x loaded; package provide t 1.2"
+ }
+ package forget t
+ package unknown pkgUnknown
+ set x xxx
+ set result [list [package require t] $x]
+ package unknown {}
+ set result
+} {1.2 loaded}
+test pkg-2.15 {Tcl_PkgRequire procedure, "package unknown" support} {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ package provide [lindex $args 0] 2.0
+ }
+ package forget {a b}
+ package unknown pkgUnknown
+ set x xxx
+ package require {a b}
+ package unknown {}
+ set x
+} {{a b} {}}
+test pkg-2.16 {Tcl_PkgRequire procedure, "package unknown" error} {
+ proc pkgUnknown args {
+ error "testing package unknown"
+ }
+ package forget t
+ package unknown pkgUnknown
+ set result [list [catch {package require t} msg] $msg $errorInfo]
+ package unknown {}
+ set result
+} {1 {testing package unknown} {testing package unknown
+ while executing
+"error "testing package unknown""
+ (procedure "pkgUnknown" line 2)
+ invoked from within
+"pkgUnknown t {}"
+ ("package unknown" script)
+ invoked from within
+"package require t"}}
+test pkg-2.17 {Tcl_PkgRequire procedure, "package unknown" doesn't load package} {
+ proc pkgUnknown args {
+ global x
+ set x $args
+ }
+ package forget t
+ foreach i {1.4 3.4 2.3 2.4 2.2} {
+ package ifneeded t $i "set x $i"
+ }
+ package unknown pkgUnknown
+ set x xxx
+ set result [list [catch {package require -exact t 1.5} msg] $msg $x]
+ package unknown {}
+ set result
+} {1 {can't find package t 1.5} {t 1.5 -exact}}
+test pkg-2.18 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ package require t
+} {2.3}
+test pkg-2.19 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ package require t 2.1
+} {2.3}
+test pkg-2.20 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ package require t 2.3
+} {2.3}
+test pkg-2.21 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ list [catch {package require t 2.4} msg] $msg
+} {1 {version conflict for package "t": have 2.3, need 2.4}}
+test pkg-2.22 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ list [catch {package require t 1.2} msg] $msg
+} {1 {version conflict for package "t": have 2.3, need 1.2}}
+test pkg-2.23 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ package require -exact t 2.3
+} {2.3}
+test pkg-2.24 {Tcl_PkgRequire procedure, version checks} {
+ package forget t
+ package provide t 2.3
+ list [catch {package require -exact t 2.2} msg] $msg
+} {1 {version conflict for package "t": have 2.3, need 2.2}}
+
+test pkg-3.1 {Tcl_PackageCmd procedure} {
+ list [catch {package} msg] $msg
+} {1 {wrong # args: should be "package option ?arg arg ...?"}}
+test pkg-3.2 {Tcl_PackageCmd procedure, "forget" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ package names
+} {}
+test pkg-3.3 {Tcl_PackageCmd procedure, "forget" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ package forget foo
+} {}
+test pkg-3.4 {Tcl_PackageCmd procedure, "forget" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ package ifneeded t 1.1 {first script}
+ package ifneeded t 2.3 {second script}
+ package ifneeded x 1.4 {x's script}
+ set result {}
+ lappend result [lsort [package names]] [package versions t]
+ package forget t
+ lappend result [lsort [package names]] [package versions t]
+} {{t x} {1.1 2.3} x {}}
+test pkg-3.5 {Tcl_PackageCmd procedure, "forget" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ 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]]
+} {{a b c} b}
+test pkg-3.6 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ list [catch {package ifneeded a} msg] $msg
+} {1 {wrong # args: should be "package ifneeded package version ?script?"}}
+test pkg-3.7 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ list [catch {package ifneeded a b c d} msg] $msg
+} {1 {wrong # args: should be "package ifneeded package version ?script?"}}
+test pkg-3.8 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ list [catch {package ifneeded t xyz} msg] $msg
+} {1 {expected version number but got "xyz"}}
+test pkg-3.9 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ list [package ifneeded foo 1.1] [package names]
+} {{} {}}
+test pkg-3.10 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ package forget t
+ package ifneeded t 1.4 "script for t 1.4"
+ list [package names] [package ifneeded t 1.4] [package versions t]
+} {t {script for t 1.4} 1.4}
+test pkg-3.11 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ package forget t
+ package ifneeded t 1.4 "script for t 1.4"
+ list [package ifneeded t 1.5] [package names] [package versions t]
+} {{} t 1.4}
+test pkg-3.12 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ package forget t
+ 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]
+} {{second script for t 1.4} t 1.4}
+test pkg-3.13 {Tcl_PackageCmd procedure, "ifneeded" option} {
+ package forget t
+ 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]
+} {{second script} {1.4 1.2 3.1}}
+test pkg-3.14 {Tcl_PackageCmd procedure, "names" option} {
+ list [catch {package names a} msg] $msg
+} {1 {wrong # args: should be "package names"}}
+test pkg-3.15 {Tcl_PackageCmd procedure, "names" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ package names
+} {}
+test pkg-3.16 {Tcl_PackageCmd procedure, "names" option} {
+ foreach i [package names] {
+ package forget $i
+ }
+ 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]
+} {x y}
+test pkg-3.17 {Tcl_PackageCmd procedure, "provide" option} {
+ list [catch {package provide} msg] $msg
+} {1 {wrong # args: should be "package provide package ?version?"}}
+test pkg-3.18 {Tcl_PackageCmd procedure, "provide" option} {
+ list [catch {package provide a b c} msg] $msg
+} {1 {wrong # args: should be "package provide package ?version?"}}
+test pkg-3.19 {Tcl_PackageCmd procedure, "provide" option} {
+ package forget t
+ package provide t
+} {}
+test pkg-3.20 {Tcl_PackageCmd procedure, "provide" option} {
+ package forget t
+ package provide t 2.3
+ package provide t
+} {2.3}
+test pkg-3.21 {Tcl_PackageCmd procedure, "provide" option} {
+ package forget t
+ list [catch {package provide t a.b} msg] $msg
+} {1 {expected version number but got "a.b"}}
+test pkg-3.22 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require} msg] $msg
+} {1 {wrong # args: should be "package require ?-exact? package ?version?"}}
+test pkg-3.23 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require a b c} msg] $msg
+} {1 {wrong # args: should be "package require ?-exact? package ?version?"}}
+test pkg-3.24 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require -exact a b c} msg] $msg
+} {1 {wrong # args: should be "package require ?-exact? package ?version?"}}
+test pkg-3.25 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require -bs a b} msg] $msg
+} {1 {wrong # args: should be "package require ?-exact? package ?version?"}}
+test pkg-3.26 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require x a.b} msg] $msg
+} {1 {expected version number but got "a.b"}}
+test pkg-3.27 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require -exact x a.b} msg] $msg
+} {1 {expected version number but got "a.b"}}
+test pkg-3.28 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require -exact x} msg] $msg
+} {1 {wrong # args: should be "package require ?-exact? package ?version?"}}
+test pkg-3.29 {Tcl_PackageCmd procedure, "require" option} {
+ list [catch {package require -exact} msg] $msg
+} {1 {wrong # args: should be "package require ?-exact? package ?version?"}}
+test pkg-3.30 {Tcl_PackageCmd procedure, "require" option} {
+ package forget t
+ package provide t 2.3
+ package require t 2.1
+} {2.3}
+test pkg-3.31 {Tcl_PackageCmd procedure, "require" option} {
+ package forget t
+ list [catch {package require t} msg] $msg
+} {1 {can't find package t}}
+test pkg-3.32 {Tcl_PackageCmd procedure, "require" option} {
+ package forget t
+ package ifneeded t 2.3 "error {synthetic error}"
+ list [catch {package require t 2.3} msg] $msg
+} {1 {synthetic error}}
+test pkg-3.33 {Tcl_PackageCmd procedure, "unknown" option} {
+ list [catch {package unknown a b} msg] $msg
+} {1 {wrong # args: should be "package unknown ?command?"}}
+test pkg-3.34 {Tcl_PackageCmd procedure, "unknown" option} {
+ package unknown "test script"
+ package unknown
+} {test script}
+test pkg-3.35 {Tcl_PackageCmd procedure, "unknown" option} {
+ package unknown "test script"
+ package unknown {}
+ package unknown
+} {}
+test pkg-3.36 {Tcl_PackageCmd procedure, "vcompare" option} {
+ list [catch {package vcompare a} msg] $msg
+} {1 {wrong # args: should be "package vcompare version1 version2"}}
+test pkg-3.37 {Tcl_PackageCmd procedure, "vcompare" option} {
+ list [catch {package vcompare a b c} msg] $msg
+} {1 {wrong # args: should be "package vcompare version1 version2"}}
+test pkg-3.38 {Tcl_PackageCmd procedure, "vcompare" option} {
+ list [catch {package vcompare x.y 3.4} msg] $msg
+} {1 {expected version number but got "x.y"}}
+test pkg-3.39 {Tcl_PackageCmd procedure, "vcompare" option} {
+ list [catch {package vcompare 2.1 a.b} msg] $msg
+} {1 {expected version number but got "a.b"}}
+test pkg-3.40 {Tcl_PackageCmd procedure, "vcompare" option} {
+ package vc 2.1 2.3
+} {-1}
+test pkg-3.41 {Tcl_PackageCmd procedure, "vcompare" option} {
+ package vc 2.2.4 2.2.4
+} {0}
+test pkg-3.42 {Tcl_PackageCmd procedure, "versions" option} {
+ list [catch {package versions} msg] $msg
+} {1 {wrong # args: should be "package versions package"}}
+test pkg-3.43 {Tcl_PackageCmd procedure, "versions" option} {
+ list [catch {package versions a b} msg] $msg
+} {1 {wrong # args: should be "package versions package"}}
+test pkg-3.44 {Tcl_PackageCmd procedure, "versions" option} {
+ package forget t
+ package versions t
+} {}
+test pkg-3.45 {Tcl_PackageCmd procedure, "versions" option} {
+ package forget t
+ package provide t 2.3
+ package versions t
+} {}
+test pkg-3.46 {Tcl_PackageCmd procedure, "versions" option} {
+ package forget t
+ package ifneeded t 2.3 x
+ package ifneeded t 2.4 y
+ package versions t
+} {2.3 2.4}
+test pkg-3.47 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ list [catch {package vsatisfies a} msg] $msg
+} {1 {wrong # args: should be "package vsatisfies version1 version2"}}
+test pkg-3.48 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ list [catch {package vsatisfies a b c} msg] $msg
+} {1 {wrong # args: should be "package vsatisfies version1 version2"}}
+test pkg-3.49 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ list [catch {package vsatisfies x.y 3.4} msg] $msg
+} {1 {expected version number but got "x.y"}}
+test pkg-3.50 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ list [catch {package vcompare 2.1 a.b} msg] $msg
+} {1 {expected version number but got "a.b"}}
+test pkg-3.51 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ package vs 2.3 2.1
+} {1}
+test pkg-3.52 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+ package vs 2.3 1.2
+} {0}
+test pkg-3.53 {Tcl_PackageCmd procedure, "versions" option} {
+ list [catch {package foo} msg] $msg
+} {1 {bad option "foo": should be forget, ifneeded, names, provide, require, unknown, vcompare, versions, or vsatisfies}}
+
+# No tests for FindPackage; can't think up anything detectable
+# errors.
+
+test pkg-4.1 {TclFreePackageInfo procedure} {
+ 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
+ package unknown "will this get freed?"
+ }
+ interp delete foo
+} {}
+test pkg-4.2 {TclFreePackageInfo procedure} {
+ 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
+ }
+ list [catch {foo eval package require x 3.1} msg] $msg
+} {1 {can't find package x 3.1}}
+
+test pkg-5.1 {CheckVersion procedure} {
+ list [catch {package vcompare 1 2.1} msg] $msg
+} {0 -1}
+test pkg-5.2 {CheckVersion procedure} {
+ list [catch {package vcompare .1 2.1} msg] $msg
+} {1 {expected version number but got ".1"}}
+test pkg-5.3 {CheckVersion procedure} {
+ list [catch {package vcompare 111.2a.3 2.1} msg] $msg
+} {1 {expected version number but got "111.2a.3"}}
+test pkg-5.4 {CheckVersion procedure} {
+ list [catch {package vcompare 1.2.3. 2.1} msg] $msg
+} {1 {expected version number but got "1.2.3."}}
+
+test pkg-6.1 {ComparePkgVersions procedure} {
+ package vcompare 1.23 1.22
+} {1}
+test pkg-6.2 {ComparePkgVersions procedure} {
+ package vcompare 1.22.1.2.3 1.22.1.2.3
+} {0}
+test pkg-6.3 {ComparePkgVersions procedure} {
+ package vcompare 1.21 1.22
+} {-1}
+test pkg-6.4 {ComparePkgVersions procedure} {
+ package vcompare 1.21 1.21.2
+} {-1}
+test pkg-6.5 {ComparePkgVersions procedure} {
+ package vcompare 1.21.1 1.21
+} {1}
+test pkg-6.6 {ComparePkgVersions procedure} {
+ package vsatisfies 1.21.1 1.21
+} {1}
+test pkg-6.7 {ComparePkgVersions procedure} {
+ package vsatisfies 2.22.3 1.21
+} {0}
+test pkg-6.8 {ComparePkgVersions procedure} {
+ package vsatisfies 1 1
+} {1}
+test pkg-6.9 {ComparePkgVersions procedure} {
+ package vsatisfies 2 1
+} {0}
+
+set auto_path oldPath
+concat
diff --git a/contrib/tcl/tests/proc.test b/contrib/tcl/tests/proc.test
new file mode 100644
index 0000000..6eef73c
--- /dev/null
+++ b/contrib/tcl/tests/proc.test
@@ -0,0 +1,461 @@
+# Commands covered: proc, return, global
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) proc.test 1.21 96/02/16 08:56:21
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+proc tproc {} {return a; return b}
+test proc-1.1 {simple procedure call and return} {tproc} a
+proc tproc x {
+ set x [expr $x+1]
+ return $x
+}
+test proc-1.2 {simple procedure call and return} {tproc 2} 3
+test proc-1.3 {simple procedure call and return} {
+ proc tproc {} {return foo}
+} {}
+test proc-1.4 {simple procedure call and return} {
+ proc tproc {} {return}
+ tproc
+} {}
+
+test proc-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-3.1 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ tproc 11 12 13
+} {11 12 13}
+test proc-3.2 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc 11 12} msg] $msg
+} {1 {no value given for parameter "z" to "tproc"}}
+test proc-3.3 {arguments and defaults} {
+ proc tproc {x y z} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc 11 12 13 14} msg] $msg
+} {1 {called "tproc" with too many arguments}}
+test proc-3.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-3.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-3.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-3.7 {arguments and defaults} {
+ proc tproc {x {y y-default} {z z-default}} {
+ return [list $x $y $z]
+ }
+ list [catch {tproc} msg] $msg
+} {1 {no value given for parameter "x" to "tproc"}}
+test proc-3.8 {arguments and defaults} {
+ list [catch {
+ proc tproc {x {y y-default} z} {
+ return [list $x $y $z]
+ }
+ tproc 2 3
+ } msg] $msg
+} {1 {no value given for parameter "z" to "tproc"}}
+test proc-3.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-3.10 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2 3
+} {2 3 {}}
+test proc-3.11 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ tproc 2
+} {2 y-default {}}
+test proc-3.12 {arguments and defaults} {
+ proc tproc {x {y y-default} args} {
+ return [list $x $y $args]
+ }
+ list [catch {tproc} msg] $msg
+} {1 {no value given for parameter "x" to "tproc"}}
+
+test proc-4.1 {variable numbers of arguments} {
+ proc tproc args {return $args}
+ tproc
+} {}
+test proc-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-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-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-4.5 {variable numbers of arguments} {
+ proc tproc {x y args} {return $args}
+ tproc 1 2
+} {}
+test proc-4.6 {variable numbers of arguments} {
+ proc tproc {x missing args} {return $args}
+ list [catch {tproc 1} msg] $msg
+} {1 {no value given for parameter "missing" to "tproc"}}
+
+test proc-5.1 {error conditions} {
+ list [catch {proc} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-5.2 {error conditions} {
+ list [catch {proc tproc b} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-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-5.4 {error conditions} {
+ list [catch {proc tproc \{xyz {return foo}} msg] $msg
+} {1 {unmatched open brace in list}}
+test proc-5.5 {error conditions} {
+ list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {procedure "tproc" has argument with no name}}
+test proc-5.6 {error conditions} {
+ list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {procedure "tproc" has argument with no name}}
+test proc-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-5.8 {error conditions} {
+ catch {return}
+} 2
+test proc-5.9 {error conditions} {
+ list [catch {global} msg] $msg
+} {1 {wrong # args: should be "global varName ?varName ...?"}}
+proc tproc {} {
+ set a 22
+ global a
+}
+test proc-5.10 {error conditions} {
+ list [catch {tproc} msg] $msg
+} {1 {variable "a" already exists}}
+test proc-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-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-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-5.14 {error conditions} {
+ proc tproc {} {
+ set a 22
+ break
+ return
+ }
+ catch tproc msg
+ set errorInfo
+} {invoked "break" outside of a loop
+ while executing
+"tproc"}
+test proc-5.15 {error conditions} {
+ proc tproc {} {
+ set a 22
+ continue
+ return
+ }
+ catch tproc msg
+ set errorInfo
+} {invoked "continue" outside of a loop
+ while executing
+"tproc"}
+test proc-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""
+ ("while" body line 2)
+ invoked from within
+"while {$x < 100} {
+ error "Nested error"
+ }"
+ (procedure "tproc" line 4)
+ 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-6.1 {procedure that redefines itself} {
+ proc tproc {} {
+ proc tproc {} {
+ return 44
+ }
+ return 45
+ }
+ tproc
+} 45
+test proc-6.2 {procedure that deletes itself} {
+ proc tproc {} {
+ rename tproc {}
+ return 45
+ }
+ tproc
+} 45
+
+proc tproc code {
+ return -code $code abc
+}
+test proc-7.1 {return with special completion code} {
+ list [catch {tproc ok} msg] $msg
+} {0 abc}
+test proc-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-7.3 {return with special completion code} {
+ list [catch {tproc return} msg] $msg
+} {2 abc}
+test proc-7.4 {return with special completion code} {
+ list [catch {tproc break} msg] $msg
+} {3 abc}
+test proc-7.5 {return with special completion code} {
+ list [catch {tproc continue} msg] $msg
+} {4 abc}
+test proc-7.6 {return with special completion code} {
+ list [catch {tproc -14} msg] $msg
+} {-14 abc}
+test proc-7.7 {return with special completion code} {
+ list [catch {tproc gorp} msg] $msg
+} {1 {bad completion code "gorp": must be ok, error, return, break, continue, or an integer}}
+test proc-7.8 {return with special completion code} {
+ list [catch {tproc 10b} msg] $msg
+} {1 {bad completion code "10b": must be ok, error, return, break, continue, or an integer}}
+test proc-7.9 {return with special completion code} {
+ proc tproc2 {} {
+ tproc return
+ }
+ list [catch tproc2 msg] $msg
+} {0 abc}
+test proc-7.10 {return with special completion code} {
+ proc tproc2 {} {
+ return -code error
+ }
+ list [catch tproc2 msg] $msg
+} {1 {}}
+test proc-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
+ }
+ normalizeMsg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
+} {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-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
+ }
+ normalizeMsg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
+} {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-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
+ }
+ normalizeMsg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
+} {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-7.14 {return with special completion code} {
+ proc tproc2 {} {
+ global errorCode errorInfo
+ catch {open _bad_file_name r} msg
+ return -code error $msg
+ }
+ normalizeMsg [list [catch tproc2 msg] $msg $errorInfo $errorCode]
+} {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-7.14 {return with special completion code} {
+ list [catch {return -badOption foo message} msg] $msg
+} {1 {bad option "-badOption: must be -code, -errorcode, or -errorinfo}}
diff --git a/contrib/tcl/tests/regexp.test b/contrib/tcl/tests/regexp.test
new file mode 100644
index 0000000..1f1aecf
--- /dev/null
+++ b/contrib/tcl/tests/regexp.test
@@ -0,0 +1,315 @@
+# 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) 1994 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) regexp.test 1.20 96/04/02 15:03:53
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+catch {unset foo}
+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-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-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 regsub} {
+ list [regexp -nocase $x $x foo] $foo
+} "1 $x"
+unset 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 ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"}}
+test regexp-6.2 {regexp errors} {
+ list [catch {regexp -nocase a} msg] $msg
+} {1 {wrong # args: should be "regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"}}
+test regexp-6.3 {regexp errors} {
+ list [catch {regexp -gorp a} msg] $msg
+} {1 {bad switch "-gorp": must be -indices, -nocase, or --}}
+test regexp-6.4 {regexp errors} {
+ list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: unmatched ()}}
+test regexp-6.5 {regexp errors} {
+ list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: unmatched ()}}
+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
+} {1 {couldn't compile regular expression pattern: too many ()}}
+test regexp-6.8 {regexp errors} {
+ set f1 44
+ list [catch {regexp abc abc f1(f2)} msg] $msg
+} {1 {couldn't set variable "f1(f2)"}}
+
+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-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 {regsub errors} {
+ list [catch {regsub a b c} msg] $msg
+} {1 {wrong # args: should be "regsub ?switches? exp string subSpec varName"}}
+test regexp-10.2 {regsub errors} {
+ list [catch {regsub -nocase a b c} msg] $msg
+} {1 {wrong # args: should be "regsub ?switches? exp string subSpec varName"}}
+test regexp-10.3 {regsub errors} {
+ list [catch {regsub -nocase -all a b c} msg] $msg
+} {1 {wrong # args: should be "regsub ?switches? exp string subSpec varName"}}
+test regexp-10.4 {regsub errors} {
+ list [catch {regsub a b c d e f} msg] $msg
+} {1 {wrong # args: should be "regsub ?switches? exp string subSpec varName"}}
+test regexp-10.5 {regsub errors} {
+ list [catch {regsub -gorp a b c} msg] $msg
+} {1 {bad switch "-gorp": must be -all, -nocase, or --}}
+test regexp-10.6 {regsub errors} {
+ list [catch {regsub -nocase a( b c d} msg] $msg
+} {1 {couldn't compile regular expression pattern: unmatched ()}}
+test regexp-10.7 {regsub errors} {
+ list [catch {regsub -nocase aaa aaa xxx f1(f2)} msg] $msg
+} {1 {couldn't set variable "f1(f2)"}}
diff --git a/contrib/tcl/tests/remote.tcl b/contrib/tcl/tests/remote.tcl
new file mode 100644
index 0000000..3ede61a
--- /dev/null
+++ b/contrib/tcl/tests/remote.tcl
@@ -0,0 +1,161 @@
+# 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.
+#
+# @(#) remote.tcl 1.5 96/04/17 08:21:19"
+
+# 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
+ if {[catch {uplevel #0 $l} msg]} {
+ list error $msg
+ } else {
+ list success $msg
+ }
+}
+
+proc __readAndExecute__ {s} {
+ global command VERBOSE
+
+ set l [gets $s]
+ if {[string compare $l "--Marker--Marker--Marker--"] == 0} {
+ if {[info exists command($s)]} {
+ puts $s [list error incomplete_command]
+ }
+ puts $s "--Marker--Marker--Marker--"
+ return
+ }
+ if {[string compare $l ""] == 0} {
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ }
+ return
+ }
+ append command($s) $l "\n"
+ if {[info complete $command($s)]} {
+ set cmds $command($s)
+ unset command($s)
+ puts $s [__doCommands__ $cmds $s]
+ }
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ }
+}
+
+proc __accept__ {s a p} {
+ global VERBOSE
+
+ if {$VERBOSE} {
+ puts "Server accepts new connection from $a:$p on $s"
+ }
+ fileevent $s readable [list __readAndExecute__ $s]
+ fconfigure $s -buffering line -translation crlf
+}
+
+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
+}
+
+if {[catch {set serverSocket \
+ [socket -myaddr $serverAddress -server __accept__ $serverPort]} msg]} {
+ puts "Server on $serverAddress:$serverPort cannot start: $msg"
+} else {
+ vwait __server_wait_variable__
+}
diff --git a/contrib/tcl/tests/rename.test b/contrib/tcl/tests/rename.test
new file mode 100644
index 0000000..1613445
--- /dev/null
+++ b/contrib/tcl/tests/rename.test
@@ -0,0 +1,131 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) rename.test 1.13 96/03/20 10:49:22
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+# 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 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"} NONE}
+test rename-3.2 {error conditions} {
+ list [catch {rename r1 r2 r3} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} NONE}
+test rename-3.3 {error conditions} {
+ proc r1 {} {}
+ proc r2 {} {}
+ list [catch {rename r1 r2} msg] $msg
+} {1 {can't rename to "r2": command already exists}}
+test rename-3.4 {error conditions} {
+ catch {rename r1 {}}
+ catch {rename r2 {}}
+ list [catch {rename r1 r2} msg] $msg
+} {1 {can't rename "r1": command doesn't exist}}
+test rename-3.5 {error conditions} {
+ catch {rename _non_existent_command {}}
+ list [catch {rename _non_existent_command {}} msg] $msg
+} {1 {can't delete "_non_existent_command": command doesn't exist}}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+if {[info command testdel] == "testdel"} {
+ test rename-4.1 {reentrancy issues with command deletion and renaming} {
+ 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} {
+ 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} {
+ 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} {
+ 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} {
+ 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} {
+ 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} {
+ 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}
+}
diff --git a/contrib/tcl/tests/scan.test b/contrib/tcl/tests/scan.test
new file mode 100644
index 0000000..0b2da90
--- /dev/null
+++ b/contrib/tcl/tests/scan.test
@@ -0,0 +1,257 @@
+# 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 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) scan.test 1.23 96/02/16 08:56:24
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test scan-1.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-1.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-1.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-1.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-1.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-1.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-1.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-1.8 {integer scanning} {
+ set a {}; set b {}
+ list [scan "a 1234" "%d %d" a b] $a $b
+} {0 {} {}}
+test scan-1.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-1.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 {} {}}
+test scan-1.11 {integer scanning} {nonPortable} {
+ set a {}; set b {};
+ list [scan "4294967280 4294967280" "%u %d" a b] $a $b
+} {2 4294967280 -16}
+
+test scan-2.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 -3e+08 0.99962 {}}
+test scan-2.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-2.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}
+test scan-2.4 {floating-point scanning} {nonPortable} {
+ 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-2.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-2.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-05}
+test scan-2.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-2.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-3.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-3.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-3.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-3.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-3.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-4.1 {error conditions} {
+ catch {scan a}
+} 1
+test scan-4.2 {error conditions} {
+ catch {scan a} msg
+ set msg
+} {wrong # args: should be "scan string format ?varName varName ...?"}
+test scan-4.3 {error conditions} {
+ catch {scan "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21" "%d %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 a21}
+} 1
+test scan-4.4 {error conditions} {
+ catch {scan "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21" "%d %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 a21} msg
+ set msg
+} {too many fields to scan}
+test scan-4.5 {error conditions} {
+ list [catch {scan a %D} msg] $msg
+} {1 {bad scan conversion character "D"}}
+test scan-4.6 {error conditions} {
+ list [catch {scan a %O} msg] $msg
+} {1 {bad scan conversion character "O"}}
+test scan-4.7 {error conditions} {
+ list [catch {scan a %X} msg] $msg
+} {1 {bad scan conversion character "X"}}
+test scan-4.8 {error conditions} {
+ list [catch {scan a %F} msg] $msg
+} {1 {bad scan conversion character "F"}}
+test scan-4.9 {error conditions} {
+ list [catch {scan a %E} msg] $msg
+} {1 {bad scan conversion character "E"}}
+test scan-4.10 {error conditions} {
+ list [catch {scan a "%d %d" a} msg] $msg
+} {1 {different numbers of variable names and field specifiers}}
+test scan-4.11 {error conditions} {
+ list [catch {scan a "%d %d" a b c} msg] $msg
+} {1 {different numbers of variable names and field specifiers}}
+test scan-4.12 {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-4.13 {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-4.14 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %d a} msg] $msg
+} {1 {couldn't set variable "a"}}
+test scan-4.15 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %c a} msg] $msg
+} {1 {couldn't set variable "a"}}
+test scan-4.16 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %s a} msg] $msg
+} {1 {couldn't set variable "a"}}
+test scan-4.17 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %f a} msg] $msg
+} {1 {couldn't set variable "a"}}
+test scan-4.18 {error conditions} {
+ catch {unset a}
+ set a(0) 44
+ list [catch {scan 44 %f a} msg] $msg
+} {1 {couldn't set variable "a"}}
+catch {unset a}
+test scan-4.19 {error conditions} {
+ list [catch {scan 44 %2c a} msg] $msg
+} {1 {field width may not be specified in %c conversion}}
+test scan-4.20 {error conditions} {
+ list [catch {scan abc {%[}} msg] $msg
+} {1 {unmatched [ in format string}}
+
+test scan-5.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-5.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-6.1 {miscellaneous tests} {
+ set a {}
+ list [scan ab16c ab%dc a] $a
+} {1 16}
+test scan-6.2 {miscellaneous tests} {
+ set a {}
+ list [scan ax16c ab%dc a] $a
+} {0 {}}
+test scan-6.3 {miscellaneous tests} {
+ set a {}
+ list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
+} {0 1 114}
+test scan-6.4 {miscellaneous tests} {
+ set a {}
+ list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
+} {0 1 14}
+test scan-6.5 {miscellaneous tests} {
+ catch {unset tcl_precision}
+ set a {}
+ scan 1.111122223333 %f a
+ set a
+} {1.11112}
+test scan-6.6 {miscellaneous tests} {
+ set tcl_precision 10
+ set a {}
+ scan 1.111122223333 %lf a
+ unset tcl_precision
+ set a
+} {1.111122223}
+test scan-6.7 {miscellaneous tests} {
+ set tcl_precision 10
+ set a {}
+ scan 1.111122223333 %f a
+ unset tcl_precision
+ set a
+} {1.111122223}
+
+test scan-7.1 {alignment in results array (TCL_ALIGN)} {
+ scan "123 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-7.2 {alignment in results array (TCL_ALIGN)} {
+ scan "1234567 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-7.3 {alignment in results array (TCL_ALIGN)} {
+ scan "12345678901 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-7.4 {alignment in results array (TCL_ALIGN)} {
+ scan "123456789012345 13.6" "%s %f" a b
+ set b
+} 13.6
+test scan-7.5 {alignment in results array (TCL_ALIGN)} {
+ scan "1234567890123456789 13.6" "%s %f" a b
+ set b
+} 13.6
diff --git a/contrib/tcl/tests/set.test b/contrib/tcl/tests/set.test
new file mode 100644
index 0000000..8a8d887
--- /dev/null
+++ b/contrib/tcl/tests/set.test
@@ -0,0 +1,677 @@
+# Commands covered: set, unset, array
+#
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) set.test 1.18 96/02/16 08:56:25
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+proc ignore args {}
+
+# Simple variable operations.
+
+catch {unset a}
+test set-1.1 {basic variable setting and unsetting} {
+ set a 22
+} 22
+test set-1.2 {basic variable setting and unsetting} {
+ set a 123
+ set a
+} 123
+test set-1.3 {basic variable setting and unsetting} {
+ set a xxx
+ format %s $a
+} xxx
+test set-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-2.1 {basic array operations} {
+ lsort [array names a]
+} {44 {a long name} xyz}
+test set-2.2 {basic array operations} {
+ set a(44)
+} 3
+test set-2.3 {basic array operations} {
+ set a(xyz)
+} 2
+test set-2.4 {basic array operations} {
+ set "a(a long name)"
+} test
+test set-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-2.6 {basic array operations} {
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+test set-2.7 {basic array operations} {
+ format %s $a(44)
+} 3
+test set-2.8 {basic array operations} {
+ format %s $a(a long name)
+} test
+unset a(44)
+test set-2.9 {basic array operations} {
+ lsort [array names a]
+} {{a long name} xyz}
+test set-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-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-2.12 {basic array operations} {
+ list [catch {set a 14} msg] $msg
+} {1 {can't set "a": variable is array}}
+unset a
+test set-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-3.1 {set command} {
+ list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-3.2 {set command} {
+ list [catch {set x y z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-3.3 {set command} {
+ catch {unset a}
+ list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-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-4.1 {parsing array names} {
+ catch {unset a}
+ set a(()) 44
+ list [catch {array names a} msg] $msg
+} {0 ()}
+test set-4.2 {parsing array names} {
+ catch {unset a a(abcd}
+ set a(abcd 33
+ info exists a(abcd
+} 1
+test set-4.3 {parsing array names} {
+ catch {unset a a(abcd}
+ set a(abcd 33
+ list [catch {array names a} msg] $msg
+} {0 {}}
+test set-4.4 {parsing array names} {
+ catch {unset a abcd)}
+ set abcd) 33
+ info exists abcd)
+} 1
+test set-4.5 {parsing array names} {
+ set a(bcd yyy
+ catch {unset a}
+ list [catch {set a(bcd} msg] $msg
+} {0 yyy}
+test set-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-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-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-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-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-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-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-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-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-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-7.2 {unset command} {
+ list [catch {unset} msg] $msg
+} {1 {wrong # args: should be "unset varName ?varName ...?"}}
+test set-7.3 {unset command} {
+ catch {unset a}
+ list [catch {unset a} msg] $msg
+} {1 {can't unset "a": no such variable}}
+test set-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-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-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-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-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-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-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-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 {}}
+
+# Array command.
+
+test set-8.1 {array command} {
+ list [catch {array} msg] $msg
+} {1 {wrong # args: should be "array option arrayName ?arg ...?"}}
+test set-8.2 {array command} {
+ list [catch {array a} msg] $msg
+} {1 {wrong # args: should be "array option arrayName ?arg ...?"}}
+test set-8.3 {array command} {
+ catch {unset a}
+ list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-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-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-8.6 {array command} {
+ catch {unset a}
+ set a(22) 3
+ list [catch {array gorp a} msg] $msg
+} {1 {bad option "gorp": should be anymore, donesearch, exists, get, names, nextelement, set, size, or startsearch}}
+test set-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-8.8 {array command, donesearch option} {
+ catch {unset a}
+ list [catch {array donesearch a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-8.9 {array command, exists option} {
+ list [catch {array exists a b} msg] $msg
+} {1 {wrong # args: should be "array exists arrayName"}}
+test set-8.10 {array command, exists option} {
+ catch {unset a}
+ array exists a
+} {0}
+test set-8.11 {array command, exists option} {
+ catch {unset a}
+ set a(0) 1
+ array exists a
+} {1}
+test set-8.12 {array command, get option} {
+ list [catch {array get} msg] $msg
+} {1 {wrong # args: should be "array option arrayName ?arg ...?"}}
+test set-8.13 {array command, get option} {
+ list [catch {array get a b c} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-8.14 {array command, get option} {
+ catch {unset a}
+ array get a
+} {}
+test set-8.15 {array command, get option} {
+ catch {unset a}
+ set a(22) 3
+ set {a(long name)} {}
+ array get a
+} {22 3 {long name} {}}
+test set-8.16 {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-8.17 {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
+ array get a x*
+} {x1 3 x2 4 x3 5}
+test set-8.18 {array command, names option} {
+ catch {unset a}
+ set a(22) 3
+ list [catch {array names a 4 5} msg] $msg
+} {1 {wrong # args: should be "array names arrayName ?pattern?"}}
+test set-8.19 {array command, names option} {
+ catch {unset a}
+ array names a
+} {}
+test set-8.20 {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-8.21 {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-8.22 {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-8.23 {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-8.24 {array command, nextelement option} {
+ list [catch {array nextelement a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-8.25 {array command, nextelement option} {
+ catch {unset a}
+ list [catch {array nextelement a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-8.26 {array command, set option} {
+ list [catch {array set a} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-8.27 {array command, set option} {
+ list [catch {array set a 1 2} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-8.28 {array command, set option} {
+ list [catch {array set a "a \{ c"} msg] $msg
+} {1 {unmatched open brace in list}}
+test set-8.29 {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-8.30 {array command, set option} {
+ catch {unset a}
+ set a(xx) yy
+ array set a {b c d e}
+ array get a
+} {d e xx yy b c}
+test set-8.31 {array command, size option} {
+ list [catch {array size a 4} msg] $msg
+} {1 {wrong # args: should be "array size arrayName"}}
+test set-8.32 {array command, size option} {
+ catch {unset a}
+ array size a
+} {0}
+test set-8.33 {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-8.34 {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-8.35 {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-8.36 {array command, startsearch option} {
+ list [catch {array startsearch a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-8.37 {array command, startsearch option} {
+ catch {unset a}
+ list [catch {array startsearch a} msg] $msg
+} {1 {"a" isn't an array}}
+
+test set-9.1 {ids for array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ list [array st a] [array st a] [array done a s-1-a; array st 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-9.2 {array enumeration} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 1
+ set a(c) 1
+ set x [array startsearch a]
+ 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-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]
+ 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 b a a b b c c {} {} c {}}
+test set-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]
+ 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 b a c b c}
+test set-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-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-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-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-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-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-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-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]
+ list [array next a $x] [array next a $x]
+} {a {}}
+
+test set-10.1 {array enumeration errors} {
+ list [catch {array start} msg] $msg
+} {1 {wrong # args: should be "array option arrayName ?arg ...?"}}
+test set-10.2 {array enumeration errors} {
+ list [catch {array start a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-10.3 {array enumeration errors} {
+ catch {unset a}
+ list [catch {array start a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-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-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-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-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-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-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-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-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-10.12 {array enumeration errors} {
+ list [catch {array done a} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-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-10.14 {array enumeration errors} {
+ list [catch {array done a b} msg] $msg
+} {1 {illegal search identifier "b"}}
+test set-10.15 {array enumeration errors} {
+ list [catch {array anymore a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-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-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-11.1 {array anymore option} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 2
+ set a(c) 3
+ array startsearch a
+ 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]
+} {1 a 1 b 1 c 0 {}}
+test set-11.2 {array anymore option} {
+ catch {unset a}
+ set a(a) 1
+ set a(b) 2
+ set a(c) 3
+ array startsearch a
+ 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]
+} {a b 1 c {} 0}
+
+# 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-12.1 {cleanup on procedure return} {
+ proc foo {} {
+ set x 12345
+ }
+ foo
+} 12345
+test set-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}
+return ""
diff --git a/contrib/tcl/tests/socket.test b/contrib/tcl/tests/socket.test
new file mode 100644
index 0000000..a6c6642
--- /dev/null
+++ b/contrib/tcl/tests/socket.test
@@ -0,0 +1,1009 @@
+# 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.
+#
+# 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.
+#
+# "@(#) socket.test 1.56 96/04/20 13:29:26"
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+#
+# 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(remoteServerIP)]} {
+ set remoteServerPort $env(remoteServerPort)
+ } else {
+ if {[info exists remoteServerIP]} {
+ set remoteServerPort 2048
+ }
+ }
+}
+
+#
+# Check if we're supposed to do tests against the remote server
+#
+
+set doTestsWithRemoteServer 1
+if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
+ set remoteServerIP localhost
+}
+if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
+ set remoteServerPort 2048
+}
+
+# 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 remotePid -1
+if {$doTestsWithRemoteServer == 1} {
+ catch {close $commandSocket}
+ if {[catch {set commandSocket [socket $remoteServerIP \
+ $remoteServerPort]}] != 0} {
+ if {[info commands exec] == ""} {
+ set doTestsWithRemoteServer 0
+ } else {
+ set remoteServerIP localhost
+ if {[catch {set remotePid [exec $tcltest remote.tcl \
+ -serverIsSilent \
+ -port $remoteServerPort \
+ -address $remoteServerIP &]} \
+ msg] == 0} {
+ after 1000
+ if {[catch {set commandSocket [socket $remoteServerIP \
+ $remoteServerPort]}] == 0} {
+ fconfigure $commandSocket -translation crlf -buffering line
+ } else {
+ set doTestsWithRemoteServer 0
+ }
+ } else {
+ set doTestsWithRemoteServer 0
+ }
+ }
+ } else {
+ fconfigure $commandSocket -translation crlf -buffering line
+ }
+}
+
+if {$doTestsWithRemoteServer == 0} {
+ puts "Skipping tests with remote server. See tests/socket.test for"
+ puts "information on how to run remote server."
+}
+
+#
+# If we do the tests, define a command to send a command to the
+# remote server.
+#
+
+if {$doTestsWithRemoteServer == 1} {
+ 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"
+ }
+
+ set resp ""
+ while {1} {
+ set line [gets $commandSocket]
+ if {[eof $commandSocket]} {
+ error "remote server disappaered"
+ }
+ if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
+ if {[string compare [lindex $resp 0] error] == 0} {
+ error [lindex $resp 1]
+ } else {
+ return [lindex $resp 1]
+ }
+ } else {
+ append resp $line "\n"
+ }
+ }
+ }
+}
+
+test socket-1.1 {arg parsing for socket command} {
+ list [catch {socket -server} msg] $msg
+} {1 {no argument given for -server option}}
+test socket-1.2 {arg parsing for socket command} {
+ list [catch {socket -server foo} msg] $msg
+} {1 {wrong # args: should be either:
+socket ?-myaddr addr? ?-myport myport? ?-async? host port
+socket -server command ?-myaddr addr? port}}
+test socket-1.3 {arg parsing for socket command} {
+ list [catch {socket -myaddr} msg] $msg
+} {1 {no argument given for -myaddr option}}
+test socket-1.4 {arg parsing for socket command} {
+ list [catch {socket -myaddr 127.0.0.1} msg] $msg
+} {1 {wrong # args: should be either:
+socket ?-myaddr addr? ?-myport myport? ?-async? host port
+socket -server command ?-myaddr addr? port}}
+test socket-1.5 {arg parsing for socket command} {
+ list [catch {socket -myport} msg] $msg
+} {1 {no argument given for -myport option}}
+test socket-1.6 {arg parsing for socket command} {
+ list [catch {socket -myport xxxx} msg] $msg
+} {1 {expected integer but got "xxxx"}}
+test socket-1.7 {arg parsing for socket command} {
+ list [catch {socket -myport 2522} msg] $msg
+} {1 {wrong # args: should be either:
+socket ?-myaddr addr? ?-myport myport? ?-async? host port
+socket -server command ?-myaddr addr? port}}
+test socket-1.8 {arg parsing for socket command} {
+ list [catch {socket -froboz} msg] $msg
+} {1 {bad option "-froboz", must be -async, -myaddr, -myport, or -server}}
+test socket-1.9 {arg parsing for socket command} {
+ list [catch {socket -server foo -myport 2521 3333} msg] $msg
+} {1 {Option -myport is not valid for servers}}
+test socket-1.10 {arg parsing for socket command} {
+ list [catch {socket host 2528 -junk} msg] $msg
+} {1 {wrong # args: should be either:
+socket ?-myaddr addr? ?-myport myport? ?-async? host port
+socket -server command ?-myaddr addr? port}}
+test socket-1.11 {arg parsing for socket command} {
+ list [catch {socket -server callback 2520 --} msg] $msg
+} {1 {wrong # args: should be either:
+socket ?-myaddr addr? ?-myport myport? ?-async? host port
+socket -server command ?-myaddr addr? port}}
+test socket-1.12 {arg parsing for socket command} {
+ list [catch {socket foo badport} msg] $msg
+} {1 {expected integer but got "badport"}}
+
+test socket-2.1 {tcp connection} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ proc accept {file addr port} {
+ global x
+ set x done
+ close $file
+ }
+ puts ready
+ vwait x
+ close $f
+ puts done
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f x
+ if {[catch {socket localhost 2828} msg]} {
+ set x $msg
+ } else {
+ lappend x [gets $f]
+ close $msg
+ }
+ lappend x [gets $f]
+ close $f
+ set x
+} {ready done {}}
+
+if [info exists port] {
+ incr port
+} else {
+ set port [expr 2048 + [pid]%1024]
+}
+test socket-2.2 {tcp connection with client port specified} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file] $port"
+ close $file
+ set x done
+ }
+ puts ready
+ vwait x
+ close $f
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f x
+ global port
+ if {[catch {socket -myport $port localhost 2828} sock]} {
+ set x $sock
+ close [socket localhost 2828]
+ puts stderr $sock
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} [list ready "hello $port"]
+test socket-2.3 {tcp connection with client interface specified} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file] $addr"
+ close $file
+ set x done
+ }
+ puts ready
+ vwait x
+ close $f
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f x
+ if {[catch {socket -myaddr localhost localhost 2828} sock]} {
+ set x $sock
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} {ready {hello 127.0.0.1}}
+test socket-2.4 {tcp connection with server interface specified} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept -myaddr [info hostname] 2828]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file]"
+ close $file
+ set x done
+ }
+ puts ready
+ vwait x
+ close $f
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f x
+ if {[catch {socket [info hostname] 2828} sock]} {
+ set x $sock
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} {ready hello}
+test socket-2.5 {tcp connection with redundant server port} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ proc accept {file addr port} {
+ global x
+ puts "[gets $file]"
+ close $file
+ set x done
+ }
+ puts ready
+ vwait x
+ close $f
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f x
+ if {[catch {socket localhost 2828} sock]} {
+ set x $sock
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} {ready hello}
+test socket-2.6 {tcp connection} {unixOrPc} {
+ set status ok
+ if {![catch {set sock [socket localhost 2828]}]} {
+ if {![catch {gets $sock}]} {
+ set status broken
+ }
+ close $sock
+ }
+ set status
+} ok
+test socket-2.7 {echo server, one line} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ 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
+ vwait x
+ close $f
+ puts done
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f
+ set s [socket localhost 2828]
+ fconfigure $s -buffering line -translation lf
+ puts $s "hello abcdefghijklmnop"
+ set x [gets $s]
+ close $s
+ set y [gets $f]
+ close $f
+ list $x $y
+} {{hello abcdefghijklmnop} done}
+test socket-2.8 {echo server, loop 50 times, single connection} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ 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
+ vwait x
+ close $f
+ puts "done $i"
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f
+ set s [socket localhost 2828]
+ fconfigure $s -buffering line
+ for {set x 0} {$x < 50} {incr x} {
+ puts $s "hello abcdefghijklmnop"
+ gets $s
+ }
+ close $s
+ set x [gets $f]
+ close $f
+ set x
+} {done 50}
+test socket-2.9 {socket conflict} {unixOrPc} {
+ set s [socket -server accept 2828]
+ removeFile script
+ set f [open script w]
+ puts $f {set f [socket -server accept 2828]}
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f
+ after 100
+ set x [list [catch {close $f} msg] $msg]
+ close $s
+ set x
+} {1 {couldn't open socket: address already in use
+ while executing
+"socket -server accept 2828"
+ invoked from within
+"set f [socket -server accept 2828]..."
+ (file "script" line 1)}}
+
+test socket-3.1 {socket conflict} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set f [socket -server accept 2828]
+ puts ready
+ gets stdin
+ close $f
+ }
+ close $f
+ set f [open "|$tcltest script" r+]
+ gets $f
+ set x [list [catch {socket -server accept 2828} msg] \
+ $msg]
+ puts $f bye
+ close $f
+ set x
+} {1 {couldn't open socket: address already in use}}
+test socket-3.2 {server with several clients} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set counter 0
+ set s [socket -server accept 2828]
+ 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
+ vwait x
+ vwait x
+ vwait x
+ close $s
+ puts done
+ }
+ close $f
+ set f [open "|$tcltest script" r+]
+ set x [gets $f]
+ set s1 [socket localhost 2828]
+ fconfigure $s1 -buffering line
+ set s2 [socket localhost 2828]
+ fconfigure $s2 -buffering line
+ set s3 [socket localhost 2828]
+ 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]
+ close $f
+ set x
+} {ready done}
+
+test socket-4.1 {server with several clients} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ gets stdin
+ set s [socket localhost 2828]
+ 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 "|$tcltest script" r+]
+ fconfigure $p1 -buffering line
+ set p2 [open "|$tcltest script" r+]
+ fconfigure $p2 -buffering line
+ set p3 [open "|$tcltest script" r+]
+ fconfigure $p3 -buffering line
+ 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 s [socket -server accept 2828]
+ puts $p1 open
+ puts $p2 open
+ puts $p3 open
+ vwait x
+ vwait x
+ vwait x
+ close $s
+ set l ""
+ lappend l [list p1 [gets $p1]]
+ lappend l [list p2 [gets $p2]]
+ lappend l [list p3 [gets $p3]]
+ puts $p1 bye
+ puts $p2 bye
+ puts $p3 bye
+ close $p1
+ close $p2
+ close $p3
+ set l
+} {{p1 bye} {p2 bye} {p3 bye}}
+test socket-4.2 {byte order problems, socket numbers, htons} {
+ set x ok
+ if {[catch {socket -server dodo 0x3000} msg]} {
+ set x $msg
+ } else {
+ close $msg
+ }
+ set x
+} ok
+
+test socket-5.1 {byte order problems, socket numbers, htons} {unixOnly} {
+ #
+ # THIS TEST WILL FAIL if you are running as superuser.
+ #
+ set x {couldn't open socket: not owner}
+ if {![catch {socket -server dodo 0x1} msg]} {
+ set x {htons problem, should be disallowed, are you running as SU?}
+ close $msg
+ }
+ set x
+} {couldn't open socket: not owner}
+test socket-5.2 {byte order problems, socket numbers, htons} {
+ set x {couldn't open socket: port number too high}
+ if {![catch {socket -server dodo 0x10000} msg]} {
+ set x {port resolution problem, should be disallowed}
+ close $msg
+ }
+ set x
+} {couldn't open socket: port number too high}
+test socket-5.3 {byte order problems, socket numbers, htons} {unixOnly} {
+ #
+ # THIS TEST WILL FAIL if you are running as superuser.
+ #
+ set x {couldn't open socket: not owner}
+ if {![catch {socket -server dodo 21} msg]} {
+ set x {htons problem, should be disallowed, are you running as SU?}
+ close $msg
+ }
+ set x
+} {couldn't open socket: not owner}
+
+test socket-6.1 {accept callback error} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ gets stdin
+ socket localhost 2848
+ }
+ close $f
+ set f [open "|$tcltest script" r+]
+ proc bgerror args {
+ global x
+ set x $args
+ }
+ proc accept {s a p} {expr 10 / 0}
+ set s [socket -server accept 2848]
+ puts $f hello
+ close $f
+ vwait x
+ close $s
+ rename bgerror {}
+ set x
+} {{divide by zero}}
+
+test socket-7.1 {testing socket specific options} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ socket -server accept 2828
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ vwait x
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f
+ set s [socket localhost 2828]
+ set p [fconfigure $s -peername]
+ close $s
+ close $f
+ set l ""
+ lappend l [string compare [lindex $p 0] 127.0.0.1]
+ lappend l [string compare [lindex $p 2] 2828]
+ lappend l [llength $p]
+} {0 0 3}
+test socket-7.2 {testing socket specific options} {unixOrPc} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ socket -server accept 2828
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ vwait x
+ }
+ close $f
+ set f [open "|$tcltest script" r]
+ gets $f
+ set s [socket localhost 2828]
+ set p [fconfigure $s -sockname]
+ close $s
+ close $f
+ set l ""
+ lappend l [llength $p]
+ lappend l [lindex $p 0]
+ lappend l [expr [lindex $p 2] == 2828]
+} {3 127.0.0.1 0}
+test socket-7.3 {testing socket specific options} {
+ set s [socket -server accept 2828]
+ set l [fconfigure $s]
+ close $s
+ llength $l
+} 10
+test socket-7.4 {testing socket specific options} {
+ set s [socket -server accept 2828]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set s1 [socket localhost 2828]
+ vwait x
+ close $s
+ close $s1
+ set l ""
+ lappend l [lindex $x 0] [lindex $x 2] [llength $x]
+} {127.0.0.1 2828 3}
+
+test socket-8.1 {testing -async flag on sockets} {
+ # 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 2828]
+ proc accept {s a p} {
+ global x
+ puts $s bye
+ close $s
+ set x done
+ }
+ set s1 [socket -async localhost 2828]
+ vwait x
+ set z [gets $s1]
+ close $s
+ close $s1
+ set z
+} bye
+
+removeFile script
+
+#
+# The rest of the tests are run only if we are doing testing against
+# a remote server.
+#
+
+if {$doTestsWithRemoteServer == 0} {
+ return
+}
+
+test socket-9.1 {tcp connection} {
+ sendCommand {
+ set socket9_1_test_server [socket -server accept 2828]
+ proc accept {s a p} {
+ puts $s done
+ close $s
+ }
+ }
+ set s [socket $remoteServerIP 2828]
+ set r [gets $s]
+ close $s
+ sendCommand {close $socket9_1_test_server}
+ set r
+} done
+test socket-9.2 {client specifies its port} {
+ if {[info exists port]} {
+ incr port
+ } else {
+ set port [expr 2048 + [pid]%1024]
+ }
+ sendCommand {
+ set socket9_2_test_server [socket -server accept 2828]
+ proc accept {s a p} {
+ puts $s $p
+ close $s
+ }
+ }
+ set s [socket -myport $port $remoteServerIP 2828]
+ set r [gets $s]
+ close $s
+ sendCommand {close $socket9_2_test_server}
+ if {$r == $port} {
+ set result ok
+ } else {
+ set result broken
+ }
+ set result
+} ok
+#
+# Tests io-9.3, io-9.4 have been removed.
+#
+test socket-9.5 {trying to connect, no server} {
+ set status ok
+ if {![catch {set s [socket $remoteServerIp 2828]}]} {
+ if {![catch {gets $s}]} {
+ set status broken
+ }
+ close $s
+ }
+ set status
+} ok
+test socket-9.6 {remote echo, one line} {
+ sendCommand {
+ set socket9_6_test_server [socket -server accept 2828]
+ 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
+ }
+ }
+ }
+ set f [socket $remoteServerIP 2828]
+ fconfigure $f -translation crlf -buffering line
+ puts $f hello
+ set r [gets $f]
+ close $f
+ sendCommand {close $socket9_6_test_server}
+ set r
+} hello
+test socket-9.7 {remote echo, 50 lines} {
+ sendCommand {
+ set socket9_7_test_server [socket -server accept 2828]
+ 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
+ }
+ }
+ }
+ set f [socket $remoteServerIP 2828]
+ fconfigure $f -translation crlf -buffering line
+ for {set cnt 0} {$cnt < 50} {incr cnt} {
+ puts $f "hello, $cnt"
+ if {[string compare [gets $f] "hello, $cnt"] != 0} {
+ break
+ }
+ }
+ close $f
+ sendCommand {close $socket9_7_test_server}
+ set cnt
+} 50
+# Macintosh sockets can have more than one server per port
+if {$tcl_platform(platform) == "macintosh"} {
+ set conflictResult {0 2828}
+} else {
+ set conflictResult {1 {couldn't open socket: address already in use}}
+}
+test socket-9.8 {socket conflict} {
+ set s1 [socket -server accept 2828]
+ if {[catch {set s2 [socket -server accept 2828]} msg]} {
+ set result [list 1 $msg]
+ } else {
+ set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
+ close $s2
+ }
+ close $s1
+ set result
+} $conflictResult
+test socket-9.9 {server with several clients} {
+ sendCommand {
+ set socket9_9_test_server [socket -server accept 2828]
+ 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
+ }
+ }
+ }
+ set s1 [socket $remoteServerIP 2828]
+ fconfigure $s1 -buffering line
+ set s2 [socket $remoteServerIP 2828]
+ fconfigure $s2 -buffering line
+ set s3 [socket $remoteServerIP 2828]
+ 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
+ sendCommand {close $socket9_9_test_server}
+ set i
+} 100
+test socket-9.10 {client with several servers} {
+ sendCommand {
+ set s1 [socket -server "accept 3000" 3000]
+ set s2 [socket -server "accept 3001" 3001]
+ set s3 [socket -server "accept 3002" 3002]
+ proc accept {mp s a p} {
+ puts $s $mp
+ close $s
+ }
+ }
+ set s1 [socket $remoteServerIP 3000]
+ set s2 [socket $remoteServerIP 3001]
+ set s3 [socket $remoteServerIP 3002]
+ set l ""
+ lappend l [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
+ [gets $s3] [gets $s3] [eof $s3]
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {
+ close $s1
+ close $s2
+ close $s3
+ }
+ set l
+} {3000 {} 1 3001 {} 1 3002 {} 1}
+test socket-9.11 {accept callback error} {
+ set s [socket -server accept 2828]
+ proc accept {s a p} {expr 10 / 0}
+ proc bgerror args {
+ global x
+ set x $args
+ }
+ if {[catch {sendCommand {
+ set peername [fconfigure $callerSocket -peername]
+ set s [socket [lindex $peername 0] 2828]
+ close $s
+ }} msg]} {
+ close $s
+ error $msg
+ }
+ vwait x
+ close $s
+ rename bgerror {}
+ set x
+} {{divide by zero}}
+test socket-9.12 {testing socket specific options} {
+ sendCommand {
+ set socket9_12_test_server [socket -server accept 2828]
+ proc accept {s a p} {close $s}
+ }
+ set s [socket $remoteServerIP 2828]
+ set p [fconfigure $s -peername]
+ set n [fconfigure $s -sockname]
+ set l ""
+ lappend l [lindex $p 2] [llength $p] [llength $p]
+ close $s
+ sendCommand {close $socket9_12_test_server}
+ set l
+} {2828 3 3}
+
+if {$remotePid != -1} {
+ puts $commandSocket exit
+ flush $commandSocket
+}
+catch {close $commandSocket}
+
+set x ""
+unset x
diff --git a/contrib/tcl/tests/source.test b/contrib/tcl/tests/source.test
new file mode 100644
index 0000000..f335c0e
--- /dev/null
+++ b/contrib/tcl/tests/source.test
@@ -0,0 +1,180 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) source.test 1.22 96/04/05 15:27:13
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test source-1.1 {source command} {
+ set x "old x value"
+ set y "old y value"
+ set z "old z value"
+ makeFile {
+ set x 22
+ set y 33
+ set z 44
+ } source.file
+ source source.file
+ list $x $y $z
+} {22 33 44}
+test source-1.2 {source command} {
+ makeFile {list result} source.file
+ source source.file
+} result
+
+# The mac version of source returns a differnt result for
+# the next two tests.
+
+if {$tcl_platform(platform) == "macintosh"} {
+ set retMsg1 {1 {wrong # args: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
+ set retMsg2 {1 {bad argument: should be "source fileName" or "source -rsrc name ?fileName?" or "source -rsrcid id ?fileName?"}}
+} else {
+ set retMsg1 {1 {wrong # args: should be "source fileName"}}
+ set retMsg2 {1 {wrong # args: should be "source fileName"}}
+}
+test source-2.1 {source error conditions} {
+ list [catch {source} msg] $msg
+} $retMsg1
+test source-2.2 {source error conditions} {
+ list [catch {source a b} msg] $msg
+} $retMsg2
+test source-2.3 {source error conditions} {
+ makeFile {
+ set x 146
+ error "error in sourced file"
+ set y $x
+ } source.file
+ list [catch {source source.file} msg] $msg $errorInfo
+} {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 source.file"}}
+test source-2.4 {source error conditions} {
+ makeFile {break} source.file
+ catch {source source.file}
+} 3
+test source-2.5 {source error conditions} {
+ makeFile {continue} source.file
+ catch {source source.file}
+} 4
+test source-2.6 {source error conditions} {
+ normalizeMsg [list [catch {source _non_existent_} msg] $msg $errorCode]
+} {1 {couldn't read file "_non_existent_": no such file or directory} {posix enoent {no such file or directory}}}
+
+test source-3.1 {return in middle of source file} {
+ makeFile {
+ set x new-x
+ return allDone
+ set y new-y
+ } source.file
+ set x old-x
+ set y old-y
+ set z [source source.file]
+ list $x $y $z
+} {new-x old-y allDone}
+test source-3.2 {return with special code etc.} {
+ makeFile {
+ set x new-x
+ return -code break "Silly result"
+ set y new-y
+ } source.file
+ list [catch {source source.file} msg] $msg
+} {3 {Silly result}}
+test source-3.3 {return with special code etc.} {
+ makeFile {
+ set x new-x
+ return -code error "Simulated error"
+ set y new-y
+ } source.file
+ list [catch {source source.file} msg] $msg $errorInfo $errorCode
+} {1 {Simulated error} {Simulated error
+ while executing
+"source source.file"} NONE}
+test source-3.4 {return with special code etc.} {
+ makeFile {
+ set x new-x
+ return -code error -errorinfo "Simulated errorInfo stuff"
+ set y new-y
+ } source.file
+ list [catch {source source.file} msg] $msg $errorInfo $errorCode
+} {1 {} {Simulated errorInfo stuff
+ invoked from within
+"source source.file"} NONE}
+test source-3.5 {return with special code etc.} {
+ makeFile {
+ set x new-x
+ return -code error -errorinfo "Simulated errorInfo stuff" \
+ -errorcode {a b c}
+ set y new-y
+ } source.file
+ list [catch {source source.file} msg] $msg $errorInfo $errorCode
+} {1 {} {Simulated errorInfo stuff
+ invoked from within
+"source source.file"} {a b c}}
+
+# Test for the Macintosh specfic features of the source command
+test source-4.1 {source error conditions} {macOnly} {
+ list [catch {source -rsrc _no_exist_} msg] $msg
+} [list 1 "The resource \"_no_exist_\" could not be loaded from application."]
+test source-4.2 {source error conditions} {macOnly} {
+ list [catch {source -rsrcid bad_id} msg] $msg
+} [list 1 "expected integer but got \"bad_id\""]
+test source-4.3 {source error conditions} {macOnly} {
+ list [catch {source -rsrc rsrcName fileName extra} msg] $msg
+} $retMsg1
+test source-4.4 {source error conditions} {macOnly} {
+ list [catch {source non_switch rsrcName} msg] $msg
+} $retMsg2
+test source-4.5 {source error conditions} {macOnly} {
+ list [catch {source -bad_switch argument} msg] $msg
+} $retMsg2
+test source-5.1 {source resource files} {macOnly} {
+ list [catch {source -rsrc rsrcName bad_file} msg] $msg
+} [list 1 "Error finding the file: \"bad_file\"."]
+test source-5.2 {source resource files} {macOnly} {
+ makeFile {return} source.file
+ list [catch {source -rsrc rsrcName source.file} msg] $msg
+} [list 1 "Error reading the file: \"source.file\"."]
+test source-5.3 {source resource files} {macOnly} {
+ testWriteTextResource -rsrc rsrcName -file rsrc.file {set msg2 ok; return}
+ set result [catch {source -rsrc rsrcName rsrc.file} msg]
+ rm rsrc.file
+ list $msg2 $result $msg
+} [list ok 0 {}]
+test source-5.4 {source resource files} {macOnly} {
+ catch {unset msg2}
+ testWriteTextResource -rsrc fileRsrcName -file rsrc.file {set msg2 ok; return}
+ source -rsrc fileRsrcName rsrc.file
+ set result [catch {source -rsrc fileRsrcName} msg]
+ rm rsrc.file
+ list $msg2 $result $msg
+} [list ok 1 {The resource "fileRsrcName" could not be loaded from application.}]
+test source-5.5 {source resource files} {macOnly} {
+ testWriteTextResource -rsrcid 200 -file rsrc.file {set msg2 hello; set msg3 bye}
+ set result [catch {source -rsrcid 200 rsrc.file} msg]
+ rm rsrc.file
+ list $msg2 $result $msg
+} [list hello 0 bye]
+test source-5.6 {source resource files} {macOnly} {
+ testWriteTextResource -rsrcid 200 -file rsrc.file {set msg2 hello; error bad; set msg3 bye}
+ set result [catch {source -rsrcid 200 rsrc.file} msg]
+ rm rsrc.file
+ list $msg2 $result $msg
+} [list hello 1 bad]
+
+catch {exec rm source.file}
+
+# Generate null final value
+
+concat {}
diff --git a/contrib/tcl/tests/split.test b/contrib/tcl/tests/split.test
new file mode 100644
index 0000000..e87fcd4
--- /dev/null
+++ b/contrib/tcl/tests/split.test
@@ -0,0 +1,44 @@
+# 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 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) split.test 1.8 96/02/16 08:56:28
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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-2.1 {split errors} {
+ list [catch split msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} NONE}
+test split-2.2 {split errors} {
+ list [catch {split a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} NONE}
diff --git a/contrib/tcl/tests/string.test b/contrib/tcl/tests/string.test
new file mode 100644
index 0000000..77e1bc7
--- /dev/null
+++ b/contrib/tcl/tests/string.test
@@ -0,0 +1,375 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) string.test 1.12 96/02/16 08:56:29
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test string-1.1 {string compare} {
+ string compare abcde abdef
+} -1
+test string-1.2 {string compare} {
+ string c abcde ABCDE
+} 1
+test string-1.3 {string compare} {
+ string compare abcde abcde
+} 0
+test string-1.4 {string compare} {
+ list [catch {string compare a} msg] $msg
+} {1 {wrong # args: should be "string compare string1 string2"}}
+test string-1.5 {string compare} {
+ list [catch {string compare a b c} msg] $msg
+} {1 {wrong # args: should be "string compare string1 string2"}}
+
+test string-2.1 {string first} {
+ string first bq abcdefgbcefgbqrs
+} 12
+test string-2.2 {string first} {
+ string fir bcd abcdefgbcefgbqrs
+} 1
+test string-2.3 {string first} {
+ string f b abcdefgbcefgbqrs
+} 1
+test string-2.4 {string first} {
+ string first xxx x123xx345xxx789xxx012
+} 9
+test string-2.5 {string first} {
+ list [catch {string first a} msg] $msg
+} {1 {wrong # args: should be "string first string1 string2"}}
+test string-2.6 {string first} {
+ list [catch {string first a b c} msg] $msg
+} {1 {wrong # args: should be "string first string1 string2"}}
+
+test string-3.1 {string index} {
+ string index abcde 0
+} a
+test string-3.2 {string index} {
+ string i abcde 4
+} e
+test string-3.3 {string index} {
+ string index abcde 5
+} {}
+test string-3.4 {string index} {
+ list [catch {string index abcde -10} msg] $msg
+} {0 {}}
+test string-3.5 {string index} {
+ list [catch {string index} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-3.6 {string index} {
+ list [catch {string index a b c} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-3.7 {string index} {
+ list [catch {string index a xyz} msg] $msg
+} {1 {expected integer but got "xyz"}}
+
+test string-4.1 {string last} {
+ string la xxx xxxx123xx345x678
+} 1
+test string-4.2 {string last} {
+ string last xx xxxx123xx345x678
+} 7
+test string-4.3 {string last} {
+ string las x xxxx123xx345x678
+} 12
+test string-4.4 {string last} {
+ list [catch {string last a} msg] $msg
+} {1 {wrong # args: should be "string last string1 string2"}}
+test string-4.5 {string last} {
+ list [catch {string last a b c} msg] $msg
+} {1 {wrong # args: should be "string last string1 string2"}}
+
+test string-5.1 {string length} {
+ string length "a little string"
+} 15
+test string-5.2 {string length} {
+ string le ""
+} 0
+test string-5.3 {string length} {
+ list [catch {string length} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-5.4 {string length} {
+ list [catch {string length a b} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+
+test string-6.1 {string match} {
+ string match abc abc
+} 1
+test string-6.2 {string match} {
+ string m abc abd
+} 0
+test string-6.3 {string match} {
+ string match ab*c abc
+} 1
+test string-6.4 {string match} {
+ string match ab**c abc
+} 1
+test string-6.5 {string match} {
+ string match ab* abcdef
+} 1
+test string-6.6 {string match} {
+ string match *c abc
+} 1
+test string-6.7 {string match} {
+ string match *3*6*9 0123456789
+} 1
+test string-6.8 {string match} {
+ string match *3*6*9 01234567890
+} 0
+test string-6.9 {string match} {
+ string match a?c abc
+} 1
+test string-6.10 {string match} {
+ string match a??c abc
+} 0
+test string-6.11 {string match} {
+ string match ?1??4???8? 0123456789
+} 1
+test string-6.12 {string match} {
+ string match {[abc]bc} abc
+} 1
+test string-6.13 {string match} {
+ string match {a[abc]c} abc
+} 1
+test string-6.14 {string match} {
+ string match {a[xyz]c} abc
+} 0
+test string-6.15 {string match} {
+ string match {12[2-7]45} 12345
+} 1
+test string-6.16 {string match} {
+ string match {12[ab2-4cd]45} 12345
+} 1
+test string-6.17 {string match} {
+ string match {12[ab2-4cd]45} 12b45
+} 1
+test string-6.18 {string match} {
+ string match {12[ab2-4cd]45} 12d45
+} 1
+test string-6.19 {string match} {
+ string match {12[ab2-4cd]45} 12145
+} 0
+test string-6.20 {string match} {
+ string match {12[ab2-4cd]45} 12545
+} 0
+test string-6.21 {string match} {
+ string match {a\*b} a*b
+} 1
+test string-6.22 {string match} {
+ string match {a\*b} ab
+} 0
+test string-6.23 {string match} {
+ string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test string-6.24 {string match} {
+ string match ** ""
+} 1
+test string-6.25 {string match} {
+ string match *. ""
+} 0
+test string-6.26 {string match} {
+ string match "" ""
+} 1
+test string-6.27 {string match} {
+ string match \[a a
+} 1
+test string-6.28 {string match} {
+ list [catch {string match a} msg] $msg
+} {1 {wrong # args: should be "string match pattern string"}}
+test string-6.29 {string match} {
+ list [catch {string match a b c} msg] $msg
+} {1 {wrong # args: should be "string match pattern string"}}
+
+test string-7.1 {string range} {
+ string range abcdefghijklmnop 2 14
+} {cdefghijklmno}
+test string-7.2 {string range} {
+ string range abcdefghijklmnop 7 1000
+} {hijklmnop}
+test string-7.3 {string range} {
+ string range abcdefghijklmnop 10 e
+} {klmnop}
+test string-7.4 {string range} {
+ string range abcdefghijklmnop 10 9
+} {}
+test string-7.5 {string range} {
+ string range abcdefghijklmnop -3 2
+} {abc}
+test string-7.6 {string range} {
+ string range abcdefghijklmnop -3 -2
+} {}
+test string-7.7 {string range} {
+ string range abcdefghijklmnop 1000 1010
+} {}
+test string-7.8 {string range} {
+ string range abcdefghijklmnop -100 end
+} {abcdefghijklmnop}
+test string-7.9 {string range} {
+ list [catch {string range} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-7.10 {string range} {
+ list [catch {string range a 1} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-7.11 {string range} {
+ list [catch {string range a 1 2 3} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-7.12 {string range} {
+ list [catch {string range abc abc 1} msg] $msg
+} {1 {expected integer but got "abc"}}
+test string-7.13 {string range} {
+ list [catch {string range abc 1 eof} msg] $msg
+} {1 {expected integer or "end" but got "eof"}}
+
+test string-8.1 {string trim} {
+ string trim " XYZ "
+} {XYZ}
+test string-8.2 {string trim} {
+ string trim "\t\nXYZ\t\n\r\n"
+} {XYZ}
+test string-8.3 {string trim} {
+ string trim " A XYZ A "
+} {A XYZ A}
+test string-8.4 {string trim} {
+ string trim "XXYYZZABC XXYYZZ" ZYX
+} {ABC }
+test string-8.5 {string trim} {
+ string trim " \t\r "
+} {}
+test string-8.6 {string trim} {
+ string trim {abcdefg} {}
+} {abcdefg}
+test string-8.7 {string trim} {
+ string trim {}
+} {}
+test string-8.8 {string trim} {
+ string trim ABC DEF
+} {ABC}
+test string-8.9 {string trim} {
+ list [catch {string trim} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-8.10 {string trim} {
+ list [catch {string trim a b c} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+
+test string-9.1 {string trimleft} {
+ string trimleft " XYZ "
+} {XYZ }
+test string-9.2 {string trimleft} {
+ list [catch {string triml} msg] $msg
+} {1 {wrong # args: should be "string trimleft string ?chars?"}}
+
+test string-10.1 {string trimright} {
+ string trimright " XYZ "
+} { XYZ}
+test string-10.2 {string trimright} {
+ string trimright " "
+} {}
+test string-10.3 {string trimright} {
+ string trimright ""
+} {}
+test string-10.4 {string trimright errors} {
+ list [catch {string trimr} msg] $msg
+} {1 {wrong # args: should be "string trimright string ?chars?"}}
+test string-10.5 {string trimright errors} {
+ list [catch {string trimg a} msg] $msg
+} {1 {bad option "trimg": should be compare, first, index, last, length, match, range, tolower, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+
+test string-11.1 {string tolower} {
+ string tolower ABCDeF
+} {abcdef}
+test string-11.2 {string tolower} {
+ string tolower "ABC XyZ"
+} {abc xyz}
+test string-11.3 {string tolower} {
+ string tolower {123#$&*()}
+} {123#$&*()}
+test string-11.4 {string tolower} {
+ list [catch {string tolower} msg] $msg
+} {1 {wrong # args: should be "string tolower string"}}
+test string-11.5 {string tolower} {
+ list [catch {string tolower a b} msg] $msg
+} {1 {wrong # args: should be "string tolower string"}}
+
+test string-12.1 {string toupper} {
+ string toupper abCDEf
+} {ABCDEF}
+test string-12.2 {string toupper} {
+ string toupper "abc xYz"
+} {ABC XYZ}
+test string-12.3 {string toupper} {
+ string toupper {123#$&*()}
+} {123#$&*()}
+test string-12.4 {string toupper} {
+ list [catch {string toupper} msg] $msg
+} {1 {wrong # args: should be "string toupper string"}}
+test string-12.5 {string toupper} {
+ list [catch {string toupper a b} msg] $msg
+} {1 {wrong # args: should be "string toupper string"}}
+
+test string-13.1 {string wordend} {
+ list [catch {string wordend a} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-13.2 {string wordend} {
+ list [catch {string wordend a b c} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-13.3 {string wordend} {
+ list [catch {string wordend a gorp} msg] $msg
+} {1 {expected integer but got "gorp"}}
+test string-13.4 {string wordend} {
+ string wordend abc. -1
+} 3
+test string-13.5 {string wordend} {
+ string wordend abc. 100
+} 4
+test string-13.6 {string wordend} {
+ string wordend "word_one two three" 2
+} 8
+test string-13.7 {string wordend} {
+ string wordend "one .&# three" 5
+} 6
+test string-13.8 {string wordend} {
+ string worde "x.y" 0
+} 1
+
+test string-14.1 {string wordstart} {
+ list [catch {string word a} msg] $msg
+} {1 {bad option "word": should be compare, first, index, last, length, match, range, tolower, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-14.2 {string wordstart} {
+ list [catch {string wordstart a} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-14.3 {string wordstart} {
+ list [catch {string wordstart a b c} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-14.4 {string wordstart} {
+ list [catch {string wordstart a gorp} msg] $msg
+} {1 {expected integer but got "gorp"}}
+test string-14.5 {string wordstart} {
+ string wordstart "one two three_words" 400
+} 8
+test string-14.6 {string wordstart} {
+ string wordstart "one two three_words" 2
+} 0
+test string-14.7 {string wordend} {
+ string wordstart "one two three_words" -2
+} 0
+test string-14.8 {string wordend} {
+ string wordstart "one .*&^ three" 6
+} 6
+test string-14.9 {string wordend} {
+ string wordstart "one two three" 4
+} 4
+
+test string-15.1 {error conditions} {
+ list [catch {string gorp a b} msg] $msg
+} {1 {bad option "gorp": should be compare, first, index, last, length, match, range, tolower, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-15.2 {error conditions} {
+ list [catch {string} msg] $msg
+} {1 {wrong # args: should be "string option arg ?arg ...?"}}
diff --git a/contrib/tcl/tests/subst.test b/contrib/tcl/tests/subst.test
new file mode 100644
index 0000000..5c7f556
--- /dev/null
+++ b/contrib/tcl/tests/subst.test
@@ -0,0 +1,106 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) subst.test 1.7 96/02/16 08:56:30
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test subst-1.1 {basics} {
+ list [catch {subst} msg] $msg
+} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
+test subst-1.2 {basics} {
+ list [catch {subst a b c} msg] $msg
+} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
+
+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-3.1 {backslash substitutions} {
+ subst {\x\$x\[foo bar]\\}
+} "x\$x\[foo bar]\\"
+
+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} {
+ catch {unset a}
+ set a(13) 82
+ set i 13
+ subst {x.$a($i)}
+} {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} {
+ list [catch {subst {$long $a}} msg] $msg
+} {1 {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.3 {command substitutions} {
+ list [catch {subst {$long [set long] [bogus_command]}} msg] $msg
+} {1 {invalid command name "bogus_command"}}
+
+test subst-6.1 {clear the result after command substitution} {
+ catch {unset a}
+ list [catch {subst {[concat foo] $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+
+test subst-7.1 {switches} {
+ list [catch {subst foo bar} msg] $msg
+} {1 {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}}
+test subst-7.2 {switches} {
+ list [catch {subst -no bar} msg] $msg
+} {1 {bad switch "-no": must be -nobackslashes, -nocommands, or -novariables}}
+test subst-7.3 {switches} {
+ list [catch {subst -bogus bar} msg] $msg
+} {1 {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}
diff --git a/contrib/tcl/tests/switch.test b/contrib/tcl/tests/switch.test
new file mode 100644
index 0000000..740ecb1
--- /dev/null
+++ b/contrib/tcl/tests/switch.test
@@ -0,0 +1,170 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) switch.test 1.5 96/02/16 08:56:31
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test switch-1.1 {simple patterns} {
+ switch a a {format 1} b {format 2} c {format 3} default {format 4}
+} 1
+test switch-1.2 {simple patterns} {
+ switch b a {format 1} b {format 2} c {format 3} default {format 4}
+} 2
+test switch-1.3 {simple patterns} {
+ switch x a {format 1} b {format 2} c {format 3} default {format 4}
+} 4
+test switch-1.4 {simple patterns} {
+ switch x a {format 1} b {format 2} c {format 3}
+} {}
+test switch-1.5 {simple pattern matches many times} {
+ switch b a {format 1} b {format 2} b {format 3} b {format 4}
+} 2
+test switch-1.6 {simple patterns} {
+ switch default a {format 1} default {format 2} c {format 3} default {format 4}
+} 2
+test switch-1.7 {simple patterns} {
+ switch x a {format 1} default {format 2} c {format 3} default {format 4}
+} 4
+
+test switch-2.1 {single-argument form for pattern/command pairs} {
+ switch b {
+ a {format 1}
+ b {format 2}
+ default {format 6}
+ }
+} {2}
+test switch-2.2 {single-argument form for pattern/command pairs} {
+ list [catch {switch z {a 2 b}} msg] $msg
+} {1 {extra switch pattern with no body}}
+
+test switch-3.1 {-exact vs. -glob vs. -regexp} {
+ switch -exact aaaab {
+ ^a*b$ {concat regexp}
+ *b {concat glob}
+ aaaab {concat exact}
+ default {concat none}
+ }
+} exact
+test switch-3.2 {-exact vs. -glob vs. -regexp} {
+ switch -exact -regexp aaaab {
+ ^a*b$ {concat regexp}
+ *b {concat glob}
+ aaaab {concat exact}
+ default {concat none}
+ }
+} regexp
+test switch-3.3 {-exact vs. -glob vs. -regexp} {
+ switch -glob aaaab {
+ ^a*b$ {concat regexp}
+ *b {concat glob}
+ aaaab {concat exact}
+ default {concat none}
+ }
+} glob
+test switch-3.4 {-exact vs. -glob vs. -regexp} {
+ switch aaaab {^a*b$} {concat regexp} *b {concat glob} \
+ aaaab {concat exact} default {concat none}
+} exact
+test switch-3.5 {-exact vs. -glob vs. -regexp} {
+ switch -- -glob {
+ ^g.*b$ {concat regexp}
+ -* {concat glob}
+ -glob {concat exact}
+ default {concat none}
+ }
+} exact
+test switch-3.6 {-exact vs. -glob vs. -regexp} {
+ list [catch {switch -foo a b c} msg] $msg
+} {1 {bad option "-foo": should be -exact, -glob, -regexp, or --}}
+
+test switch-4.1 {error in executed command} {
+ list [catch {switch a 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
+"switch a a {error "Just a test"} default {format 1}"}}
+test switch-4.2 {error: not enough args} {
+ list [catch {switch} msg] $msg
+} {1 {wrong # args: should be "switch ?switches? string pattern body ... ?default body?"}}
+test switch-4.3 {error: pattern with no body} {
+ list [catch {switch a b} msg] $msg
+} {1 {extra switch pattern with no body}}
+test switch-4.4 {error: pattern with no body} {
+ list [catch {switch a b {format 1} c} msg] $msg
+} {1 {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} {
+ list [catch {switch -regexp aaaab {
+ *b {concat glob}
+ aaaab {concat exact}
+ default {concat none}
+ }} msg] $msg
+} {1 {couldn't compile regular expression pattern: ?+* follows nothing}}
+
+test switch-6.1 {backslashes in patterns} {
+ switch -exact {\a\$\.\[} {
+ \a\$\.\[ {concat first}
+ \a\\$\.\\[ {concat second}
+ \\a\\$\\.\\[ {concat third}
+ {\a\\$\.\\[} {concat fourth}
+ {\\a\\$\\.\\[} {concat fifth}
+ default {concat none}
+ }
+} third
+test switch-6.2 {backslashes in patterns} {
+ switch -exact {\a\$\.\[} {
+ \a\$\.\[ {concat first}
+ {\a\$\.\[} {concat second}
+ {{\a\$\.\[}} {concat third}
+ default {concat none}
+ }
+} second
+
+test switch-7.1 {"-" bodies} {
+ switch a {
+ a -
+ b -
+ c {concat 1}
+ default {concat 2}
+ }
+} 1
+test switch-7.2 {"-" bodies} {
+ list [catch {
+ switch a {
+ a -
+ b -
+ c -
+ }
+ } msg] $msg
+} {1 {no body specified for pattern "a"}}
+test switch-7.3 {"-" bodies} {
+ list [catch {
+ switch a {
+ a -
+ b -foo
+ c -
+ }
+ } msg] $msg
+} {1 {invalid command name "-foo"}}
diff --git a/contrib/tcl/tests/trace.test b/contrib/tcl/tests/trace.test
new file mode 100644
index 0000000..9077906
--- /dev/null
+++ b/contrib/tcl/tests/trace.test
@@ -0,0 +1,930 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) trace.test 1.24 96/02/16 08:56:32
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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 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
+}
+
+# Read-tracing on variables
+
+test trace-1.1 {trace variable reads} {
+ catch {unset x}
+ set info {}
+ trace var x r traceScalar
+ list [catch {set x} msg] $msg $info
+} {1 {can't read "x": no such variable} {x {} r 1 {can't read "x": no such variable}}}
+test trace-1.2 {trace variable reads} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace var x r traceScalar
+ list [catch {set x} msg] $msg $info
+} {0 123 {x {} r 0 123}}
+test trace-1.3 {trace variable reads} {
+ catch {unset x}
+ set info {}
+ trace var x r traceScalar
+ set x 123
+ set info
+} {}
+test trace-1.4 {trace array element reads} {
+ catch {unset x}
+ set info {}
+ trace var x(2) r traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such element in array} {x 2 r 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 var x(2) r traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 r 0 zzz}}
+test trace-1.6 {trace reads on whole arrays} {
+ catch {unset x}
+ set info {}
+ trace var x r traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such variable} {}}
+test trace-1.7 {trace reads on whole arrays} {
+ catch {unset x}
+ set x(2) zzz
+ set info {}
+ trace var x r traceArray
+ list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 r 0 zzz}}
+test trace-1.8 {trace variable reads} {
+ catch {unset x}
+ set x 444
+ set info {}
+ trace var x r traceScalar
+ unset x
+ set info
+} {}
+
+# Basic write-tracing on variables
+
+test trace-2.1 {trace variable writes} {
+ catch {unset x}
+ set info {}
+ trace var x w traceScalar
+ set x 123
+ set info
+} {x {} w 0 123}
+test trace-2.2 {trace writes to array elements} {
+ catch {unset x}
+ set info {}
+ trace var x(33) w traceArray
+ set x(33) 444
+ set info
+} {x 33 w 0 444}
+test trace-2.3 {trace writes on whole arrays} {
+ catch {unset x}
+ set info {}
+ trace var x w traceArray
+ set x(abc) qq
+ set info
+} {x abc w 0 qq}
+test trace-2.4 {trace variable writes} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace var x w traceScalar
+ set x
+ set info
+} {}
+test trace-2.5 {trace variable writes} {
+ catch {unset x}
+ set x 1234
+ set info {}
+ trace var x w traceScalar
+ unset x
+ set info
+} {}
+
+test trace-3.1 {trace variable read-modify-writes} {
+ catch {unset x}
+ set info {}
+ trace var x r traceScalarAppend
+ append x 123
+ append x 456
+ lappend x 789
+ set info
+} {x {} r 1 {can't read "x": no such variable} x {} r 0 123 x {} r 0 123456}
+test trace-3.2 {trace variable read-modify-writes} {
+ catch {unset x}
+ set info {}
+ trace var x rw traceScalarAppend
+ append x 123
+ lappend x 456
+ set info
+} {x {} r 1 {can't read "x": no such variable} x {} w 0 123 x {} r 0 123 x {} w 0 {123 456}}
+
+# Basic unset-tracing on variables
+
+test trace-4.1 {trace variable unsets} {
+ catch {unset x}
+ set info {}
+ trace var x u traceScalar
+ catch {unset x}
+ set info
+} {x {} u 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 var x u traceScalar
+ unset x
+ set info
+} {x {} u 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 var x u 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 var x(1) u traceArray
+ catch {unset x(1)}
+ set info
+} {x 1 u 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 var x(1) u traceArray
+ unset x(1)
+ set info
+} {x 1 u 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 var x(1) u traceArray
+ unset x
+ set info
+} {x 1 u 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 var x u 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 var x u traceProc
+ unset x(1)
+ set info
+} {x 1 u}
+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 var x u traceProc
+ unset x
+ set info
+} {x {} u}
+
+# Trace multiple trace types at once.
+
+test trace-5.1 {multiple ops traced at once} {
+ catch {unset x}
+ set info {}
+ trace var x rwu traceProc
+ catch {set x}
+ set x 22
+ set x
+ set x 33
+ unset x
+ set info
+} {x {} r x {} w x {} r x {} w x {} u}
+test trace-5.2 {multiple ops traced on array element} {
+ catch {unset x}
+ set info {}
+ trace var x(0) rwu 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 r x 0 w x 0 r x 0 w x 0 u}
+test trace-5.3 {multiple ops traced on whole array} {
+ catch {unset x}
+ set info {}
+ trace var x rwu 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 w x 0 r x 0 w x 0 u x {} u}
+
+# Check order of invocation of traces
+
+test trace-6.1 {order of invocation of traces} {
+ catch {unset x}
+ set info {}
+ trace var x r "traceTag 1"
+ trace var x r "traceTag 2"
+ trace var x r "traceTag 3"
+ catch {set x}
+ set x 22
+ set x
+ set info
+} {3 2 1 3 2 1}
+test trace-6.2 {order of invocation of traces} {
+ catch {unset x}
+ set x(0) 44
+ set info {}
+ trace var x(0) r "traceTag 1"
+ trace var x(0) r "traceTag 2"
+ trace var x(0) r "traceTag 3"
+ set x(0)
+ set info
+} {3 2 1}
+test trace-6.3 {order of invocation of traces} {
+ catch {unset x}
+ set x(0) 44
+ set info {}
+ trace var x(0) r "traceTag 1"
+ trace var x r "traceTag A1"
+ trace var x(0) r "traceTag 2"
+ trace var x r "traceTag A2"
+ trace var x(0) r "traceTag 3"
+ trace var x r "traceTag A3"
+ set x(0)
+ set info
+} {A3 A2 A1 3 2 1}
+
+# Check effects of errors in trace procedures
+
+test trace-7.1 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace var x r "traceTag 1"
+ trace var x r traceError
+ list [catch {set x} msg] $msg $info
+} {1 {can't read "x": trace returned error} {}}
+test trace-7.2 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace var x w "traceTag 1"
+ trace var x w traceError
+ list [catch {set x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-7.3 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace var x r traceError
+ trace var x w traceScalar
+ list [catch {append x 44} msg] $msg $info
+} {1 {can't read "x": trace returned error} {}}
+test trace-7.4 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ set info {}
+ trace var x u "traceTag 1"
+ trace var x u traceError
+ list [catch {unset x} msg] $msg $info
+} {0 {} 1}
+test trace-7.5 {error returns from traces} {
+ catch {unset x}
+ set x(0) 123
+ set info {}
+ trace var x(0) r "traceTag 1"
+ trace var x r "traceTag 2"
+ trace var x r traceError
+ trace var x r "traceTag 3"
+ list [catch {set x(0)} msg] $msg $info
+} {1 {can't read "x(0)": trace returned error} 3}
+test trace-7.6 {error returns from traces} {
+ catch {unset x}
+ set x 123
+ trace var x u traceError
+ list [catch {unset x} msg] $msg
+} {0 {}}
+test trace-7.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 var x r traceError
+ catch {set x}
+ catch {set x}
+ trace vdelete x r traceError
+} {}
+
+# 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-8.1 {be sure variable is unset before trace is called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace var x u {traceCheck {uplevel set x}}
+ unset x
+ set info
+} {1 {can't read "x": no such variable}}
+test trace-8.2 {be sure variable is unset before trace is called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace var x u {traceCheck {uplevel set x 22}}
+ unset x
+ concat $info [list [catch {set x} msg] $msg]
+} {0 22 0 22}
+test trace-8.3 {be sure traces are cleared before unset trace called} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace var x u {traceCheck {uplevel trace vinfo x}}
+ unset x
+ set info
+} {0 {}}
+test trace-8.4 {set new trace during unset trace} {
+ catch {unset x}
+ set x 33
+ set info {}
+ trace var x u {traceCheck {global x; trace var x u traceProc}}
+ unset x
+ concat $info [trace vinfo x]
+} {0 {} {u traceProc}}
+
+test trace-9.1 {make sure array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace var x(0) u {traceCheck {uplevel set x(0)}}
+ unset x(0)
+ set info
+} {1 {can't read "x(0)": no such element in array}}
+test trace-9.2 {make sure array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace var x(0) u {traceCheck {uplevel set x(0) zzz}}
+ unset x(0)
+ concat $info [list [catch {set x(0)} msg] $msg]
+} {0 zzz 0 zzz}
+test trace-9.3 {array elements are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace var x(0) u {traceCheck {global x; trace vinfo x(0)}}
+ unset x(0)
+ set info
+} {0 {}}
+test trace-9.4 {set new array element trace during unset trace} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace var x(0) u {traceCheck {uplevel {trace variable x(0) r {}}}}
+ catch {unset x(0)}
+ concat $info [trace vinfo x(0)]
+} {0 {} {r {}}}
+
+test trace-10.1 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(0) 33
+ set info {}
+ trace var x u {traceCheck {uplevel set x(0)}}
+ unset x
+ set info
+} {1 {can't read "x(0)": no such variable}}
+test trace-10.2 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace var x u {traceCheck {uplevel set x(y) 22}}
+ unset x
+ concat $info [list [catch {set x(y)} msg] $msg]
+} {0 22 0 22}
+test trace-10.3 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace var x u {traceCheck {uplevel array exists x}}
+ unset x
+ set info
+} {0 0}
+test trace-10.4 {make sure arrays are unset before traces are called} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ set cmd {traceCheck {uplevel {trace vinfo x}}}
+ trace var x u $cmd
+ unset x
+ set info
+} {0 {}}
+test trace-10.5 {set new array trace during unset trace} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace var x u {traceCheck {global x; trace var x r {}}}
+ unset x
+ concat $info [trace vinfo x]
+} {0 {} {r {}}}
+test trace-10.6 {create scalar during array unset trace} {
+ catch {unset x}
+ set x(y) 33
+ set info {}
+ trace var x u {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-11.1 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace var x(0) w traceProc
+ list [catch {set x 22} msg] $msg
+} {1 {can't set "x": variable is array}}
+test trace-11.2 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace var x(0) w traceProc
+ list [catch {set x(0)} msg] $msg
+} {1 {can't read "x(0)": no such element in array}}
+test trace-11.3 {creating array when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace var x(0) w traceProc
+ set x(0) 22
+ set info
+} {x 0 w}
+test trace-11.4 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace var x w traceProc
+ list [catch {set x} msg] $msg
+} {1 {can't read "x": no such variable}}
+test trace-11.5 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace var x w traceProc
+ set x 22
+ set info
+} {x {} w}
+test trace-11.6 {creating variable when setting variable traces} {
+ catch {unset x}
+ set info {}
+ trace var x w traceProc
+ set x(0) 22
+ set info
+} {x 0 w}
+test trace-11.7 {create array element during read trace} {
+ catch {unset x}
+ set x(2) zzz
+ trace var x r {traceCrtElement xyzzy}
+ list [catch {set x(3)} msg] $msg
+} {0 xyzzy}
+test trace-11.8 {errors when setting variable traces} {
+ catch {unset x}
+ set x 44
+ list [catch {trace var x(0) w traceProc} msg] $msg
+} {1 {can't trace "x(0)": variable isn't array}}
+
+# Check deleting one trace from another.
+
+test trace-12.1 {delete one trace from another} {
+ proc delTraces {args} {
+ global x
+ trace vdel x r {traceTag 2}
+ trace vdel x r {traceTag 3}
+ trace vdel x r {traceTag 4}
+ }
+ catch {unset x}
+ set x 44
+ set info {}
+ trace var x r {traceTag 1}
+ trace var x r {traceTag 2}
+ trace var x r {traceTag 3}
+ trace var x r {traceTag 4}
+ trace var x r delTraces
+ trace var x r {traceTag 5}
+ set x
+ set info
+} {5 1}
+
+# Check operation and syntax of "trace" command.
+
+test trace-13.1 {trace command (overall)} {
+ list [catch {trace} msg] $msg
+} {1 {too few args: should be "trace option [arg arg ...]"}}
+test trace-13.2 {trace command (overall)} {
+ list [catch {trace gorp} msg] $msg
+} {1 {bad option "gorp": should be variable, vdelete, or vinfo}}
+test trace-13.3 {trace command ("variable" option)} {
+ list [catch {trace variable x y} msg] $msg
+} {1 {wrong # args: should be "trace variable name ops command"}}
+test trace-13.4 {trace command ("variable" option)} {
+ list [catch {trace var x y z z2} msg] $msg
+} {1 {wrong # args: should be "trace variable name ops command"}}
+test trace-13.5 {trace command ("variable" option)} {
+ list [catch {trace var x y z} msg] $msg
+} {1 {bad operations "y": should be one or more of rwu}}
+test trace-13.6 {trace command ("vdelete" option)} {
+ list [catch {trace vdelete x y} msg] $msg
+} {1 {wrong # args: should be "trace vdelete name ops command"}}
+test trace-13.7 {trace command ("vdelete" option)} {
+ list [catch {trace vdelete x y z foo} msg] $msg
+} {1 {wrong # args: should be "trace vdelete name ops command"}}
+test trace-13.8 {trace command ("vdelete" option)} {
+ list [catch {trace vdelete x y z} msg] $msg
+} {1 {bad operations "y": should be one or more of rwu}}
+test trace-13.9 {trace command ("vdelete" option)} {
+ catch {unset x}
+ set info {}
+ trace var x w traceProc
+ trace vdelete x w traceProc
+} {}
+test trace-13.10 {trace command ("vdelete" option)} {
+ catch {unset x}
+ set info {}
+ trace var x w traceProc
+ trace vdelete x w traceProc
+ set x 12345
+ set info
+} {}
+test trace-13.11 {trace command ("vdelete" option)} {
+ catch {unset x}
+ set info {}
+ trace var x w {traceTag 1}
+ trace var x w traceProc
+ trace var x w {traceTag 2}
+ set x yy
+ trace vdelete x w traceProc
+ set x 12345
+ trace vdelete x w {traceTag 1}
+ set x foo
+ trace vdelete x w {traceTag 2}
+ set x gorp
+ set info
+} {2 x {} w 1 2 1 2}
+test trace-13.12 {trace command ("vdelete" option)} {
+ catch {unset x}
+ set info {}
+ trace var x w {traceTag 1}
+ trace vdelete x w non_existent
+ set x 12345
+ set info
+} {1}
+test trace-13.13 {trace command ("vinfo" option)} {
+ list [catch {trace vinfo} msg] $msg]
+} {1 {wrong # args: should be "trace vinfo name"]}}
+test trace-13.14 {trace command ("vinfo" option)} {
+ list [catch {trace vinfo x y} msg] $msg]
+} {1 {wrong # args: should be "trace vinfo name"]}}
+test trace-13.15 {trace command ("vinfo" option)} {
+ catch {unset x}
+ trace var x w {traceTag 1}
+ trace var x w traceProc
+ trace var x w {traceTag 2}
+ trace vinfo x
+} {{w {traceTag 2}} {w traceProc} {w {traceTag 1}}}
+test trace-13.16 {trace command ("vinfo" option)} {
+ catch {unset x}
+ trace vinfo x
+} {}
+test trace-13.17 {trace command ("vinfo" option)} {
+ catch {unset x}
+ trace vinfo x(0)
+} {}
+test trace-13.18 {trace command ("vinfo" option)} {
+ catch {unset x}
+ set x 44
+ trace vinfo x(0)
+} {}
+test trace-13.19 {trace command ("vinfo" option)} {
+ catch {unset x}
+ set x 44
+ trace var x w {traceTag 1}
+ proc check {} {global x; trace vinfo x}
+ check
+} {{w {traceTag 1}}}
+
+# Check fancy trace commands (long ones, weird arguments, etc.)
+
+test trace-14.1 {long trace command} {
+ catch {unset x}
+ set info {}
+ trace var x w {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-14.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 var x w longResult
+ set x 44
+ set x 5
+ set x abcde
+} abcde
+test trace-14.3 {special list-handling in trace commands} {
+ catch {unset "x y z"}
+ set "x y z(a\n\{)" 44
+ set info {}
+ trace var "x y z(a\n\{)" w traceProc
+ set "x y z(a\n\{)" 33
+ set info
+} "{x y z} a\\n\\{ w"
+
+# 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-15.1 {unsets during read traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y r {traceUnset y}
+ trace var y u {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-15.2 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) r {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-15.3 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) r {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-15.4 {unsets during read traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y r {traceReset y y}
+ lappend info [catch {set y} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-15.5 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) r {traceReset y(0) y(0)}
+ lappend info [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-15.6 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) r {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-15.7 {unsets during read traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) r {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-15.8 {unsets during write traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y w {traceUnset y}
+ trace var y u {traceAppend unset}
+ lappend info [catch {set y xxx} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-15.9 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) w {traceUnset y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-15.10 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) w {traceUnset y}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-15.11 {unsets during write traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y w {traceReset y y}
+ lappend info [catch {set y xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-15.12 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) w {traceReset y(0) y(0)}
+ lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-15.13 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) w {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-15.14 {unsets during write traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) w {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-15.15 {unsets during unset traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y u {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-15.16 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) u {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-15.17 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) u {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-15.18 {unsets during unset traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y u {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-15.19 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) u {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-15.20 {unsets during unset traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) u {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-15.21 {unsets cancelling traces} {
+ catch {unset y}
+ set y 1234
+ set info {}
+ trace var y r {traceAppend first}
+ trace var y r {traceUnset y}
+ trace var y r {traceAppend third}
+ trace var y u {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-15.22 {unsets cancelling traces} {
+ catch {unset y}
+ set y(0) 1234
+ set info {}
+ trace var y(0) r {traceAppend first}
+ trace var y(0) r {traceUnset y}
+ trace var y(0) r {traceAppend third}
+ trace var y(0) u {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-16.1 {trace doesn't prevent unset errors} {
+ catch {unset x}
+ set info {}
+ trace var x u {traceProc}
+ list [catch {unset x} msg] $msg $info
+} {1 {can't unset "x": no such variable} {x {} u}}
+test trace-16.2 {traced variables must survive procedure exits} {
+ catch {unset x}
+ proc p1 {} {global x; trace var x w traceProc}
+ p1
+ trace vinfo x
+} {{w traceProc}}
+test trace-16.3 {traced variables must survive procedure exits} {
+ catch {unset x}
+ set info {}
+ proc p1 {} {global x; trace var x w traceProc}
+ p1
+ set x 44
+ set info
+} {x {} w}
+
+# Be sure that procedure frames are released before unset traces
+# are invoked.
+
+test trace-17.1 {unset traces on procedure returns} {
+ proc p1 {x y} {set a 44; p2 14}
+ proc p2 {z} {trace var z u {traceCheck {lsort [uplevel {info vars}]}}}
+ set info {}
+ p1 foo bar
+ set info
+} {0 {a x y}}
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+catch {unset x}
+catch {unset y}
+concat {}
diff --git a/contrib/tcl/tests/unknown.test b/contrib/tcl/tests/unknown.test
new file mode 100644
index 0000000..fd41109
--- /dev/null
+++ b/contrib/tcl/tests/unknown.test
@@ -0,0 +1,60 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) unknown.test 1.11 96/02/16 08:56:34
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+return {}
diff --git a/contrib/tcl/tests/uplevel.test b/contrib/tcl/tests/uplevel.test
new file mode 100644
index 0000000..84daa03
--- /dev/null
+++ b/contrib/tcl/tests/uplevel.test
@@ -0,0 +1,109 @@
+# 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) uplevel.test 1.13 96/02/16 08:56:35
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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} {
+ list [catch c1 msg] $msg
+} {1 {bad level "#2"}}
+test uplevel-4.2 {error: non-existent level} {
+ proc c2 {} {uplevel 3 {set a b}}
+ list [catch c2 msg] $msg
+} {1 {bad level "3"}}
+test uplevel-4.3 {error: not enough args} {
+ list [catch uplevel msg] $msg
+} {1 {wrong # args: should be "uplevel ?level? command ?arg ...?"}}
+test uplevel-4.4 {error: not enough args} {
+ proc upBug {} {uplevel 1}
+ list [catch upBug msg] $msg
+} {1 {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
diff --git a/contrib/tcl/tests/upvar.test b/contrib/tcl/tests/upvar.test
new file mode 100644
index 0000000..accc74c
--- /dev/null
+++ b/contrib/tcl/tests/upvar.test
@@ -0,0 +1,377 @@
+# Commands covered: 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.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) upvar.test 1.11 96/02/28 21:45:36
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+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}
+ 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 [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} {
+ list [catch upvar msg] $msg
+} {1 {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}}
+test upvar-8.2 {errors in upvar command} {
+ list [catch {upvar 1} msg] $msg
+} {1 {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}}
+test upvar-8.3 {errors in upvar command} {
+ proc p1 {} {upvar a b c}
+ list [catch p1 msg] $msg
+} {1 {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}}
+test upvar-8.4 {errors in upvar command} {
+ proc p1 {} {upvar 0 b b}
+ list [catch p1 msg] $msg
+} {1 {can't upvar from variable to itself}}
+test upvar-8.5 {errors in upvar command} {
+ proc p1 {} {upvar 0 a b; upvar 0 b a}
+ list [catch p1 msg] $msg
+} {1 {can't upvar from variable to itself}}
+test upvar-8.6 {errors in upvar command} {
+ proc p1 {} {set a 33; upvar b a}
+ list [catch p1 msg] $msg
+} {1 {variable "a" already exists}}
+test upvar-8.7 {errors in upvar command} {
+ proc p1 {} {trace variable a w foo; upvar b a}
+ list [catch p1 msg] $msg
+} {1 {variable "a" has traces: can't use for upvar}}
+
+if {[info commands testupvar] != {}} {
+ test upvar-9.1 {Tcl_UpVar2 procedure} {
+ list [catch {testupvar xyz a {} x global} msg] $msg
+ } {1 {bad level "xyz"}}
+ test upvar-9.2 {Tcl_UpVar2 procedure} {
+ 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} {
+ 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} {
+ 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} {
+ 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} {
+ 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} {
+ 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}
+
+concat
diff --git a/contrib/tcl/tests/while.test b/contrib/tcl/tests/while.test
new file mode 100644
index 0000000..ad3d328
--- /dev/null
+++ b/contrib/tcl/tests/while.test
@@ -0,0 +1,99 @@
+# 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) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) while.test 1.9 96/02/16 08:56:37
+
+if {[string compare test [info procs test]] == 1} then {source defs}
+
+test while-1.1 {basic while loops} {
+ set count 0
+ while {$count < 10} {set count [expr $count+1]}
+ set count
+} 10
+test while-1.2 {basic while loops} {
+ set value xxx
+ while {2 > 3} {set value yyy}
+ set value
+} xxx
+test while-1.3 {basic while loops} {
+ set value 1
+ while {"true"} {
+ incr value;
+ if {$value > 5} {
+ break;
+ }
+ }
+ set value
+} 6
+
+test while-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-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-4.1 {errors in while loops} {
+ set err [catch {while} msg]
+ list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-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-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-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-4.5 {errors in while loops} {
+ set x 1
+ set err [catch {while {$x} {set x foo}} msg]
+ list $err $msg
+} {1 {expected boolean value but got "foo"}}
+test while-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""
+ ("while" body line 1)
+ invoked from within
+"while {1} {error "loop aborted"}"}}
+
+test while-5.1 {while return result} {
+ while {0} {set a 400}
+} {}
+test while-5.2 {while return result} {
+ set x 1
+ while {$x} {set x 0}
+} {}
OpenPOWER on IntegriCloud