sl@0: # Commands covered: if sl@0: # sl@0: # This file contains a collection of tests for one or more of the Tcl sl@0: # built-in commands. Sourcing this file into Tcl runs the tests and sl@0: # generates output for errors. No output means no errors were found. sl@0: # sl@0: # Copyright (c) 1996 Sun Microsystems, Inc. sl@0: # Copyright (c) 1998-1999 by Scriptics Corporation. sl@0: # sl@0: # See the file "license.terms" for information on usage and redistribution sl@0: # of this file, and for a DISCLAIMER OF ALL WARRANTIES. sl@0: # sl@0: # RCS: @(#) $Id: if.test,v 1.7 2001/12/04 15:36:29 dkf Exp $ sl@0: sl@0: if {[lsearch [namespace children] ::tcltest] == -1} { sl@0: package require tcltest sl@0: namespace import -force ::tcltest::* sl@0: } sl@0: sl@0: # Basic "if" operation. sl@0: sl@0: catch {unset a} sl@0: test if-1.1 {TclCompileIfCmd: missing if/elseif test} { sl@0: list [catch {if} msg] $msg sl@0: } {1 {wrong # args: no expression after "if" argument}} sl@0: test if-1.2 {TclCompileIfCmd: error in if/elseif test} { sl@0: list [catch {if {[error "error in condition"]} foo} msg] $msg sl@0: } {1 {error in condition}} sl@0: test if-1.3 {TclCompileIfCmd: error in if/elseif test} { sl@0: list [catch {if {1+}} msg] $msg $errorInfo sl@0: } {1 {syntax error in expression "1+": premature end of expression} {syntax error in expression "1+": premature end of expression sl@0: ("if" test expression) sl@0: while compiling sl@0: "if {1+}"}} sl@0: test if-1.4 {TclCompileIfCmd: if/elseif test in braces} { sl@0: set a {} sl@0: if {1<2} {set a 1} sl@0: set a sl@0: } {1} sl@0: test if-1.5 {TclCompileIfCmd: if/elseif test not in braces} { sl@0: set a {} sl@0: if 1<2 {set a 1} sl@0: set a sl@0: } {1} sl@0: test if-1.6 {TclCompileIfCmd: multiline test expr} { sl@0: set a {} sl@0: if {($tcl_platform(platform) != "foobar1") && \ sl@0: ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4} sl@0: set a sl@0: } 3 sl@0: test if-1.7 {TclCompileIfCmd: "then" after if/elseif test} { sl@0: set a {} sl@0: if 4>3 then {set a 1} sl@0: set a sl@0: } {1} sl@0: test if-1.8 {TclCompileIfCmd: keyword other than "then" after if/elseif test} { sl@0: set a {} sl@0: catch {if 1<2 therefore {set a 1}} msg sl@0: set msg sl@0: } {invalid command name "therefore"} sl@0: test if-1.9 {TclCompileIfCmd: missing "then" body} { sl@0: set a {} sl@0: catch {if 1<2 then} msg sl@0: set msg sl@0: } {wrong # args: no script following "then" argument} sl@0: test if-1.10 {TclCompileIfCmd: error in "then" body} { sl@0: set a {} sl@0: list [catch {if {$a!="xxx"} then {set}} msg] $msg $errorInfo sl@0: } {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?" sl@0: while compiling sl@0: "set" sl@0: ("if" then script line 1) sl@0: while compiling sl@0: "if {$a!="xxx"} then {set}"}} sl@0: test if-1.11 {TclCompileIfCmd: error in "then" body} { sl@0: list [catch {if 2 then {[error "error in then clause"]}} msg] $msg sl@0: } {1 {error in then clause}} sl@0: test if-1.12 {TclCompileIfCmd: "then" body in quotes} { sl@0: set a {} sl@0: if 27>17 "append a x" sl@0: set a sl@0: } {x} sl@0: test if-1.13 {TclCompileIfCmd: computed "then" body} { sl@0: catch {unset x1} sl@0: catch {unset x2} sl@0: set a {} sl@0: set x1 {append a x1} sl@0: set x2 {; append a x2} sl@0: set a {} sl@0: if 1 $x1$x2 sl@0: set a sl@0: } {x1x2} sl@0: test if-1.14 {TclCompileIfCmd: taking proper branch} { sl@0: set a {} sl@0: if 1<2 {set a 1} sl@0: set a sl@0: } 1 sl@0: test if-1.15 {TclCompileIfCmd: taking proper branch} { sl@0: set a {} sl@0: if 1>2 {set a 1} sl@0: set a sl@0: } {} sl@0: test if-1.16 {TclCompileIfCmd: test jumpFalse instruction replacement after long "then" body} { sl@0: catch {unset i} sl@0: set a {} sl@0: if 1<2 { sl@0: set a 1 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 2 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 3 sl@0: } sl@0: set a sl@0: } 3 sl@0: test if-1.17 {TclCompileIfCmd: if/elseif test in quotes} { sl@0: set a {} sl@0: list [catch {if {"0 < 3"} {set a 1}} msg] $msg sl@0: } {1 {expected boolean value but got "0 < 3"}} sl@0: sl@0: sl@0: test if-2.1 {TclCompileIfCmd: "elseif" after if/elseif test} { sl@0: set a {} sl@0: if 3>4 {set a 1} elseif 1 {set a 2} sl@0: set a sl@0: } {2} sl@0: # Since "else" is optional, the "elwood" below is treated as a command. sl@0: # But then there shouldn't be any additional argument words for the "if". sl@0: test if-2.2 {TclCompileIfCmd: keyword other than "elseif"} { sl@0: set a {} sl@0: catch {if 1<2 {set a 1} elwood {set a 2}} msg sl@0: set msg sl@0: } {wrong # args: extra words after "else" clause in "if" command} sl@0: test if-2.3 {TclCompileIfCmd: missing expression after "elseif"} { sl@0: set a {} sl@0: catch {if 1<2 {set a 1} elseif} msg sl@0: set msg sl@0: } {wrong # args: no expression after "elseif" argument} sl@0: test if-2.4 {TclCompileIfCmd: error in expression after "elseif"} { sl@0: set a {} sl@0: list [catch {if 3>4 {set a 1} elseif {1>}} msg] $msg $errorInfo sl@0: } {1 {syntax error in expression "1>": premature end of expression} {syntax error in expression "1>": premature end of expression sl@0: ("if" test expression) sl@0: while compiling sl@0: "if 3>4 {set a 1} elseif {1>}"}} sl@0: test if-2.5 {TclCompileIfCmd: test jumpFalse instruction replacement after long "elseif" body} { sl@0: catch {unset i} sl@0: set a {} sl@0: if 1>2 { sl@0: set a 1 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 2 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 3 sl@0: } elseif 1<2 then { #; this if arm should be taken sl@0: set a 4 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 5 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 6 sl@0: } sl@0: set a sl@0: } 6 sl@0: sl@0: test if-3.1 {TclCompileIfCmd: "else" clause} { sl@0: set a {} sl@0: if 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3} sl@0: set a sl@0: } 3 sl@0: # Since "else" is optional, the "elsex" below is treated as a command. sl@0: # But then there shouldn't be any additional argument words for the "if". sl@0: test if-3.2 {TclCompileIfCmd: keyword other than "else"} { sl@0: set a {} sl@0: catch {if 1<2 then {set a 1} elsex {set a 2}} msg sl@0: set msg sl@0: } {wrong # args: extra words after "else" clause in "if" command} sl@0: test if-3.3 {TclCompileIfCmd: missing body after "else"} { sl@0: set a {} sl@0: catch {if 2<1 {set a 1} else} msg sl@0: set msg sl@0: } {wrong # args: no script following "else" argument} sl@0: test if-3.4 {TclCompileIfCmd: error compiling body after "else"} { sl@0: set a {} sl@0: catch {if 2<1 {set a 1} else {set}} msg sl@0: set errorInfo sl@0: } {wrong # args: should be "set varName ?newValue?" sl@0: while compiling sl@0: "set" sl@0: ("if" else script line 1) sl@0: while compiling sl@0: "if 2<1 {set a 1} else {set}"} sl@0: test if-3.5 {TclCompileIfCmd: extra arguments after "else" argument} { sl@0: set a {} sl@0: catch {if 2<1 {set a 1} else {set a 2} or something} msg sl@0: set msg sl@0: } {wrong # args: extra words after "else" clause in "if" command} sl@0: # The following test also checks whether contained loops and other sl@0: # commands are properly relocated because a short jump must be replaced sl@0: # by a "long distance" one. sl@0: test if-3.6 {TclCompileIfCmd: test jumpFalse instruction replacement after long "else" clause} { sl@0: catch {unset i} sl@0: set a {} sl@0: if 1>2 { sl@0: set a 1 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 2 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 3 sl@0: } elseif 1==2 then { #; this if arm should be taken sl@0: set a 4 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 5 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 6 sl@0: } else { sl@0: set a 7 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 8 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: if {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 9 sl@0: } sl@0: set a sl@0: } 9 sl@0: sl@0: test if-4.1 {TclCompileIfCmd: "if" command result} { sl@0: set a {} sl@0: set a [if 3<4 {set i 27}] sl@0: set a sl@0: } 27 sl@0: test if-4.2 {TclCompileIfCmd: "if" command result} { sl@0: set a {} sl@0: set a [if 3>4 {set i 27}] sl@0: set a sl@0: } {} sl@0: test if-4.3 {TclCompileIfCmd: "if" command result} { sl@0: set a {} sl@0: set a [if 0 {set i 1} elseif 1 {set i 2}] sl@0: set a sl@0: } 2 sl@0: test if-4.4 {TclCompileIfCmd: "if" command result} { sl@0: set a {} sl@0: set a [if 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}] sl@0: set a sl@0: } 4 sl@0: test if-4.5 {TclCompileIfCmd: return value} { sl@0: if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi} sl@0: } def sl@0: sl@0: # Check "if" and computed command names. sl@0: sl@0: catch {unset a} sl@0: test if-5.1 {if cmd with computed command names: missing if/elseif test} { sl@0: set z if sl@0: list [catch {$z} msg] $msg sl@0: } {1 {wrong # args: no expression after "if" argument}} sl@0: sl@0: test if-5.2 {if cmd with computed command names: error in if/elseif test} { sl@0: set z if sl@0: list [catch {$z {[error "error in condition"]} foo} msg] $msg sl@0: } {1 {error in condition}} sl@0: test if-5.3 {if cmd with computed command names: error in if/elseif test} { sl@0: set z if sl@0: list [catch {$z {1+}} msg] $msg $errorInfo sl@0: } {1 {syntax error in expression "1+": premature end of expression} {syntax error in expression "1+": premature end of expression sl@0: while executing sl@0: "$z {1+}"}} sl@0: test if-5.4 {if cmd with computed command names: if/elseif test in braces} { sl@0: set z if sl@0: set a {} sl@0: $z {1<2} {set a 1} sl@0: set a sl@0: } {1} sl@0: test if-5.5 {if cmd with computed command names: if/elseif test not in braces} { sl@0: set z if sl@0: set a {} sl@0: $z 1<2 {set a 1} sl@0: set a sl@0: } {1} sl@0: test if-5.6 {if cmd with computed command names: multiline test expr} { sl@0: set z if sl@0: set a {} sl@0: $z {($tcl_platform(platform) != "foobar1") && \ sl@0: ($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4} sl@0: set a sl@0: } 3 sl@0: test if-5.7 {if cmd with computed command names: "then" after if/elseif test} { sl@0: set z if sl@0: set a {} sl@0: $z 4>3 then {set a 1} sl@0: set a sl@0: } {1} sl@0: test if-5.8 {if cmd with computed command names: keyword other than "then" after if/elseif test} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 1<2 therefore {set a 1}} msg sl@0: set msg sl@0: } {invalid command name "therefore"} sl@0: test if-5.9 {if cmd with computed command names: missing "then" body} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 1<2 then} msg sl@0: set msg sl@0: } {wrong # args: no script following "then" argument} sl@0: test if-5.10 {if cmd with computed command names: error in "then" body} { sl@0: set z if sl@0: set a {} sl@0: list [catch {$z {$a!="xxx"} then {set}} msg] $msg $errorInfo sl@0: } {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?" sl@0: while compiling sl@0: "set" sl@0: invoked from within sl@0: "$z {$a!="xxx"} then {set}"}} sl@0: test if-5.11 {if cmd with computed command names: error in "then" body} { sl@0: set z if sl@0: list [catch {$z 2 then {[error "error in then clause"]}} msg] $msg sl@0: } {1 {error in then clause}} sl@0: test if-5.12 {if cmd with computed command names: "then" body in quotes} { sl@0: set z if sl@0: set a {} sl@0: $z 27>17 "append a x" sl@0: set a sl@0: } {x} sl@0: test if-5.13 {if cmd with computed command names: computed "then" body} { sl@0: set z if sl@0: catch {unset x1} sl@0: catch {unset x2} sl@0: set a {} sl@0: set x1 {append a x1} sl@0: set x2 {; append a x2} sl@0: set a {} sl@0: $z 1 $x1$x2 sl@0: set a sl@0: } {x1x2} sl@0: test if-5.14 {if cmd with computed command names: taking proper branch} { sl@0: set z if sl@0: set a {} sl@0: $z 1<2 {set a 1} sl@0: set a sl@0: } 1 sl@0: test if-5.15 {if cmd with computed command names: taking proper branch} { sl@0: set z if sl@0: set a {} sl@0: $z 1>2 {set a 1} sl@0: set a sl@0: } {} sl@0: test if-5.16 {if cmd with computed command names: test jumpFalse instruction replacement after long "then" body} { sl@0: set z if sl@0: catch {unset i} sl@0: set a {} sl@0: $z 1<2 { sl@0: set a 1 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 2 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 3 sl@0: } sl@0: set a sl@0: } 3 sl@0: test if-5.17 {if cmd with computed command names: if/elseif test in quotes} { sl@0: set z if sl@0: set a {} sl@0: list [catch {$z {"0 < 3"} {set a 1}} msg] $msg sl@0: } {1 {expected boolean value but got "0 < 3"}} sl@0: sl@0: sl@0: test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} { sl@0: set z if sl@0: set a {} sl@0: $z 3>4 {set a 1} elseif 1 {set a 2} sl@0: set a sl@0: } {2} sl@0: # Since "else" is optional, the "elwood" below is treated as a command. sl@0: # But then there shouldn't be any additional argument words for the "if". sl@0: test if-6.2 {if cmd with computed command names: keyword other than "elseif"} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 1<2 {set a 1} elwood {set a 2}} msg sl@0: set msg sl@0: } {wrong # args: extra words after "else" clause in "if" command} sl@0: test if-6.3 {if cmd with computed command names: missing expression after "elseif"} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 1<2 {set a 1} elseif} msg sl@0: set msg sl@0: } {wrong # args: no expression after "elseif" argument} sl@0: test if-6.4 {if cmd with computed command names: error in expression after "elseif"} { sl@0: set z if sl@0: set a {} sl@0: list [catch {$z 3>4 {set a 1} elseif {1>}} msg] $msg $errorInfo sl@0: } {1 {syntax error in expression "1>": premature end of expression} {syntax error in expression "1>": premature end of expression sl@0: while executing sl@0: "$z 3>4 {set a 1} elseif {1>}"}} sl@0: test if-6.5 {if cmd with computed command names: test jumpFalse instruction replacement after long "elseif" body} { sl@0: set z if sl@0: catch {unset i} sl@0: set a {} sl@0: $z 1>2 { sl@0: set a 1 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 2 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 3 sl@0: } elseif 1<2 then { #; this if arm should be taken sl@0: set a 4 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 5 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 6 sl@0: } sl@0: set a sl@0: } 6 sl@0: sl@0: test if-7.1 {if cmd with computed command names: "else" clause} { sl@0: set z if sl@0: set a {} sl@0: $z 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3} sl@0: set a sl@0: } 3 sl@0: # Since "else" is optional, the "elsex" below is treated as a command. sl@0: # But then there shouldn't be any additional argument words for the "if". sl@0: test if-7.2 {if cmd with computed command names: keyword other than "else"} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 1<2 then {set a 1} elsex {set a 2}} msg sl@0: set msg sl@0: } {wrong # args: extra words after "else" clause in "if" command} sl@0: test if-7.3 {if cmd with computed command names: missing body after "else"} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 2<1 {set a 1} else} msg sl@0: set msg sl@0: } {wrong # args: no script following "else" argument} sl@0: test if-7.4 {if cmd with computed command names: error compiling body after "else"} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 2<1 {set a 1} else {set}} msg sl@0: set errorInfo sl@0: } {wrong # args: should be "set varName ?newValue?" sl@0: while compiling sl@0: "set" sl@0: invoked from within sl@0: "$z 2<1 {set a 1} else {set}"} sl@0: test if-7.5 {if cmd with computed command names: extra arguments after "else" argument} { sl@0: set z if sl@0: set a {} sl@0: catch {$z 2<1 {set a 1} else {set a 2} or something} msg sl@0: set msg sl@0: } {wrong # args: extra words after "else" clause in "if" command} sl@0: # The following test also checks whether contained loops and other sl@0: # commands are properly relocated because a short jump must be replaced sl@0: # by a "long distance" one. sl@0: test if-7.6 {if cmd with computed command names: test jumpFalse instruction replacement after long "else" clause} { sl@0: set z if sl@0: catch {unset i} sl@0: set a {} sl@0: $z 1>2 { sl@0: set a 1 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 2 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 3 sl@0: } elseif 1==2 then { #; this if arm should be taken sl@0: set a 4 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 5 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 6 sl@0: } else { sl@0: set a 7 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 8 sl@0: while {$a != "xxx"} { sl@0: break; sl@0: while {$i >= 0} { sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: $z {[string compare $a "bar"] < 0} { sl@0: set i $i sl@0: set i [lindex $s $i] sl@0: } sl@0: set i [expr $i-1] sl@0: } sl@0: } sl@0: set a 9 sl@0: } sl@0: set a sl@0: } 9 sl@0: sl@0: test if-8.1 {if cmd with computed command names: "if" command result} { sl@0: set z if sl@0: set a {} sl@0: set a [$z 3<4 {set i 27}] sl@0: set a sl@0: } 27 sl@0: test if-8.2 {if cmd with computed command names: "if" command result} { sl@0: set z if sl@0: set a {} sl@0: set a [$z 3>4 {set i 27}] sl@0: set a sl@0: } {} sl@0: test if-8.3 {if cmd with computed command names: "if" command result} { sl@0: set z if sl@0: set a {} sl@0: set a [$z 0 {set i 1} elseif 1 {set i 2}] sl@0: set a sl@0: } 2 sl@0: test if-8.4 {if cmd with computed command names: "if" command result} { sl@0: set z if sl@0: set a {} sl@0: set a [$z 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}] sl@0: set a sl@0: } 4 sl@0: test if-8.5 {if cmd with computed command names: return value} { sl@0: set z if sl@0: $z 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi} sl@0: } def sl@0: sl@0: test if-9.1 {if cmd with namespace qualifiers} { sl@0: ::if {1} {set x 4} sl@0: } 4 sl@0: sl@0: # Test for incorrect "double evaluation semantics" sl@0: sl@0: test if-10.1 {delayed substitution of then body} { sl@0: set j 0 sl@0: set if if sl@0: # this is not compiled sl@0: $if {[incr j] == 1} " sl@0: set result $j sl@0: " sl@0: # this will be compiled sl@0: proc p {} { sl@0: set j 0 sl@0: if {[incr j]} " sl@0: set result $j sl@0: " sl@0: set result sl@0: } sl@0: append result [p] sl@0: } {00} sl@0: test if-10.2 {delayed substitution of elseif expression} { sl@0: set j 0 sl@0: set if if sl@0: # this is not compiled sl@0: $if {[incr j] == 0} { sl@0: set result badthen sl@0: } elseif "$j == 1" { sl@0: set result badelseif sl@0: } else { sl@0: set result 0 sl@0: } sl@0: # this will be compiled sl@0: proc p {} { sl@0: set j 0 sl@0: if {[incr j] == 0} { sl@0: set result badthen sl@0: } elseif "$j == 1" { sl@0: set result badelseif sl@0: } else { sl@0: set result 0 sl@0: } sl@0: set result sl@0: } sl@0: append result [p] sl@0: } {00} sl@0: test if-10.3 {delayed substitution of elseif body} { sl@0: set j 0 sl@0: set if if sl@0: # this is not compiled sl@0: $if {[incr j] == 0} { sl@0: set result badthen sl@0: } elseif {1} " sl@0: set result $j sl@0: " sl@0: # this will be compiled sl@0: proc p {} { sl@0: set j 0 sl@0: if {[incr j] == 0} { sl@0: set result badthen sl@0: } elseif {1} " sl@0: set result $j sl@0: " sl@0: } sl@0: append result [p] sl@0: } {00} sl@0: test if-10.4 {delayed substitution of else body} { sl@0: set j 0 sl@0: if {[incr j] == 0} { sl@0: set result badthen sl@0: } else " sl@0: set result $j sl@0: " sl@0: set result sl@0: } {0} sl@0: test if-10.5 {substituted control words} { sl@0: set then then; proc then {} {return badthen} sl@0: set else else; proc else {} {return badelse} sl@0: set elseif elseif; proc elseif {} {return badelseif} sl@0: list [catch {if 1 $then {if 0 {} $elseif 1 {if 0 {} $else {list ok}}}} a] $a sl@0: } {0 ok} sl@0: test if-10.6 {double invocation of variable traces} { sl@0: set iftracecounter 0 sl@0: proc iftraceproc {args} { sl@0: upvar #0 iftracecounter counter sl@0: set argc [llength $args] sl@0: set extraargs [lrange $args 0 [expr {$argc - 4}]] sl@0: set name [lindex $args [expr {$argc - 3}]] sl@0: upvar 1 $name var sl@0: if {[incr counter] % 2 == 1} { sl@0: set var "$counter oops [concat $extraargs]" sl@0: } else { sl@0: set var "$counter + [concat $extraargs]" sl@0: } sl@0: } sl@0: trace variable iftracevar r [list iftraceproc 10] sl@0: list [catch {if "$iftracevar + 20" {}} a] $a \ sl@0: [catch {if "$iftracevar + 20" {}} b] $b \ sl@0: [unset iftracevar iftracecounter] sl@0: } {1 {syntax error in expression "1 oops 10 + 20": extra tokens at end of expression} 0 {} {}} sl@0: sl@0: # cleanup sl@0: ::tcltest::cleanupTests sl@0: return