1 # This file tests the multiple interpreter facility of Tcl
3 # This file contains a collection of tests for one or more of the Tcl
4 # built-in commands. Sourcing this file into Tcl runs the tests and
5 # generates output for errors. No output means no errors were found.
7 # Copyright (c) 1995-1996 Sun Microsystems, Inc.
8 # Copyright (c) 1998-1999 by Scriptics Corporation.
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 if {"::tcltest" ni [namespace children]} {
14 package require tcltest 2.1
15 namespace import -force ::tcltest::*
18 ::tcltest::loadTestedCommands
19 catch [list package require -exact Tcltest [info patchlevel]]
21 testConstraint testinterpdelete [llength [info commands testinterpdelete]]
23 set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload}
25 foreach i [interp children] {
29 # Part 0: Check out options for interp command
30 test interp-1.1 {options for interp command} -returnCodes error -body {
32 } -result {wrong # args: should be "interp cmd ?arg ...?"}
33 test interp-1.2 {options for interp command} -returnCodes error -body {
35 } -result {bad option "frobox": must be alias, aliases, bgerror, cancel, children, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
36 test interp-1.3 {options for interp command} {
39 test interp-1.4 {options for interp command} -returnCodes error -body {
41 } -result {could not find interpreter "foo"}
42 test interp-1.5 {options for interp command} -returnCodes error -body {
44 } -result {wrong # args: should be "interp exists ?path?"}
46 # test interp-0.6 was removed
48 test interp-1.6 {options for interp command} -returnCodes error -body {
49 interp children foo bar zop
50 } -result {wrong # args: should be "interp children ?path?"}
51 test interp-1.7 {options for interp command} -returnCodes error -body {
53 } -result {bad option "hello": must be alias, aliases, bgerror, cancel, children, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
54 test interp-1.8 {options for interp command} -returnCodes error -body {
56 } -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, children, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
57 test interp-1.9 {options for interp command} -returnCodes error -body {
59 } -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, children, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
60 test interp-1.10 {options for interp command} -returnCodes error -body {
62 } -result {wrong # args: should be "interp target path alias"}
64 # Part 1: Basic interpreter creation tests:
65 test interp-2.1 {basic interpreter creation} {
68 test interp-2.2 {basic interpreter creation} {
71 test interp-2.3 {basic interpreter creation} {
72 catch {interp create -safe}
74 test interp-2.4 {basic interpreter creation} -setup {
75 catch {interp create a}
76 } -returnCodes error -body {
78 } -result {interpreter named "a" already exists, cannot create}
79 test interp-2.5 {basic interpreter creation} {
82 test interp-2.6 {basic interpreter creation} {
85 test interp-2.7 {basic interpreter creation} {
86 list [catch {interp create -froboz} msg] $msg
87 } {1 {bad option "-froboz": must be -safe or --}}
88 test interp-2.8 {basic interpreter creation} {
89 interp create -- -froboz
91 test interp-2.9 {basic interpreter creation} {
92 interp create -safe -- -froboz1
94 test interp-2.10 {basic interpreter creation} -setup {
95 catch {interp create a}
99 interp create {a x3} -safe
101 test interp-2.11 {anonymous interps vs existing procs} {
102 set x [interp create]
103 regexp "interp(\[0-9]+)" $x dummy thenum
105 proc interp$thenum {} {}
106 set x [interp create]
107 regexp "interp(\[0-9]+)" $x dummy anothernum
108 expr {$anothernum > $thenum}
110 test interp-2.12 {anonymous interps vs existing procs} {
111 set x [interp create -safe]
112 regexp "interp(\[0-9]+)" $x dummy thenum
114 proc interp$thenum {} {}
115 set x [interp create -safe]
116 regexp "interp(\[0-9]+)" $x dummy anothernum
117 expr {$anothernum - $thenum}
119 test interp-2.13 {correct default when no $path arg is given} -body {
121 } -match regexp -result {interp[0-9]+}
123 foreach i [interp children] {
127 # Part 2: Testing "interp children" and "interp exists"
128 test interp-3.1 {testing interp exists and interp children} {
131 test interp-3.2 {testing interp exists and interp children} {
135 test interp-3.3 {testing interp exists and interp children} {
136 interp exists nonexistent
138 test interp-3.4 {testing interp exists and interp children} -body {
139 interp children a b c
140 } -returnCodes error -result {wrong # args: should be "interp children ?path?"}
141 test interp-3.5 {testing interp exists and interp children} -body {
143 } -returnCodes error -result {wrong # args: should be "interp exists ?path?"}
144 test interp-3.6 {testing interp exists and interp children} {
147 test interp-3.7 {testing interp exists and interp children} -setup {
148 catch {interp create a}
152 test interp-3.8 {testing interp exists and interp children} -body {
153 interp children a b c
154 } -returnCodes error -result {wrong # args: should be "interp children ?path?"}
155 test interp-3.9 {testing interp exists and interp children} -setup {
156 catch {interp create a}
158 interp create {a a2} -safe
159 expr {"a2" in [interp children a]}
161 test interp-3.10 {testing interp exists and interp children} -setup {
162 catch {interp create a}
163 catch {interp create {a a2}}
168 # Part 3: Testing "interp delete"
169 test interp-3.11 {testing interp delete} {
172 test interp-4.1 {testing interp delete} {
173 catch {interp create a}
176 test interp-4.2 {testing interp delete} -returnCodes error -body {
177 interp delete nonexistent
178 } -result {could not find interpreter "nonexistent"}
179 test interp-4.3 {testing interp delete} -returnCodes error -body {
181 } -result {could not find interpreter "x"}
182 test interp-4.4 {testing interp delete} {
185 test interp-4.5 {testing interp delete} {
189 expr {"x1" in [interp children a]}
191 test interp-4.6 {testing interp delete} {
195 interp delete c1 c2 c3
197 test interp-4.7 {testing interp delete} -returnCodes error -body {
200 interp delete c1 c2 c3
201 } -result {could not find interpreter "c3"}
202 test interp-4.8 {testing interp delete} -returnCodes error -body {
204 } -result {cannot delete the current interpreter}
206 foreach i [interp children] {
210 # Part 4: Consistency checking - all nondeleted interpreters should be
212 test interp-5.1 {testing consistency} {
215 test interp-5.2 {testing consistency} {
218 test interp-5.3 {testing consistency} {
219 interp exists nonexistent
222 # Recreate interpreter "a"
225 # Part 5: Testing eval in interpreter object command and with interp command
226 test interp-6.1 {testing eval} {
227 a eval expr {{3 + 5}}
229 test interp-6.2 {testing eval} -returnCodes error -body {
231 } -result {invalid command name "foo"}
232 test interp-6.3 {testing eval} {
233 a eval {proc foo {} {expr {3 + 5}}}
236 catch {a eval {proc foo {} {expr {3 + 5}}}}
237 test interp-6.4 {testing eval} {
240 test interp-6.5 {testing eval} {
242 interp eval {a x2} {proc frob {} {expr {4 * 9}}}
243 interp eval {a x2} frob
245 catch {interp create {a x2}}
246 test interp-6.6 {testing eval} -returnCodes error -body {
247 interp eval {a x2} foo
248 } -result {invalid command name "foo"}
250 # UTILITY PROCEDURE RUNNING IN PARENT INTERPRETER:
251 proc in_parent {args} {
252 return [list seen in parent: $args]
255 # Part 6: Testing basic alias creation
256 test interp-7.1 {testing basic alias creation} {
257 a alias foo in_parent
259 catch {a alias foo in_parent}
260 test interp-7.2 {testing basic alias creation} {
261 a alias bar in_parent a1 a2 a3
263 catch {a alias bar in_parent a1 a2 a3}
264 # Test 6.3 has been deleted.
265 test interp-7.3 {testing basic alias creation} {
268 test interp-7.4 {testing basic alias creation} {
270 } {in_parent a1 a2 a3}
271 test interp-7.5 {testing basic alias creation} {
274 test interp-7.6 {testing basic aliases arg checking} -returnCodes error -body {
275 a aliases too many args
276 } -result {wrong # args: should be "a aliases"}
278 # Part 7: testing basic alias invocation
279 test interp-8.1 {testing basic alias invocation} {
280 catch {interp create a}
281 a alias foo in_parent
283 } {seen in parent: {s1 s2 s3}}
284 test interp-8.2 {testing basic alias invocation} {
285 catch {interp create a}
286 a alias bar in_parent a1 a2 a3
288 } {seen in parent: {a1 a2 a3 s1 s2 s3}}
289 test interp-8.3 {testing basic alias invocation} -returnCodes error -body {
290 catch {interp create a}
292 } -result {wrong # args: should be "a alias aliasName ?targetName? ?arg ...?"}
294 # Part 8: Testing aliases for non-existent or hidden targets
295 test interp-9.1 {testing aliases for non-existent targets} {
296 catch {interp create a}
297 a alias zop nonexistent-command-in-parent
298 list [catch {a eval zop} msg] $msg
299 } {1 {invalid command name "nonexistent-command-in-parent"}}
300 test interp-9.2 {testing aliases for non-existent targets} {
301 catch {interp create a}
302 a alias zop nonexistent-command-in-parent
303 proc nonexistent-command-in-parent {} {return i_exist!}
306 test interp-9.3 {testing aliases for hidden commands} {
307 catch {interp create a}
308 a eval {proc p {} {return ENTER_A}}
309 interp alias {} p a p
311 lappend res [list [catch p msg] $msg]
313 lappend res [list [catch p msg] $msg]
317 } {{0 ENTER_A} {1 {invalid command name "p"}}}
318 test interp-9.4 {testing aliases and namespace commands} {
319 proc p {} {return GLOBAL}
321 proc p {} {return NAMESPACE}
323 interp alias {} a {} p
325 lappend res [namespace eval tst a]
332 if {[info command nonexistent-command-in-parent] != ""} {
333 rename nonexistent-command-in-parent {}
336 # Part 9: Aliasing between interpreters
337 test interp-10.1 {testing aliasing between interpreters} {
338 catch {interp delete a}
339 catch {interp delete b}
342 interp alias a a_alias b b_alias 1 2 3
344 test interp-10.2 {testing aliasing between interpreters} {
345 catch {interp delete a}
346 catch {interp delete b}
349 b eval {proc b_alias {args} {return [list got $args]}}
350 interp alias a a_alias b b_alias 1 2 3
352 } {got {1 2 3 a b c}}
353 test interp-10.3 {testing aliasing between interpreters} {
354 catch {interp delete a}
355 catch {interp delete b}
358 interp alias a a_alias b b_alias 1 2 3
359 list [catch {a eval a_alias a b c} msg] $msg
360 } {1 {invalid command name "b_alias"}}
361 test interp-10.4 {testing aliasing between interpreters} {
362 catch {interp delete a}
367 test interp-10.5 {testing aliasing between interpreters} {
368 catch {interp delete a}
369 catch {interp delete b}
373 interp alias a a_del b b_del
377 test interp-10.6 {testing aliasing between interpreters} {
378 catch {interp delete a}
379 catch {interp delete b}
382 interp alias a a_command b b_command a1 a2 a3
383 b alias b_command in_parent b1 b2 b3
384 a eval a_command m1 m2 m3
385 } {seen in parent: {b1 b2 b3 a1 a2 a3 m1 m2 m3}}
386 test interp-10.7 {testing aliases between interpreters} {
387 catch {interp delete a}
389 interp alias "" foo a zoppo
390 a eval {proc zoppo {x} {list $x $x $x}}
392 a eval {rename zoppo {}}
393 interp alias "" foo a {}
397 # Part 10: Testing "interp target"
398 test interp-11.1 {testing interp target} {
399 list [catch {interp target} msg] $msg
400 } {1 {wrong # args: should be "interp target path alias"}}
401 test interp-11.2 {testing interp target} {
402 list [catch {interp target nosuchinterpreter foo} msg] $msg
403 } {1 {could not find interpreter "nosuchinterpreter"}}
404 test interp-11.3 {testing interp target} {
405 catch {interp delete a}
407 a alias boo no_command
410 test interp-11.4 {testing interp target} {
411 catch {interp delete x1}
413 x1 eval interp create x2
414 x1 eval x2 eval interp create x3
415 catch {interp delete y1}
417 y1 eval interp create y2
418 y1 eval y2 eval interp create y3
419 interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
420 interp target {x1 x2 x3} xcommand
422 test interp-11.5 {testing interp target} {
423 catch {interp delete x1}
425 interp create {x1 x2}
426 interp create {x1 x2 x3}
427 catch {interp delete y1}
429 interp create {y1 y2}
430 interp create {y1 y2 y3}
431 interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
432 list [catch {x1 eval {interp target {x2 x3} xcommand}} msg] $msg
433 } {1 {target interpreter for alias "xcommand" in path "x2 x3" is not my descendant}}
434 test interp-11.6 {testing interp target} {
435 foreach a [interp aliases] {
438 list [catch {interp target {} foo} msg] $msg
439 } {1 {alias "foo" in path "" not found}}
440 test interp-11.7 {testing interp target} {
441 catch {interp delete a}
443 list [catch {interp target a foo} msg] $msg
444 } {1 {alias "foo" in path "a" not found}}
446 # Part 11: testing "interp issafe"
447 test interp-12.1 {testing interp issafe} {
450 test interp-12.2 {testing interp issafe} {
451 catch {interp delete a}
455 test interp-12.3 {testing interp issafe} {
456 catch {interp delete a}
458 interp create {a x3} -safe
461 test interp-12.4 {testing interp issafe} {
462 catch {interp delete a}
464 interp create {a x3} -safe
465 interp create {a x3 foo}
466 interp issafe {a x3 foo}
469 # Part 12: testing interpreter object command "issafe" sub-command
470 test interp-13.1 {testing foo issafe} {
471 catch {interp delete a}
475 test interp-13.2 {testing foo issafe} {
476 catch {interp delete a}
478 interp create {a x3} -safe
481 test interp-13.3 {testing foo issafe} {
482 catch {interp delete a}
484 interp create {a x3} -safe
485 interp create {a x3 foo}
486 a eval x3 eval foo issafe
488 test interp-13.4 {testing issafe arg checking} {
489 catch {interp create a}
490 list [catch {a issafe too many args} msg] $msg
491 } {1 {wrong # args: should be "a issafe"}}
493 # part 14: testing interp aliases
494 test interp-14.1 {testing interp aliases} -setup {
497 interp eval abc {interp aliases}
501 test interp-14.2 {testing interp aliases} {
502 catch {interp delete a}
507 lsort [interp aliases a]
509 test interp-14.3 {testing interp aliases} {
510 catch {interp delete a}
513 interp alias {a x3} froboz "" puts
514 interp aliases {a x3}
516 test interp-14.4 {testing interp alias - alias over parent} {
518 catch {interp delete a}
520 list [catch {interp alias "" a a eval} msg] $msg [info commands a]
521 } {1 {cannot define or rename alias "a": interpreter deleted} {}}
522 test interp-14.5 {testing interp-alias: wrong # args} -body {
524 interp alias {} a {} setx
530 } -result {wrong # args: should be "a x"
533 test interp-14.6 {testing interp-alias: wrong # args} -setup {
535 catch {interp delete a}
538 interp alias a a {} setx
544 } -result {wrong # args: should be "a x"
549 test interp-14.7 {testing interp-alias: wrong # args} -setup {
551 catch {interp delete a}
554 interp alias a a {} setx
562 } -result {wrong # args: should be "a x"
565 test interp-14.8 {testing interp-alias: error messages} -body {
566 proc setx x {return -code error x}
567 interp alias {} a {} setx
576 test interp-14.9 {testing interp-alias: error messages} -setup {
577 proc setx x {return -code error x}
578 catch {interp delete a}
581 interp alias a a {} setx
592 test interp-14.10 {testing interp-alias: error messages} -setup {
593 proc setx x {return -code error x}
594 catch {interp delete a}
597 interp alias a a {} setx
609 test interp-14.11 {{interp alias} {target named the empty string} {bug 2bf56185}} -setup {
610 set interp [interp create [info cmdcount]]
611 interp eval $interp {
612 proc {} args {return $args}
616 interp alias {} p1 $interp {}
619 interp delete $interp
620 } -result {one two three}
622 # part 15: testing file sharing
623 test interp-15.1 {testing file sharing} {
624 catch {interp delete z}
627 list [catch {z eval puts hello} msg] $msg
628 } {1 {can not find channel named "stdout"}}
629 test interp-15.2 {testing file sharing} -body {
630 catch {interp delete z}
632 set f [open [makeFile {} file-15.2] w]
640 test interp-15.3 {testing file sharing} {
641 catch {interp delete xsafe}
642 interp create xsafe -safe
643 list [catch {xsafe eval puts hello} msg] $msg
644 } {1 {can not find channel named "stdout"}}
645 test interp-15.4 {testing file sharing} -body {
646 catch {interp delete xsafe}
647 interp create xsafe -safe
648 set f [open [makeFile {} file-15.4] w]
649 interp share "" $f xsafe
650 xsafe eval puts $f hello
656 test interp-15.5 {testing file sharing} {
657 catch {interp delete xsafe}
658 interp create xsafe -safe
659 interp share "" stdout xsafe
660 list [catch {xsafe eval gets stdout} msg] $msg
661 } {1 {channel "stdout" wasn't opened for reading}}
662 test interp-15.6 {testing file sharing} -body {
663 catch {interp delete xsafe}
664 interp create xsafe -safe
665 set f [open [makeFile {} file-15.6] w]
666 interp share "" $f xsafe
667 set x [list [catch [list xsafe eval gets $f] msg] $msg]
670 string compare [string tolower $x] \
671 [list 1 [format "channel \"%s\" wasn't opened for reading" $f]]
675 test interp-15.7 {testing file transferring} -body {
676 catch {interp delete xsafe}
677 interp create xsafe -safe
678 set f [open [makeFile {} file-15.7] w]
679 interp transfer "" $f xsafe
680 xsafe eval puts $f hello
685 test interp-15.8 {testing file transferring} -body {
686 catch {interp delete xsafe}
687 interp create xsafe -safe
688 set f [open [makeFile {} file-15.8] w]
689 interp transfer "" $f xsafe
691 set x [list [catch {close $f} msg] $msg]
692 string compare [string tolower $x] \
693 [list 1 [format "can not find channel named \"%s\"" $f]]
699 # Torture tests for interpreter deletion order
701 proc kill {} {interp delete xxx}
702 test interp-16.0 {testing deletion order} {
703 catch {interp delete xxx}
706 list [catch {xxx eval kill} msg] $msg
708 test interp-16.1 {testing deletion order} {
709 catch {interp delete xxx}
711 interp create {xxx yyy}
712 interp alias {xxx yyy} kill "" kill
713 list [catch {interp eval {xxx yyy} kill} msg] $msg
715 test interp-16.2 {testing deletion order} {
716 catch {interp delete xxx}
718 interp create {xxx yyy}
719 interp alias {xxx yyy} kill "" kill
720 list [catch {xxx eval yyy eval kill} msg] $msg
722 test interp-16.3 {testing deletion order} {
723 catch {interp delete xxx}
727 interp alias ddd kill xxx kill
728 set x [ddd eval kill]
732 test interp-16.4 {testing deletion order} {
733 catch {interp delete xxx}
735 interp create {xxx yyy}
736 interp alias {xxx yyy} kill "" kill
738 interp alias ddd kill {xxx yyy} kill
739 set x [ddd eval kill]
743 test interp-16.5 {testing deletion order, bgerror} {
744 catch {interp delete xxx}
746 xxx eval {proc bgerror {args} {exit}}
747 xxx alias exit kill xxx
748 proc kill {i} {interp delete $i}
749 xxx eval after 100 expr {a + b}
756 # Alias loop prevention testing.
759 test interp-17.1 {alias loop prevention} {
760 list [catch {interp alias {} a {} a} msg] $msg
761 } {1 {cannot define or rename alias "a": would create a loop}}
762 test interp-17.2 {alias loop prevention} {
763 catch {interp delete x}
766 list [catch {interp alias {} loop x a} msg] $msg
767 } {1 {cannot define or rename alias "loop": would create a loop}}
768 test interp-17.3 {alias loop prevention} {
769 catch {interp delete x}
772 list [catch {interp alias x b x a} msg] $msg
773 } {1 {cannot define or rename alias "b": would create a loop}}
774 test interp-17.4 {alias loop prevention} {
775 catch {interp delete x}
778 list [catch {x eval rename b a} msg] $msg
779 } {1 {cannot define or rename alias "a": would create a loop}}
780 test interp-17.5 {alias loop prevention} {
781 catch {interp delete x}
784 interp alias {} l2 x z
785 list [catch {rename l2 l1} msg] $msg
786 } {1 {cannot define or rename alias "l1": would create a loop}}
787 test interp-17.6 {alias loop prevention} {
788 catch {interp delete x}
792 list [catch {x eval rename c b} msg] $msg
793 } {1 {cannot define or rename alias "b": would create a loop}}
796 # Test robustness of Tcl_DeleteInterp when applied to a child interpreter.
797 # If there are bugs in the implementation these tests are likely to expose
798 # the bugs as a core dump.
801 test interp-18.1 {testing Tcl_DeleteInterp vs children} testinterpdelete {
802 list [catch {testinterpdelete} msg] $msg
803 } {1 {wrong # args: should be "testinterpdelete path"}}
804 test interp-18.2 {testing Tcl_DeleteInterp vs children} testinterpdelete {
805 catch {interp delete a}
809 test interp-18.3 {testing Tcl_DeleteInterp vs children} testinterpdelete {
810 catch {interp delete a}
813 testinterpdelete {a b}
815 test interp-18.4 {testing Tcl_DeleteInterp vs children} testinterpdelete {
816 catch {interp delete a}
821 test interp-18.5 {testing Tcl_DeleteInterp vs children} testinterpdelete {
822 catch {interp delete a}
825 interp alias {a b} dodel {} dodel
826 proc dodel {x} {testinterpdelete $x}
827 list [catch {interp eval {a b} {dodel {a b}}} msg] $msg
829 test interp-18.6 {testing Tcl_DeleteInterp vs children} testinterpdelete {
830 catch {interp delete a}
833 interp alias {a b} dodel {} dodel
834 proc dodel {x} {testinterpdelete $x}
835 list [catch {interp eval {a b} {dodel a}} msg] $msg
837 test interp-18.7 {eval in deleted interp} {
838 catch {interp delete a}
845 proc dosomething args {
846 puts "I should not have been called!!"
850 proc dela {} {interp delete a}
851 list [catch {a eval dodel} msg] $msg
852 } {1 {attempt to call eval in deleted interpreter}}
853 test interp-18.8 {eval in deleted interp} {
854 catch {interp delete a}
867 proc dosomething args {
868 puts "I should not have been called!!"
871 interp alias {a b} dela {} dela
872 proc dela {} {interp delete a}
873 list [catch {a eval foo} msg] $msg
874 } {1 {attempt to call eval in deleted interpreter}}
875 test interp-18.9 {eval in deleted interp, bug 495830} {
877 interp alias tst suicide {} interp delete tst
878 list [catch {tst eval {suicide; set a 5}} msg] $msg
879 } {1 {attempt to call eval in deleted interpreter}}
880 test interp-18.10 {eval in deleted interp, bug 495830} {
882 interp alias tst suicide {} interp delete tst
883 list [catch {tst eval {set set set; suicide; $set a 5}} msg] $msg
884 } {1 {attempt to call eval in deleted interpreter}}
886 # Test alias deletion
888 test interp-19.1 {alias deletion} {
889 catch {interp delete a}
891 interp alias a foo a bar
892 set s [interp alias a foo {}]
896 test interp-19.2 {alias deletion} {
897 catch {interp delete a}
899 catch {interp alias a foo {}} msg
902 } {alias "foo" not found}
903 test interp-19.3 {alias deletion} {
904 catch {interp delete a}
906 interp alias a foo a bar
907 interp eval a {rename foo zop}
908 interp alias a foo a zop
909 catch {interp eval a foo} msg
912 } {invalid command name "bar"}
913 test interp-19.4 {alias deletion} {
914 catch {interp delete a}
916 interp alias a foo a bar
917 interp eval a {rename foo zop}
918 catch {interp eval a foo} msg
921 } {invalid command name "foo"}
922 test interp-19.5 {alias deletion} {
923 catch {interp delete a}
925 interp eval a {proc bar {} {return 1}}
926 interp alias a foo a bar
927 interp eval a {rename foo zop}
928 catch {interp eval a zop} msg
932 test interp-19.6 {alias deletion} {
933 catch {interp delete a}
935 interp alias a foo a bar
936 interp eval a {rename foo zop}
937 interp alias a foo a zop
938 set s [interp aliases a]
942 test interp-19.7 {alias deletion, renaming} {
943 catch {interp delete a}
945 interp alias a foo a bar
946 interp eval a rename foo blotz
947 interp alias a foo {}
948 set s [interp aliases a]
952 test interp-19.8 {alias deletion, renaming} {
953 catch {interp delete a}
955 interp alias a foo a bar
956 interp eval a rename foo blotz
958 lappend l [interp aliases a]
959 interp alias a foo {}
960 lappend l [interp aliases a]
964 test interp-19.9 {alias deletion, renaming} {
965 catch {interp delete a}
967 interp alias a foo a bar
968 interp eval a rename foo blotz
969 interp eval a {proc foo {} {expr {34 * 34}}}
970 interp alias a foo {}
971 set l [interp eval a foo]
976 test interp-20.1 {interp hide, interp expose and interp invokehidden} {
977 set a [interp create]
978 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
979 $a eval {proc foo {} {}}
981 catch {$a eval foo something} msg
984 } {invalid command name "foo"}
985 test interp-20.2 {interp hide, interp expose and interp invokehidden} {
986 set a [interp create]
987 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
990 lappend l [catch {$a eval {list 1 2 3}} msg] $msg
992 lappend l [catch {$a eval {list 1 2 3}} msg] $msg
995 } {1 {invalid command name "list"} 0 {1 2 3}}
996 test interp-20.3 {interp hide, interp expose and interp invokehidden} {
997 set a [interp create]
998 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1001 lappend l [catch { $a eval {list 1 2 3} } msg] $msg
1002 lappend l [catch { $a invokehidden list 1 2 3 } msg] $msg
1004 lappend l [catch { $a eval {list 1 2 3} } msg] $msg
1007 } {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
1008 test interp-20.4 {interp hide, interp expose and interp invokehidden -- passing {}} {
1009 set a [interp create]
1010 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1013 lappend l [catch { $a eval {list 1 2 3} } msg] $msg
1014 lappend l [catch { $a invokehidden list {"" 1 2 3} } msg] $msg
1016 lappend l [catch { $a eval {list 1 2 3} } msg] $msg
1019 } {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
1020 test interp-20.5 {interp hide, interp expose and interp invokehidden -- passing {}} {
1021 set a [interp create]
1022 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1025 lappend l [catch { $a eval {list 1 2 3} } msg] $msg
1026 lappend l [catch { $a invokehidden list {{} 1 2 3} } msg] $msg
1028 lappend l [catch { $a eval {list 1 2 3} } msg] $msg
1031 } {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
1032 test interp-20.6 {interp invokehidden -- eval args} {
1033 set a [interp create]
1037 lappend l [catch { $a invokehidden list $z 1 2 3 } msg] $msg
1039 lappend l [catch { $a eval list $z 1 2 3 } msg] $msg
1042 } {0 {45 1 2 3} 0 {45 1 2 3}}
1043 test interp-20.7 {interp invokehidden vs variable eval} {
1044 set a [interp create]
1047 set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
1051 test interp-20.8 {interp invokehidden vs variable eval} {
1052 set a [interp create]
1056 set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
1060 test interp-20.9 {interp invokehidden vs variable eval} {
1061 set a [interp create]
1066 lappend l [catch {$a invokehidden list $z {$z a b c}} msg] $msg
1069 } {0 {45 {$z a b c}}}
1070 test interp-20.10 {interp hide, interp expose and interp invokehidden} {
1071 set a [interp create]
1072 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1073 $a eval {proc foo {} {}}
1075 catch {interp eval $a foo something} msg
1078 } {invalid command name "foo"}
1079 test interp-20.11 {interp hide, interp expose and interp invokehidden} {
1080 set a [interp create]
1081 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1084 lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
1085 interp expose $a list
1086 lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
1089 } {1 {invalid command name "list"} 0 {1 2 3}}
1090 test interp-20.12 {interp hide, interp expose and interp invokehidden} {
1091 set a [interp create]
1092 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1095 lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
1096 lappend l [catch {interp invokehidden $a list 1 2 3} msg] $msg
1097 interp expose $a list
1098 lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
1101 } {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
1102 test interp-20.13 {interp hide, interp expose, interp invokehidden -- passing {}} {
1103 set a [interp create]
1104 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1107 lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
1108 lappend l [catch {interp invokehidden $a list {"" 1 2 3}} msg] $msg
1109 interp expose $a list
1110 lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
1113 } {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
1114 test interp-20.14 {interp hide, interp expose, interp invokehidden -- passing {}} {
1115 set a [interp create]
1116 $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
1119 lappend l [catch {interp eval $a {list 1 2 3} } msg] $msg
1120 lappend l [catch {interp invokehidden $a list {{} 1 2 3}} msg] $msg
1121 interp expose $a list
1122 lappend l [catch {$a eval {list 1 2 3} } msg] $msg
1125 } {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
1126 test interp-20.15 {interp invokehidden -- eval args} {
1127 catch {interp delete a}
1132 lappend l [catch {interp invokehidden a list $z 1 2 3} msg]
1135 lappend l [catch {interp eval a list $z 1 2 3} msg]
1139 } {0 {45 1 2 3} 0 {45 1 2 3}}
1140 test interp-20.16 {interp invokehidden vs variable eval} {
1141 catch {interp delete a}
1146 lappend l [catch {interp invokehidden a list {$z a b c}} msg]
1151 test interp-20.17 {interp invokehidden vs variable eval} {
1152 catch {interp delete a}
1158 lappend l [catch {interp invokehidden a list {$z a b c}} msg]
1163 test interp-20.18 {interp invokehidden vs variable eval} {
1164 catch {interp delete a}
1170 lappend l [catch {interp invokehidden a list $z {$z a b c}} msg]
1174 } {0 {45 {$z a b c}}}
1175 test interp-20.19 {interp invokehidden vs nested commands} {
1176 catch {interp delete a}
1179 set l [a invokehidden list {[list x y z] f g h} z]
1182 } {{[list x y z] f g h} z}
1183 test interp-20.20 {interp invokehidden vs nested commands} {
1184 catch {interp delete a}
1187 set l [interp invokehidden a list {[list x y z] f g h} z]
1190 } {{[list x y z] f g h} z}
1191 test interp-20.21 {interp hide vs safety} {
1192 catch {interp delete a}
1193 interp create a -safe
1195 lappend l [catch {a hide list} msg]
1200 test interp-20.22 {interp hide vs safety} {
1201 catch {interp delete a}
1202 interp create a -safe
1204 lappend l [catch {interp hide a list} msg]
1209 test interp-20.23 {interp hide vs safety} {
1210 catch {interp delete a}
1211 interp create a -safe
1213 lappend l [catch {a eval {interp hide {} list}} msg]
1217 } {1 {permission denied: safe interpreter cannot hide commands}}
1218 test interp-20.24 {interp hide vs safety} {
1219 catch {interp delete a}
1220 interp create a -safe
1223 lappend l [catch {a eval {interp hide b list}} msg]
1227 } {1 {permission denied: safe interpreter cannot hide commands}}
1228 test interp-20.25 {interp hide vs safety} {
1229 catch {interp delete a}
1230 interp create a -safe
1233 lappend l [catch {interp hide {a b} list} msg]
1238 test interp-20.26 {interp expoose vs safety} {
1239 catch {interp delete a}
1240 interp create a -safe
1242 lappend l [catch {a hide list} msg]
1244 lappend l [catch {a expose list} msg]
1249 test interp-20.27 {interp expose vs safety} {
1250 catch {interp delete a}
1251 interp create a -safe
1253 lappend l [catch {interp hide a list} msg]
1255 lappend l [catch {interp expose a list} msg]
1260 test interp-20.28 {interp expose vs safety} {
1261 catch {interp delete a}
1262 interp create a -safe
1264 lappend l [catch {a hide list} msg]
1266 lappend l [catch {a eval {interp expose {} list}} msg]
1270 } {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
1271 test interp-20.29 {interp expose vs safety} {
1272 catch {interp delete a}
1273 interp create a -safe
1275 lappend l [catch {interp hide a list} msg]
1277 lappend l [catch {a eval {interp expose {} list}} msg]
1281 } {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
1282 test interp-20.30 {interp expose vs safety} {
1283 catch {interp delete a}
1284 interp create a -safe
1287 lappend l [catch {interp hide {a b} list} msg]
1289 lappend l [catch {a eval {interp expose b list}} msg]
1293 } {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
1294 test interp-20.31 {interp expose vs safety} {
1295 catch {interp delete a}
1296 interp create a -safe
1299 lappend l [catch {interp hide {a b} list} msg]
1301 lappend l [catch {interp expose {a b} list} msg]
1306 test interp-20.32 {interp invokehidden vs safety} {
1307 catch {interp delete a}
1308 interp create a -safe
1311 lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
1315 } {1 {not allowed to invoke hidden commands from safe interpreter}}
1316 test interp-20.33 {interp invokehidden vs safety} {
1317 catch {interp delete a}
1318 interp create a -safe
1321 lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
1323 lappend l [catch {a invokehidden list a b c} msg]
1327 } {1 {not allowed to invoke hidden commands from safe interpreter}\
1329 test interp-20.34 {interp invokehidden vs safety} {
1330 catch {interp delete a}
1331 interp create a -safe
1333 interp hide {a b} list
1335 lappend l [catch {a eval {interp invokehidden b list a b c}} msg]
1337 lappend l [catch {interp invokehidden {a b} list a b c} msg]
1341 } {1 {not allowed to invoke hidden commands from safe interpreter}\
1343 test interp-20.35 {invokehidden at local level} {
1344 catch {interp delete a}
1360 interp invokehidden a h1
1362 set r [interp eval a p1]
1366 test interp-20.36 {invokehidden at local level} {
1367 catch {interp delete a}
1384 interp invokehidden a h1
1386 set r [interp eval a p1]
1390 test interp-20.37 {invokehidden at local level} {
1391 catch {interp delete a}
1406 interp invokehidden a h1
1408 set r [interp eval a p1]
1412 test interp-20.38 {invokehidden at global level} {
1413 catch {interp delete a}
1428 interp invokehidden a -global h1
1430 set r [catch {interp eval a p1} msg]
1433 } {1 {can't read "z": no such variable}}
1434 test interp-20.39 {invokehidden at global level} {
1435 catch {interp delete a}
1451 interp invokehidden a -global h1
1453 set r [catch {interp eval a p1} msg]
1457 test interp-20.40 {safe, invokehidden at local level} {
1458 catch {interp delete a}
1459 interp create a -safe
1474 interp invokehidden a h1
1476 set r [interp eval a p1]
1480 test interp-20.41 {safe, invokehidden at local level} {
1481 catch {interp delete a}
1482 interp create a -safe
1498 interp invokehidden a h1
1500 set r [interp eval a p1]
1504 test interp-20.42 {safe, invokehidden at local level} {
1505 catch {interp delete a}
1506 interp create a -safe
1520 interp invokehidden a h1
1522 set r [interp eval a p1]
1526 test interp-20.43 {invokehidden at global level} {
1527 catch {interp delete a}
1542 interp invokehidden a -global h1
1544 set r [catch {interp eval a p1} msg]
1547 } {1 {can't read "z": no such variable}}
1548 test interp-20.44 {invokehidden at global level} {
1549 catch {interp delete a}
1565 interp invokehidden a -global h1
1567 set r [catch {interp eval a p1} msg]
1571 test interp-20.45 {interp hide vs namespaces} {
1572 catch {interp delete a}
1575 namespace eval foo {}
1578 set l [list [catch {interp hide a foo::x} msg] $msg]
1581 } {1 {cannot use namespace qualifiers in hidden command token (rename)}}
1582 test interp-20.46 {interp hide vs namespaces} {
1583 catch {interp delete a}
1586 namespace eval foo {}
1589 set l [list [catch {interp hide a foo::x x} msg] $msg]
1592 } {1 {can only hide global namespace commands (use rename then hide)}}
1593 test interp-20.47 {interp hide vs namespaces} {
1594 catch {interp delete a}
1599 set l [list [catch {interp hide a x foo::x} msg] $msg]
1602 } {1 {cannot use namespace qualifiers in hidden command token (rename)}}
1603 test interp-20.48 {interp hide vs namespaces} {
1604 catch {interp delete a}
1607 namespace eval foo {}
1610 set l [list [catch {interp hide a foo::x bar::x} msg] $msg]
1613 } {1 {cannot use namespace qualifiers in hidden command token (rename)}}
1614 test interp-20.49 {interp invokehidden -namespace} -setup {
1615 set script [makeFile {
1616 set x [namespace current]
1618 interp create -safe child
1620 child invokehidden -namespace ::foo source $script
1621 child eval {set ::foo::x}
1626 test interp-20.50 {Bug 2486550} -setup {
1629 child hide coroutine
1630 child invokehidden coroutine
1633 } -returnCodes error -match glob -result *
1634 test interp-20.50.1 {Bug 2486550} -setup {
1637 child hide coroutine
1638 catch {child invokehidden coroutine} m o
1639 dict get $o -errorinfo
1641 unset -nocomplain m 0
1643 } -returnCodes ok -result {wrong # args: should be "coroutine name cmd ?arg ...?"
1647 "child invokehidden coroutine"}
1649 test interp-21.1 {interp hidden} {
1652 test interp-21.2 {interp hidden} {
1655 test interp-21.3 {interp hidden vs interp hide, interp expose} -setup {
1658 lappend l [interp hidden]
1660 lappend l [interp hidden]
1661 interp expose {} pwd
1662 lappend l [interp hidden]
1663 } -result {{} pwd {}}
1664 test interp-21.4 {interp hidden} -setup {
1665 catch {interp delete a}
1672 test interp-21.5 {interp hidden} -setup {
1673 catch {interp delete a}
1675 interp create -safe a
1676 lsort [interp hidden a]
1679 } -result $hidden_cmds
1680 test interp-21.6 {interp hidden vs interp hide, interp expose} -setup {
1681 catch {interp delete a}
1685 lappend l [interp hidden a]
1687 lappend l [interp hidden a]
1689 lappend l [interp hidden a]
1692 } -result {{} pwd {}}
1693 test interp-21.7 {interp hidden} -setup {
1694 catch {interp delete a}
1701 test interp-21.8 {interp hidden} -setup {
1702 catch {interp delete a}
1704 interp create a -safe
1708 } -result $hidden_cmds
1709 test interp-21.9 {interp hidden vs interp hide, interp expose} -setup {
1710 catch {interp delete a}
1714 lappend l [a hidden]
1716 lappend l [a hidden]
1718 lappend l [a hidden]
1721 } -result {{} pwd {}}
1723 test interp-22.1 {testing interp marktrusted} {
1724 catch {interp delete a}
1727 lappend l [a issafe]
1728 lappend l [a marktrusted]
1729 lappend l [a issafe]
1733 test interp-22.2 {testing interp marktrusted} {
1734 catch {interp delete a}
1737 lappend l [interp issafe a]
1738 lappend l [interp marktrusted a]
1739 lappend l [interp issafe a]
1743 test interp-22.3 {testing interp marktrusted} {
1744 catch {interp delete a}
1745 interp create a -safe
1747 lappend l [a issafe]
1748 lappend l [a marktrusted]
1749 lappend l [a issafe]
1753 test interp-22.4 {testing interp marktrusted} {
1754 catch {interp delete a}
1755 interp create a -safe
1757 lappend l [interp issafe a]
1758 lappend l [interp marktrusted a]
1759 lappend l [interp issafe a]
1763 test interp-22.5 {testing interp marktrusted} {
1764 catch {interp delete a}
1765 interp create a -safe
1767 catch {a eval {interp marktrusted b}} msg
1770 } {permission denied: safe interpreter cannot mark trusted}
1771 test interp-22.6 {testing interp marktrusted} {
1772 catch {interp delete a}
1773 interp create a -safe
1775 catch {a eval {b marktrusted}} msg
1778 } {permission denied: safe interpreter cannot mark trusted}
1779 test interp-22.7 {testing interp marktrusted} {
1780 catch {interp delete a}
1781 interp create a -safe
1783 lappend l [interp issafe a]
1784 interp marktrusted a
1786 lappend l [interp issafe a]
1787 lappend l [interp issafe {a b}]
1791 test interp-22.8 {testing interp marktrusted} {
1792 catch {interp delete a}
1793 interp create a -safe
1795 lappend l [interp issafe a]
1797 lappend l [interp issafe {a b}]
1798 interp marktrusted a
1800 lappend l [interp issafe a]
1801 lappend l [interp issafe {a c}]
1805 test interp-22.9 {testing interp marktrusted} {
1806 catch {interp delete a}
1807 interp create a -safe
1809 lappend l [interp issafe a]
1811 lappend l [interp issafe {a b}]
1812 interp marktrusted {a b}
1813 lappend l [interp issafe a]
1814 lappend l [interp issafe {a b}]
1815 interp create {a b c}
1816 lappend l [interp issafe {a b c}]
1821 test interp-23.1 {testing hiding vs aliases: unsafe interp} -setup {
1822 catch {interp delete a}
1826 lappend l [interp hidden a]
1828 lappend l [interp aliases a] [interp hidden a]
1830 lappend l [interp aliases a] [interp hidden a]
1832 lappend l [interp aliases a] [interp hidden a]
1835 } -result {{} bar {} bar bar {} {}}
1836 test interp-23.2 {testing hiding vs aliases: safe interp} -setup {
1837 catch {interp delete a}
1839 } -constraints {unixOrWin} -body {
1840 interp create a -safe
1841 lappend l [lsort [interp hidden a]]
1843 lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
1845 lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
1847 lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
1850 } -result [list $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} [lsort [concat $hidden_cmds bar]] {::tcl::mathfunc::max ::tcl::mathfunc::min clock} $hidden_cmds]
1852 test interp-24.1 {result resetting on error} -setup {
1853 catch {interp delete a}
1856 interp alias a foo {} apply {args {error $args}}
1858 lappend l [catch {foo 1 2 3} msg] $msg
1859 lappend l [catch {foo 3 4 5} msg] $msg
1863 } -result {1 {1 2 3} 1 {3 4 5}}
1864 test interp-24.2 {result resetting on error} -setup {
1865 catch {interp delete a}
1867 interp create a -safe
1868 interp alias a foo {} apply {args {error $args}}
1870 lappend l [catch {foo 1 2 3} msg] $msg
1871 lappend l [catch {foo 3 4 5} msg] $msg
1875 } -result {1 {1 2 3} 1 {3 4 5}}
1876 test interp-24.3 {result resetting on error} -setup {
1877 catch {interp delete a}
1882 proc foo args {error $args}
1884 interp alias {a b} foo a foo
1886 lappend l [catch {foo 1 2 3} msg] $msg
1887 lappend l [catch {foo 3 4 5} msg] $msg
1891 } -result {1 {1 2 3} 1 {3 4 5}}
1892 test interp-24.4 {result resetting on error} -setup {
1893 catch {interp delete a}
1895 interp create a -safe
1898 proc foo args {error $args}
1900 interp alias {a b} foo a foo
1902 lappend l [catch {foo 1 2 3} msg]
1904 lappend l [catch {foo 3 4 5} msg]
1909 } -result {1 {1 2 3} 1 {3 4 5}}
1910 test interp-24.5 {result resetting on error} -setup {
1911 catch {interp delete a}
1912 catch {interp delete b}
1917 proc foo args {error $args}
1919 interp alias b foo a foo
1921 lappend l [catch {foo 1 2 3} msg] $msg
1922 lappend l [catch {foo 3 4 5} msg] $msg
1927 } -result {1 {1 2 3} 1 {3 4 5}}
1928 test interp-24.6 {result resetting on error} -setup {
1929 catch {interp delete a}
1930 catch {interp delete b}
1932 interp create a -safe
1933 interp create b -safe
1935 proc foo args {error $args}
1937 interp alias b foo a foo
1939 lappend l [catch {foo 1 2 3} msg] $msg
1940 lappend l [catch {foo 3 4 5} msg] $msg
1945 } -result {1 {1 2 3} 1 {3 4 5}}
1946 test interp-24.7 {result resetting on error} -setup {
1947 catch {interp delete a}
1952 proc foo args {error $args}
1954 lappend l [catch {interp eval a foo 1 2 3} msg] $msg
1955 lappend l [catch {interp eval a foo 3 4 5} msg] $msg
1958 } -result {1 {1 2 3} 1 {3 4 5}}
1959 test interp-24.8 {result resetting on error} -setup {
1960 catch {interp delete a}
1963 interp create a -safe
1965 proc foo args {error $args}
1967 lappend l [catch {interp eval a foo 1 2 3} msg] $msg
1968 lappend l [catch {interp eval a foo 3 4 5} msg] $msg
1971 } -result {1 {1 2 3} 1 {3 4 5}}
1972 test interp-24.9 {result resetting on error} -setup {
1973 catch {interp delete a}
1979 proc foo args {error $args}
1983 eval interp eval b foo $args
1986 lappend l [catch {interp eval a foo 1 2 3} msg] $msg
1987 lappend l [catch {interp eval a foo 3 4 5} msg] $msg
1990 } -result {1 {1 2 3} 1 {3 4 5}}
1991 test interp-24.10 {result resetting on error} -setup {
1992 catch {interp delete a}
1995 interp create a -safe
1998 proc foo args {error $args}
2002 eval interp eval b foo $args
2005 lappend l [catch {interp eval a foo 1 2 3} msg] $msg
2006 lappend l [catch {interp eval a foo 3 4 5} msg] $msg
2009 } -result {1 {1 2 3} 1 {3 4 5}}
2010 test interp-24.11 {result resetting on error} -setup {
2011 catch {interp delete a}
2016 proc foo args {error $args}
2020 lappend l [catch {eval interp eval b foo $args} msg] $msg
2021 lappend l [catch {eval interp eval b foo $args} msg] $msg
2024 interp eval a foo 1 2 3
2027 } -result {1 {1 2 3} 1 {1 2 3}}
2028 test interp-24.12 {result resetting on error} -setup {
2029 catch {interp delete a}
2031 interp create a -safe
2034 proc foo args {error $args}
2038 lappend l [catch {eval interp eval b foo $args} msg] $msg
2039 lappend l [catch {eval interp eval b foo $args} msg] $msg
2042 interp eval a foo 1 2 3
2045 } -result {1 {1 2 3} 1 {1 2 3}}
2047 test interp-25.1 {testing aliasing of string commands} -setup {
2048 catch {interp delete a}
2051 a alias exec foo ;# Relies on exec being a string command!
2056 # Interps result transmission
2059 test interp-26.1 {result code transmission : interp eval direct} {
2060 # Test that all the possibles error codes from Tcl get passed up
2061 # from the child interp's context to the parent, even though the
2062 # child nominally thinks the command is running at the root level.
2063 catch {interp delete a}
2066 # use a for so if a return -code break 'escapes' we would notice
2067 for {set code -1} {$code<=5} {incr code} {
2068 lappend res [catch {interp eval a return -code $code} msg]
2073 test interp-26.2 {result code transmission : interp eval indirect} {
2074 # retcode == 2 == return is special
2075 catch {interp delete a}
2077 interp eval a {proc retcode {code} {return -code $code ret$code}}
2079 # use a for so if a return -code break 'escapes' we would notice
2080 for {set code -1} {$code<=5} {incr code} {
2081 lappend res [catch {interp eval a retcode $code} msg] $msg
2085 } {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
2086 test interp-26.3 {result code transmission : aliases} {
2087 # Test that all the possibles error codes from Tcl get passed up from the
2088 # child interp's context to the parent, even though the child nominally
2089 # thinks the command is running at the root level.
2090 catch {interp delete a}
2093 proc MyTestAlias {code} {
2094 return -code $code ret$code
2096 interp alias a Test {} MyTestAlias
2097 for {set code -1} {$code<=5} {incr code} {
2098 lappend res [interp eval a [list catch [list Test $code] msg]]
2103 test interp-26.4 {result code transmission: invoke hidden direct--bug 1637} \
2105 # The known bug is that code 2 is returned, not the -code argument
2106 catch {interp delete a}
2109 interp hide a return
2110 for {set code -1} {$code<=5} {incr code} {
2111 lappend res [catch {interp invokehidden a return -code $code ret$code}]
2116 test interp-26.5 {result code transmission: invoke hidden indirect--bug 1637} -setup {
2117 catch {interp delete a}
2120 # The known bug is that the break and continue should raise errors that
2121 # they are used outside a loop.
2123 interp eval a {proc retcode {code} {return -code $code ret$code}}
2124 interp hide a retcode
2125 for {set code -1} {$code<=5} {incr code} {
2126 lappend res [catch {interp invokehidden a retcode $code} msg] $msg
2131 } -result {-1 ret-1 0 ret0 1 ret1 2 ret2 3 ret3 4 ret4 5 ret5}
2132 test interp-26.6 {result code transmission: all combined--bug 1637} -setup {
2133 set interp [interp create]
2134 } -constraints knownBug -body {
2135 # Test that all the possibles error codes from Tcl get passed in both
2136 # directions. This doesn't work.
2137 proc MyTestAlias {interp args} {
2139 lappend aliasTrace $args
2140 interp invokehidden $interp {*}$args
2142 foreach c {return} {
2143 interp hide $interp $c
2144 interp alias $interp $c {} MyTestAlias $interp $c
2146 interp eval $interp {proc ret {code} {return -code $code ret$code}}
2149 for {set code -1} {$code<=5} {incr code} {
2150 lappend res [catch {interp eval $interp ret $code} msg] $msg
2154 interp delete $interp
2155 } -result {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
2156 # Some tests might need to be added to check for difference between toplevel
2157 # and non-toplevel evals.
2158 # End of return code transmission section
2159 test interp-26.7 {errorInfo transmission: regular interps} -setup {
2160 set interp [interp create]
2162 proc MyError {secret} {
2163 return -code error "msg"
2165 proc MyTestAlias {interp args} {
2166 MyError "some secret"
2168 interp alias $interp test {} MyTestAlias $interp
2169 interp eval $interp {catch test;set ::errorInfo}
2171 interp delete $interp
2174 "MyError "some secret""
2175 (procedure "MyTestAlias" line 2)
2178 test interp-26.8 {errorInfo transmission: safe interps--bug 1637} -setup {
2179 set interp [interp create -safe]
2180 } -constraints knownBug -body {
2181 # this test fails because the errorInfo is fully transmitted whether the
2182 # interp is safe or not. The errorInfo should never report data from the
2183 # parent interpreter because it could contain sensitive information.
2184 proc MyError {secret} {
2185 return -code error "msg"
2187 proc MyTestAlias {interp args} {
2188 MyError "some secret"
2190 interp alias $interp test {} MyTestAlias $interp
2191 interp eval $interp {catch test;set ::errorInfo}
2193 interp delete $interp
2198 # Interps & Namespaces
2199 test interp-27.1 {interp aliases & namespaces} -setup {
2200 set i [interp create]
2203 proc tstAlias {args} {
2205 lappend aliasTrace [list [namespace current] $args]
2207 $i alias foo::bar tstAlias foo::bar
2208 $i eval foo::bar test
2212 } -result {{:: {foo::bar test}}}
2213 test interp-27.2 {interp aliases & namespaces} -setup {
2214 set i [interp create]
2217 proc tstAlias {args} {
2219 lappend aliasTrace [list [namespace current] $args]
2221 $i alias foo::bar tstAlias foo::bar
2222 $i eval namespace eval foo {bar test}
2226 } -result {{:: {foo::bar test}}}
2227 test interp-27.3 {interp aliases & namespaces} -setup {
2228 set i [interp create]
2231 proc tstAlias {args} {
2233 lappend aliasTrace [list [namespace current] $args]
2235 interp eval $i {namespace eval foo {proc bar {} {error "bar called"}}}
2236 interp alias $i foo::bar {} tstAlias foo::bar
2237 interp eval $i {namespace eval foo {bar test}}
2241 } -result {{:: {foo::bar test}}}
2242 test interp-27.4 {interp aliases & namespaces} -setup {
2243 set i [interp create]
2245 namespace eval foo2 {
2246 variable aliasTrace {}
2249 lappend aliasTrace [list [namespace current] $args]
2252 $i alias foo::bar foo2::bar foo::bar
2253 $i eval namespace eval foo {bar test}
2254 return $foo2::aliasTrace
2256 namespace delete foo2
2258 } -result {{::foo2 {foo::bar test}}}
2259 test interp-27.5 {interp hidden & namespaces} -setup {
2260 set i [interp create]
2261 } -constraints knownBug -body {
2263 namespace eval foo {
2265 return "bar called ([namespace current]) ($args)"
2269 set res [list [interp eval $i {namespace eval foo {bar test1}}]]
2270 interp hide $i foo::bar
2271 lappend res [list [catch {interp eval $i {namespace eval foo {bar test2}}} msg] $msg]
2274 } -result {{bar called (::foo) (test1)} {1 {invalid command name "bar"}}}
2275 test interp-27.6 {interp hidden & aliases & namespaces} -setup {
2276 set i [interp create]
2277 } -constraints knownBug -body {
2279 namespace eval foo {
2280 variable v foo-parent
2281 proc bar {interp args} {
2283 list "parent bar called ($v) ([namespace current]) ($args)"\
2284 [interp invokehidden $interp foo::bar $args]
2288 namespace eval foo {
2290 variable v foo-child
2293 return "child bar called ($v) ([namespace current]) ($args)"
2297 set res [list [interp eval $i {namespace eval foo {bar test1}}]]
2299 $i alias foo::bar foo::bar $i
2300 set res [concat $res [interp eval $i {
2302 namespace eval test {
2304 namespace import ::foo::*
2309 namespace delete foo
2311 } -result {{child bar called (foo-child) (::foo) (test1)} {parent bar called (foo-parent) (::foo) (test2)} {child bar called (foo-child) (::foo) (test2)}}
2312 test interp-27.7 {interp hidden & aliases & imports & namespaces} -setup {
2313 set i [interp create]
2314 } -constraints knownBug -body {
2316 namespace eval mfoo {
2317 variable v foo-parent
2318 proc bar {interp args} {
2320 list "parent bar called ($v) ([namespace current]) ($args)"\
2321 [interp invokehidden $interp test::bar $args]
2325 namespace eval foo {
2327 variable v foo-child
2330 return "child bar called ($v) ([info level 0]) ([uplevel namespace current]) ([namespace current]) ($args)"
2334 namespace eval test {
2336 namespace import ::foo::*
2339 set res [list [interp eval $i {namespace eval test {bar test1}}]]
2341 $i alias test::bar mfoo::bar $i
2342 set res [concat $res [interp eval $i {test::bar test2}]]
2344 namespace delete mfoo
2346 } -result {{child bar called (foo-child) (bar test1) (::tcltest) (::foo) (test1)} {parent bar called (foo-parent) (::mfoo) (test2)} {child bar called (foo-child) (test::bar test2) (::) (::foo) (test2)}}
2347 test interp-27.8 {hiding, namespaces and integrity} knownBug {
2348 namespace eval foo {
2350 proc bar {} {variable v; set v}
2351 # next command would currently generate an unknown command "bar" error.
2354 namespace delete foo
2355 list [catch {interp invokehidden {} foo::bar} msg] $msg
2356 } {1 {invalid hidden command name "foo"}}
2358 test interp-28.1 {getting fooled by child's namespace ?} -setup {
2359 set i [interp create -safe]
2360 proc parent {interp args} {interp hide $interp list}
2362 $i alias parent parent $i
2363 set r [interp eval $i {
2364 namespace eval foo {
2366 return "dummy foo::list"
2376 test interp-28.2 {parent's nsName cache should not cross} -setup {
2377 set i [interp create]
2378 $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
2381 set x {namespace children ::}
2382 set y [list namespace children ::]
2383 namespace delete {*}[filter [{*}$y]]
2384 set j [interp create]
2385 $j alias filter filter
2386 $j eval {namespace delete {*}[filter [namespace children ::]]}
2387 namespace eval foo {}
2388 list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
2392 } -result {::foo ::foo {} {}}
2394 # Part 29: recursion limit
2395 # 29.1.* Argument checking
2396 # 29.2.* Reading and setting the recursion limit
2397 # 29.3.* Does the recursion limit work?
2398 # 29.4.* Recursion limit inheritance by sub-interpreters
2399 # 29.5.* Confirming the recursionlimit command does not affect the parent
2400 # 29.6.* Safe interpreter restriction
2402 test interp-29.1.1 {interp recursionlimit argument checking} {
2403 list [catch {interp recursionlimit} msg] $msg
2404 } {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
2405 test interp-29.1.2 {interp recursionlimit argument checking} {
2406 list [catch {interp recursionlimit foo bar} msg] $msg
2407 } {1 {could not find interpreter "foo"}}
2408 test interp-29.1.3 {interp recursionlimit argument checking} {
2409 list [catch {interp recursionlimit foo bar baz} msg] $msg
2410 } {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
2411 test interp-29.1.4 {interp recursionlimit argument checking} {
2413 set result [catch {interp recursionlimit moo bar} msg]
2416 } {1 {expected integer but got "bar"}}
2417 test interp-29.1.5 {interp recursionlimit argument checking} {
2419 set result [catch {interp recursionlimit moo 0} msg]
2422 } {1 {recursion limit must be > 0}}
2423 test interp-29.1.6 {interp recursionlimit argument checking} {
2425 set result [catch {interp recursionlimit moo -1} msg]
2428 } {1 {recursion limit must be > 0}}
2429 test interp-29.1.7 {interp recursionlimit argument checking} {
2431 set result [catch {interp recursionlimit moo [expr {wide(1)<<32}]} msg]
2433 list $result [string range $msg 0 35]
2434 } {1 {integer value too large to represent}}
2435 test interp-29.1.8 {child recursionlimit argument checking} {
2437 set result [catch {moo recursionlimit foo bar} msg]
2440 } {1 {wrong # args: should be "moo recursionlimit ?newlimit?"}}
2441 test interp-29.1.9 {child recursionlimit argument checking} {
2443 set result [catch {moo recursionlimit foo} msg]
2446 } {1 {expected integer but got "foo"}}
2447 test interp-29.1.10 {child recursionlimit argument checking} {
2449 set result [catch {moo recursionlimit 0} msg]
2452 } {1 {recursion limit must be > 0}}
2453 test interp-29.1.11 {child recursionlimit argument checking} {
2455 set result [catch {moo recursionlimit -1} msg]
2458 } {1 {recursion limit must be > 0}}
2459 test interp-29.1.12 {child recursionlimit argument checking} {
2461 set result [catch {moo recursionlimit [expr {wide(1)<<32}]} msg]
2463 list $result [string range $msg 0 35]
2464 } {1 {integer value too large to represent}}
2465 test interp-29.2.1 {query recursion limit} {
2466 interp recursionlimit {}
2468 test interp-29.2.2 {query recursion limit} {
2469 set i [interp create]
2470 set n [interp recursionlimit $i]
2474 test interp-29.2.3 {query recursion limit} {
2475 set i [interp create]
2476 set n [$i recursionlimit]
2480 test interp-29.2.4 {query recursion limit} {
2481 set i [interp create]
2483 set n1 [interp recursionlimit {} 42]
2484 set n2 [interp recursionlimit {}]
2490 test interp-29.2.5 {query recursion limit} {
2491 set i [interp create]
2492 set n1 [interp recursionlimit $i 42]
2493 set n2 [interp recursionlimit $i]
2497 test interp-29.2.6 {query recursion limit} {
2498 set i [interp create]
2499 set n1 [interp recursionlimit $i 42]
2500 set n2 [$i recursionlimit]
2504 test interp-29.2.7 {query recursion limit} {
2505 set i [interp create]
2506 set n1 [$i recursionlimit 42]
2507 set n2 [interp recursionlimit $i]
2511 test interp-29.2.8 {query recursion limit} {
2512 set i [interp create]
2513 set n1 [$i recursionlimit 42]
2514 set n2 [$i recursionlimit]
2518 test interp-29.3.1 {recursion limit} {
2519 set i [interp create]
2520 set r [interp eval $i {
2521 interp recursionlimit {} 50
2522 proc p {} {incr ::i; p}
2524 list [catch p msg] $msg $i
2528 } {1 {too many nested evaluations (infinite loop?)} 49}
2529 test interp-29.3.2 {recursion limit} {
2530 set i [interp create]
2531 interp recursionlimit $i 50
2532 set r [interp eval $i {
2533 proc p {} {incr ::i; p}
2535 list [catch p msg] $msg $i
2539 } {1 {too many nested evaluations (infinite loop?)} 49}
2540 test interp-29.3.3 {recursion limit} {
2541 set i [interp create]
2542 $i recursionlimit 50
2543 set r [interp eval $i {
2544 proc p {} {incr ::i; p}
2546 list [catch p msg] $msg $i
2550 } {1 {too many nested evaluations (infinite loop?)} 49}
2551 test interp-29.3.4 {recursion limit error reporting} {
2553 set r1 [child eval {
2554 catch { # nesting level 1
2559 interp recursionlimit {} 5
2567 set r2 [child eval { set msg }]
2570 } {1 {falling back due to new recursion limit}}
2571 test interp-29.3.5 {recursion limit error reporting} {
2573 set r1 [child eval {
2574 catch { # nesting level 1
2579 interp recursionlimit {} 4
2587 set r2 [child eval { set msg }]
2590 } {1 {falling back due to new recursion limit}}
2591 test interp-29.3.6 {recursion limit error reporting} {
2593 set r1 [child eval {
2594 catch { # nesting level 1
2599 interp recursionlimit {} 6
2607 set r2 [child eval { set msg }]
2612 # Note that TEBC does not verify the interp's nesting level itself; the nesting
2613 # level will only be verified when it invokes a non-bcc'd command.
2615 test interp-29.3.7a {recursion limit error reporting} {
2617 after 0 {interp recursionlimit child 5}
2618 set r1 [child eval {
2619 catch { # nesting level 1
2632 set r2 [child eval { set msg }]
2636 test interp-29.3.7b {recursion limit error reporting} {
2638 after 0 {interp recursionlimit child 5}
2639 set r1 [child eval {
2640 catch { # nesting level 1
2653 set r2 [child eval { set msg }]
2657 test interp-29.3.7c {recursion limit error reporting} {
2659 after 0 {interp recursionlimit child 5}
2660 set r1 [child eval {
2661 catch { # nesting level 1
2675 set r2 [child eval { set msg }]
2678 } {1 {too many nested evaluations (infinite loop?)}}
2679 test interp-29.3.8a {recursion limit error reporting} {
2681 after 0 {interp recursionlimit child 4}
2682 set r1 [child eval {
2683 catch { # nesting level 1
2696 set r2 [child eval { set msg }]
2700 test interp-29.3.8b {recursion limit error reporting} {
2702 after 0 {interp recursionlimit child 4}
2703 set r1 [child eval {
2704 catch { # nesting level 1
2717 set r2 [child eval { set msg }]
2720 } {1 {too many nested evaluations (infinite loop?)}}
2721 test interp-29.3.9a {recursion limit error reporting} {
2723 after 0 {interp recursionlimit child 6}
2724 set r1 [child eval {
2725 catch { # nesting level 1
2738 set r2 [child eval { set msg }]
2742 test interp-29.3.9b {recursion limit error reporting} {
2744 after 0 {interp recursionlimit child 6}
2745 set r1 [child eval {
2746 catch { # nesting level 1
2759 set r2 [child eval { set msg }]
2763 test interp-29.3.10a {recursion limit error reporting} {
2765 after 0 {child recursionlimit 4}
2766 set r1 [child eval {
2767 catch { # nesting level 1
2780 set r2 [child eval { set msg }]
2784 test interp-29.3.10b {recursion limit error reporting} {
2786 after 0 {child recursionlimit 4}
2787 set r1 [child eval {
2788 catch { # nesting level 1
2801 set r2 [child eval { set msg }]
2804 } {1 {too many nested evaluations (infinite loop?)}}
2805 test interp-29.3.11a {recursion limit error reporting} {
2807 after 0 {child recursionlimit 5}
2808 set r1 [child eval {
2809 catch { # nesting level 1
2822 set r2 [child eval { set msg }]
2826 test interp-29.3.11b {recursion limit error reporting} {
2828 after 0 {child recursionlimit 5}
2829 set r1 [child eval {
2830 catch { # nesting level 1
2844 set r2 [child eval { set msg }]
2847 } {1 {too many nested evaluations (infinite loop?)}}
2848 test interp-29.3.12a {recursion limit error reporting} {
2850 after 0 {child recursionlimit 6}
2851 set r1 [child eval {
2852 catch { # nesting level 1
2865 set r2 [child eval { set msg }]
2869 test interp-29.3.12b {recursion limit error reporting} {
2871 after 0 {child recursionlimit 6}
2872 set r1 [child eval {
2873 catch { # nesting level 1
2887 set r2 [child eval { set msg }]
2891 test interp-29.4.1 {recursion limit inheritance} {
2892 set i [interp create]
2893 set ii [interp eval $i {
2894 interp recursionlimit {} 50
2897 set r [interp eval [list $i $ii] {
2898 proc p {} {incr ::i; p}
2906 test interp-29.4.2 {recursion limit inheritance} {
2907 set i [interp create]
2908 $i recursionlimit 50
2909 set ii [interp eval $i {interp create}]
2910 set r [interp eval [list $i $ii] {
2911 proc p {} {incr ::i; p}
2919 test interp-29.5.1 {does child recursion limit affect parent?} {
2920 set before [interp recursionlimit {}]
2921 set i [interp create]
2922 interp recursionlimit $i 20000
2923 set after [interp recursionlimit {}]
2924 set childlimit [interp recursionlimit $i]
2926 list [expr {$before == $after}] $childlimit
2928 test interp-29.5.2 {does child recursion limit affect parent?} {
2929 set before [interp recursionlimit {}]
2930 set i [interp create]
2931 interp recursionlimit $i 20000
2932 set after [interp recursionlimit {}]
2933 set childlimit [$i recursionlimit]
2935 list [expr {$before == $after}] $childlimit
2937 test interp-29.5.3 {does child recursion limit affect parent?} {
2938 set before [interp recursionlimit {}]
2939 set i [interp create]
2940 $i recursionlimit 20000
2941 set after [interp recursionlimit {}]
2942 set childlimit [interp recursionlimit $i]
2944 list [expr {$before == $after}] $childlimit
2946 test interp-29.5.4 {does child recursion limit affect parent?} {
2947 set before [interp recursionlimit {}]
2948 set i [interp create]
2949 $i recursionlimit 20000
2950 set after [interp recursionlimit {}]
2951 set childlimit [$i recursionlimit]
2953 list [expr {$before == $after}] $childlimit
2955 test interp-29.6.1 {safe interpreter recursion limit} {
2956 interp create child -safe
2957 set n [interp recursionlimit child]
2961 test interp-29.6.2 {safe interpreter recursion limit} {
2962 interp create child -safe
2963 set n [child recursionlimit]
2967 test interp-29.6.3 {safe interpreter recursion limit} {
2968 interp create child -safe
2969 set n1 [interp recursionlimit child 42]
2970 set n2 [interp recursionlimit child]
2974 test interp-29.6.4 {safe interpreter recursion limit} {
2975 interp create child -safe
2976 set n1 [child recursionlimit 42]
2977 set n2 [interp recursionlimit child]
2981 test interp-29.6.5 {safe interpreter recursion limit} {
2982 interp create child -safe
2983 set n1 [interp recursionlimit child 42]
2984 set n2 [child recursionlimit]
2988 test interp-29.6.6 {safe interpreter recursion limit} {
2989 interp create child -safe
2990 set n1 [child recursionlimit 42]
2991 set n2 [child recursionlimit]
2995 test interp-29.6.7 {safe interpreter recursion limit} {
2996 interp create child -safe
2997 set n1 [child recursionlimit 42]
2998 set n2 [child recursionlimit]
3002 test interp-29.6.8 {safe interpreter recursion limit} {
3003 interp create child -safe
3004 set n [catch {child eval {interp recursionlimit {} 42}} msg]
3007 } {1 {permission denied: safe interpreters cannot change recursion limit}}
3008 test interp-29.6.9 {safe interpreter recursion limit} {
3009 interp create child -safe
3012 interp create child2 -safe
3014 interp recursionlimit child2 42
3021 } {1 {permission denied: safe interpreters cannot change recursion limit}}
3022 test interp-29.6.10 {safe interpreter recursion limit} {
3023 interp create child -safe
3026 interp create child2 -safe
3028 child2 recursionlimit 42
3035 } {1 {permission denied: safe interpreters cannot change recursion limit}}
3038 # # Deep recursion (into interps when the regular one fails):
3039 # # still crashes...
3041 # if {[catch p ret]} {
3043 # set i [interp create]
3044 # interp eval $i [list proc p {} [info body p]]
3054 # more tests needed...
3057 #test interp-29.1 {interp and stack (info level)} {
3060 # End of stack-recursion tests
3062 # This test dumps core in Tcl 8.0.3!
3063 test interp-30.1 {deletion of aliases inside namespaces} {
3064 set i [interp create]
3065 $i alias ns::cmd list
3069 test interp-31.1 {alias invocation scope} {
3070 proc mySet {varName value} {
3071 upvar 1 $varName localVar
3074 interp alias {} myNewSet {} mySet
3075 proc testMyNewSet {value} {
3080 set result [testMyNewSet "ok"]
3081 rename testMyNewSet {}
3087 test interp-32.1 {parent's working directory should be inherited by a child interp} -setup {
3088 cd [temporaryDirectory]
3091 set i [interp create]
3092 set child [$i eval pwd]
3096 lappend parent [pwd]
3097 set i [interp create]
3098 lappend child [$i eval pwd]
3100 file delete cwd_test
3102 expr {[string equal $parent $child] ? 1 :
3103 "\{$parent\} != \{$child\}"}
3105 cd [workingDirectory]
3108 test interp-33.1 {refCounting for target words of alias [Bug 730244]} {
3109 # This test will panic if Bug 730244 is not fixed.
3110 set i [interp create]
3111 proc testHelper args {rename testHelper {}; return $args}
3112 # Note: interp names are simple words by default
3113 trace add execution testHelper enter "interp alias $i alias {} ;#"
3114 interp alias $i alias {} testHelper this
3118 test interp-34.1 {basic test of limits - calling commands} -body {
3119 set i [interp create]
3122 for {set x 0} {$x<1000000} {incr x} {
3123 # Calls to this are not bytecoded away
3128 $i limit command -value 1000
3130 } -returnCodes error -result {command count limit exceeded} -cleanup {
3133 test interp-34.2 {basic test of limits - bytecoded commands} -body {
3134 set i [interp create]
3137 for {set x 0} {$x<1000000} {incr x} {
3138 # Calls to this *are* bytecoded away
3143 $i limit command -value 1000
3145 } -returnCodes error -result {command count limit exceeded} -cleanup {
3148 test interp-34.3 {basic test of limits - pure bytecode loop} -body {
3149 set i [interp create]
3153 # No bytecode at all here...
3157 # We use a time limit here; command limits don't trap this case
3158 $i limit time -seconds [expr {[clock seconds]+2}]
3160 } -returnCodes error -result {time limit exceeded} -cleanup {
3163 test interp-34.3.1 {basic test of limits - pure inside-command loop} -body {
3164 set i [interp create]
3169 # No bytecode at all here...
3173 # We use a time limit here; command limits don't trap this case
3174 $i limit time -seconds [expr {[clock seconds] + 2}]
3176 } -returnCodes error -result {time limit exceeded} -cleanup {
3179 test interp-34.4 {limits with callbacks: extending limits} -setup {
3180 set i [interp create]
3188 proc cb2 {newlimit args} {
3191 $i limit command -value $newlimit
3194 interp alias $i foo {} cb1
3195 set curlim [$i eval info cmdcount]
3196 $i limit command -command "cb2 [expr {$curlim + 100}]" \
3197 -value [expr {$curlim + 10}]
3198 $i eval {for {set i 0} {$i<10} {incr i} {foo}}
3200 } -result {6 4 b} -cleanup {
3205 # The next three tests exercise all the three ways that limit handlers
3206 # can be deleted. Fully verifying this requires additional source
3207 # code instrumentation.
3208 test interp-34.5 {limits with callbacks: removing limits} -setup {
3209 set i [interp create]
3217 proc cb2 {newlimit args} {
3220 $i limit command -value $newlimit
3223 interp alias $i foo {} cb1
3224 set curlim [$i eval info cmdcount]
3225 $i limit command -command "cb2 {}" -value [expr {$curlim + 10}]
3226 $i eval {for {set i 0} {$i<10} {incr i} {foo}}
3228 } -result {6 4 b} -cleanup {
3233 test interp-34.6 {limits with callbacks: removing limits and handlers} -setup {
3234 set i [interp create]
3245 $i limit command -value {} -command {}
3248 interp alias $i foo {} cb1
3249 set curlim [$i eval info cmdcount]
3250 $i limit command -command cb2 -value [expr {$curlim + 10}]
3251 $i eval {for {set i 0} {$i<10} {incr i} {foo}}
3253 } -result {6 4 b} -cleanup {
3258 test interp-34.7 {limits with callbacks: deleting the handler interp} -setup {
3259 set i [interp create]
3261 set i [interp create]
3269 $i limit command -value [expr {$curlim + 1000}]
3275 interp alias [list $i $subi] foo {} cb4
3283 set subi [$i eval set i]
3284 interp alias $i trapToParent {} cb3
3290 interp alias $i foo {} cb1
3291 set curlim [$i eval info cmdcount]
3292 $i limit command -command cb2 -value [expr {$curlim + 10}]
3296 for {set i 0} {$i<10} {incr i} {foo}
3299 list $n [interp exists $i]
3300 } -result {4 0} -cleanup {
3305 test interp-34.8 {time limits trigger in vwaits} -body {
3306 set i [interp create]
3307 interp limit $i time -seconds [expr {[clock seconds] + 1}] -granularity 1
3314 } -returnCodes error -result {limit exceeded}
3315 test interp-34.9 {time limits trigger in blocking after} {
3316 set i [interp create]
3317 set t0 [clock seconds]
3318 interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1
3320 $i eval {after 10000}
3322 set t1 [clock seconds]
3324 list $code $msg [expr {($t1-$t0) < 3 ? "OK" : $t1-$t0}]
3325 } {1 {time limit exceeded} OK}
3326 test interp-34.10 {time limits trigger in vwaits: Bug 1221395} -body {
3327 set i [interp create]
3328 # Assume someone hasn't set the clock to early 1970!
3329 $i limit time -seconds 1 -granularity 4
3330 interp alias $i log {} lappend result
3341 } -result {1 {time limit exceeded}}
3342 test interp-34.11 {time limit extension in callbacks} -setup {
3346 $i limit time -seconds $t -command cb2
3353 set i [interp create]
3354 set t0 [clock seconds]
3355 $i limit time -seconds [expr {$t0 + 1}] -granularity 1 \
3356 -command "cb1 $i [expr {$t0 + 2}]"
3358 lappend ::result [catch {
3360 for {set i 0} {$i<30} {incr i} {
3365 set t1 [clock seconds]
3366 lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
3369 } -result {cb1 cb2 1 {time limit exceeded} ok} -cleanup {
3373 test interp-34.12 {time limit extension in callbacks} -setup {
3377 set times [lassign $times t]
3378 $i limit time -seconds $t
3381 set i [interp create]
3382 set t0 [clock seconds]
3383 set ::times "[expr {$t0 + 2}] [expr {$t0 + 100}]"
3384 $i limit time -seconds [expr {$t0 + 1}] -granularity 1 -command "cb1 $i"
3386 lappend ::result [catch {
3388 for {set i 0} {$i<30} {incr i} {
3393 set t1 [clock seconds]
3394 lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
3397 } -result {cb1 cb1 0 {} ok} -cleanup {
3400 test interp-34.13 {time limit granularity and vwait: Bug 2891362} -setup {
3401 set i [interp create -safe]
3403 $i limit time -seconds [clock add [clock seconds] 1 second]
3405 after 2000 set x timeout
3411 } -returnCodes error -result {limit exceeded}
3413 test interp-35.1 {interp limit syntax} -body {
3415 } -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
3416 test interp-35.2 {interp limit syntax} -body {
3418 } -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
3419 test interp-35.3 {interp limit syntax} -body {
3421 } -returnCodes error -result {bad limit type "foo": must be commands or time}
3422 test interp-35.4 {interp limit syntax} -body {
3423 set i [interp create]
3424 set dict [interp limit $i commands]
3426 foreach key [lsort [dict keys $dict]] {
3427 lappend result $key [dict get $dict $key]
3432 } -result {-command {} -granularity 1 -value {}}
3433 test interp-35.5 {interp limit syntax} -body {
3434 set i [interp create]
3435 interp limit $i commands -granularity
3439 test interp-35.6 {interp limit syntax} -body {
3440 set i [interp create]
3441 interp limit $i commands -granularity 2
3445 test interp-35.7 {interp limit syntax} -body {
3446 set i [interp create]
3447 interp limit $i commands -foobar
3450 } -returnCodes error -result {bad option "-foobar": must be -command, -granularity, or -value}
3451 test interp-35.8 {interp limit syntax} -body {
3452 set i [interp create]
3453 interp limit $i commands -granularity foobar
3456 } -returnCodes error -result {expected integer but got "foobar"}
3457 test interp-35.9 {interp limit syntax} -body {
3458 set i [interp create]
3459 interp limit $i commands -granularity 0
3462 } -returnCodes error -result {granularity must be at least 1}
3463 test interp-35.10 {interp limit syntax} -body {
3464 set i [interp create]
3465 interp limit $i commands -value foobar
3468 } -returnCodes error -result {expected integer but got "foobar"}
3469 test interp-35.11 {interp limit syntax} -body {
3470 set i [interp create]
3471 interp limit $i commands -value -1
3474 } -returnCodes error -result {command limit value must be at least 0}
3475 test interp-35.12 {interp limit syntax} -body {
3476 set i [interp create]
3477 set dict [interp limit $i time]
3479 foreach key [lsort [dict keys $dict]] {
3480 lappend result $key [dict get $dict $key]
3485 } -result {-command {} -granularity 10 -milliseconds {} -seconds {}}
3486 test interp-35.13 {interp limit syntax} -body {
3487 set i [interp create]
3488 interp limit $i time -granularity
3492 test interp-35.14 {interp limit syntax} -body {
3493 set i [interp create]
3494 interp limit $i time -granularity 2
3498 test interp-35.15 {interp limit syntax} -body {
3499 set i [interp create]
3500 interp limit $i time -foobar
3503 } -returnCodes error -result {bad option "-foobar": must be -command, -granularity, -milliseconds, or -seconds}
3504 test interp-35.16 {interp limit syntax} -body {
3505 set i [interp create]
3506 interp limit $i time -granularity foobar
3509 } -returnCodes error -result {expected integer but got "foobar"}
3510 test interp-35.17 {interp limit syntax} -body {
3511 set i [interp create]
3512 interp limit $i time -granularity 0
3515 } -returnCodes error -result {granularity must be at least 1}
3516 test interp-35.18 {interp limit syntax} -body {
3517 set i [interp create]
3518 interp limit $i time -seconds foobar
3521 } -returnCodes error -result {expected integer but got "foobar"}
3522 test interp-35.19 {interp limit syntax} -body {
3523 set i [interp create]
3524 interp limit $i time -seconds -1
3527 } -returnCodes error -result {seconds must be at least 0}
3528 test interp-35.20 {interp limit syntax} -body {
3529 set i [interp create]
3530 interp limit $i time -millis foobar
3533 } -returnCodes error -result {expected integer but got "foobar"}
3534 test interp-35.21 {interp limit syntax} -body {
3535 set i [interp create]
3536 interp limit $i time -millis -1
3539 } -returnCodes error -result {milliseconds must be at least 0}
3540 test interp-35.22 {interp time limits normalize milliseconds} -body {
3541 set i [interp create]
3542 interp limit $i time -seconds 1 -millis 1500
3543 list [$i limit time -seconds] [$i limit time -millis]
3548 test interp-35.23 {interp command limits can't touch current interp} -body {
3549 interp limit {} commands -value 10
3550 } -returnCodes error -result {limits on current interpreter inaccessible}
3551 test interp-35.24 {interp time limits can't touch current interp} -body {
3552 interp limit {} time -seconds 2
3553 } -returnCodes error -result {limits on current interpreter inaccessible}
3555 test interp-36.1 {interp bgerror syntax} -body {
3557 } -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
3558 test interp-36.2 {interp bgerror syntax} -body {
3559 interp bgerror x y z
3560 } -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
3561 test interp-36.3 {interp bgerror syntax} -setup {
3567 } -returnCodes error -result {wrong # args: should be "child bgerror ?cmdPrefix?"}
3568 test interp-36.4 {ChildBgerror syntax} -setup {
3574 } -returnCodes error -result {cmdPrefix must be list of length >= 1}
3575 test interp-36.5 {ChildBgerror syntax} -setup {
3581 } -returnCodes error -result {cmdPrefix must be list of length >= 1}
3582 test interp-36.6 {ChildBgerror returns handler} -setup {
3585 child bgerror {foo bar soom}
3588 } -result {foo bar soom}
3589 test interp-36.7 {ChildBgerror sets error handler of child [1999035]} -setup {
3591 child alias handler handler
3592 child bgerror handler
3593 variable result {untouched}
3594 proc handler {args} {
3596 set result [lindex $args 0]
3602 after 10 [list ::set [namespace which -variable done] {}]
3603 vwait [namespace which -variable done]
3608 unset -nocomplain result
3612 test interp-37.1 {safe interps and min() and max(): Bug 2895741} -setup {
3613 catch {interp delete a}
3617 interp create {a b} -safe
3618 lappend result [interp eval a {expr {min(5,2,3)*max(7,13,11)}}]
3619 lappend result [interp eval {a b} {expr {min(5,2,3)*max(7,13,11)}}]
3621 unset -nocomplain result
3625 test interp-38.1 {interp debug one-way switch} -setup {
3626 catch {interp delete a}
3628 interp debug a -frame 1
3630 # TIP #3xx interp debug frame is a one-way switch
3631 interp debug a -frame 0
3635 test interp-38.2 {interp debug env var} -setup {
3636 catch {interp delete a}
3637 set ::env(TCL_INTERP_DEBUG_FRAME) 1
3642 unset -nocomplain ::env(TCL_INTERP_DEBUG_FRAME)
3644 } -result {-frame 1}
3645 test interp-38.3 {interp debug wrong args} -body {
3649 } -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
3650 test interp-38.4 {interp debug basic setup} -constraints {!singleTestInterp} -body {
3652 } -result {-frame 0}
3653 test interp-38.5 {interp debug basic setup} -constraints {!singleTestInterp} -body {
3656 test interp-38.6 {interp debug basic setup} -body {
3657 interp debug -frames
3658 } -returnCodes error -result {could not find interpreter "-frames"}
3659 test interp-38.7 {interp debug basic setup} -body {
3660 interp debug {} -frames
3661 } -returnCodes error -result {bad debug option "-frames": must be -frame}
3662 test interp-38.8 {interp debug basic setup} -body {
3663 interp debug {} -frame 0 bogus
3666 } -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
3669 unset -nocomplain hidden_cmds
3670 foreach i [interp children] {
3673 ::tcltest::cleanupTests