# # This file contains tests corresponding to the `Shell Grammar' texinfo node. # %prep mkdir basic.tmp && cd basic.tmp touch foo bar echo "'" >unmatched_quote.txt %test # # Tests for `Simple Commands and Pipelines' # echo foo | cat | sed 's/foo/bar/' 0:Basic pipeline handling >bar false | true 0:Exit status of pipeline with builtins (true) true | false 1:Exit status of pipeline with builtins (false) fn() { local foo; read foo; print $foo; } coproc fn print -p coproc test output read -p bar print $bar 0:Basic coprocess handling >coproc test output true | false && print true || print false 0:Basic sublist (i) >false false | true && print true || print false 0:Basic sublist (ii) >true (cd /NonExistentDirectory >&/dev/null) || print false 0:Basic subshell list with error >false { cd /NonExistentDirectory >&/dev/null } || print false 0:Basic current shell list with error >false # # Tests for `Precommand Modifiers' # - $ZTST_testdir/../Src/zsh -fc "[[ \$0 = \"-$ZTST_testdir/../Src/zsh\" ]]" 0:`-' precommand modifier echo f* noglob echo f* 0:`noglob' precommand modifier >foo >f* (exec /bin/sh; echo bar) 0:`exec' precommand modifier cat() { echo Function cat executed; } command cat && unfunction cat 0:`command' precommand modifier External command cat executed cd() { echo Not cd at all; } builtin cd . && unfunction cd 0:`builtin' precommand modifier # # Tests for `Complex Commands' # if true; then print true-1 elif true; then print true-2 else print false fi 0:`if ...' (i) >true-1 if false; then print true-1 elif true; then print true-2 else print false fi 0:`if ...' (ii) >true-2 if false; then print true-1 elif false; then print true-2 else print false fi 0:`if ...' (iii) >false if true; : fi 1d:`if ...' (iv) ?(eval):3: parse error near `fi' for name in word to term; do print $name done 0:`for' loop >word >to >term for name in word to term; do print $name done 0:`for' loop with newline before in keyword >word >to >term for (( name = 0; name < 3; name++ )); do print $name done 0:arithmetic `for' loop >0 >1 >2 for keyvar valvar in key1 val1 key2 val2; do print key=$keyvar val=$valvar done 0:enhanced `for' syntax with two loop variables >key=key1 val=val1 >key=key2 val=val2 for keyvar valvar stuffvar in keyA valA stuffA keyB valB stuffB; do print key=$keyvar val=$valvar stuff=$stuffvar done 0:enhanced `for' syntax with three loop variables >key=keyA val=valA stuff=stuffA >key=keyB val=valB stuff=stuffB for in in in in in stop; do print in=$in done 0:compatibility of enhanced `for' syntax with standard syntax >in=in >in=in >in=in >in=stop name=0 while (( name < 3 )); do print $name (( name++ )) done 0:`while' loop >0 >1 >2 name=0 until (( name == 3 )); do print $name (( name++ )) done 0:`until' loop >0 >1 >2 repeat 3 do echo over and over done 0:`repeat' loop >over and over >over and over >over and over word=Trinity case $word in Michaelmas) print 0 ;; Hilary) print 1 ;; Trinity) print 2 ;; *) print 3 ;; esac 0:`case', old syntax >2 word=Trinity case $word in (Michaelmas) print 0 ;; (Hilary) print 1 ;; (Trinity) print 2 ;; (*) print 3 ;; esac 0:`case', new syntax >2 word=Hilary case $word in (Michaelmas) print 0 ;; (Hilary) print 1 ;& (Trinity) print 2 ;& (*) print 3 ;; esac 0:`case', new syntax, cascaded >1 >2 >3 ## Select now reads from stdin if the shell is not interactive. ## Its own output goes to stderr. (COLUMNS=80 PS3="input> " select name in one two three; do print $name done) 0:`select' loop <2 ?1) one 2) two 3) three ?input> input> >two function name1 name2 () { print This is $0; } name2 name1 name2() { print This is still $0; } name2 0:`function' keyword >This is name2 >This is still name2 (time cat) >&/dev/null 0:`time' keyword (status only) if [[ -f foo && -d . && -n $ZTST_testdir ]]; then true else false fi 0:basic [[ ... ]] test # # Current shell execution with try/always form. # We put those with errors in subshells so that any unhandled error doesn't # propagate. # { print The try block. } always { print The always block. } print After the always block. 0:Basic `always' syntax >The try block. >The always block. >After the always block. ({ print Position one. print ${*this is an error*} print Position two. } always { if (( TRY_BLOCK_ERROR )); then print An error occurred. else print No error occurred. fi } print Position three) 1:Always block with error not reset >Position one. >An error occurred. ?(eval):3: bad substitution ({ print Stelle eins. print ${*voici une erreur} print Posizione due. } always { if (( TRY_BLOCK_ERROR )); then print Erratum factum est. Retro ponetur. (( TRY_BLOCK_ERROR = 0 )) else print unray touay foay anguageslay fi } print Status after always block is $?.) 0:Always block with error reset >Stelle eins. >Erratum factum est. Retro ponetur. >Status after always block is 1. ?(eval):3: bad substitution # Outputting of structures from the wordcode is distinctly non-trivial, # we probably ought to have more like the following... fn1() { { echo foo; } } fn2() { { echo foo; } always { echo bar; } } fn3() { ( echo foo; ) } functions fn1 fn2 fn3 0:Output of syntactic structures with and without always blocks >fn1 () { > { > echo foo > } >} >fn2 () { > { > echo foo > } always { > echo bar > } >} >fn3 () { > ( > echo foo > ) >} # # Tests for `Alternate Forms For Complex Commands' # if (true) { print true-1 } elif (true) { print true-2 } else { print false } if (false) { print true-1 } elif (true) { print true-2 } else { print false } if (false) { print true-1 } elif (false) { print true-2 } else { print false } 0:Alternate `if' with braces >true-1 >true-2 >false if true; print true 0:Short form of `if' >true for name ( word1 word2 word3 ) print $name 0:Form of `for' with parentheses. >word1 >word2 >word3 for name in alpha beta gamma; print $name 0:Short form of `for' >alpha >beta >gamma for (( val = 2; val < 10; val *= val )) print $val 0:Short arithmetic `for' >2 >4 foreach name ( verbiage words periphrasis ) print $name end 0:Csh-like `for' >verbiage >words >periphrasis # see comment with braces used in if loops val=0; while (( val < 2 )) { print $((val++)); } 0:Alternative `while' >0 >1 val=2; until (( val == 0 )) { print $((val--)); } 0:Alternative `until' >2 >1 repeat 3 print Hip hip hooray 0:Short `repeat' >Hip hip hooray >Hip hip hooray >Hip hip hooray case bravo { (alpha) print schmalpha ;; (bravo) print schmavo ;; (charlie) print schmarlie ;; } 0:`case' with braces >schmavo for word in artichoke bladderwort chrysanthemum Zanzibar case $word in (*der*) print $word contains the forbidden incantation der ;; (a*) print $word begins with a ;& ([[:upper:]]*) print $word either begins with a or an upper case letter ;| ([[:lower:]]*) print $word begins with a lower case letter ;| (*e*) print $word contains an e ;; esac 0:`case' with mixed ;& and ;| >artichoke begins with a >artichoke either begins with a or an upper case letter >artichoke begins with a lower case letter >artichoke contains an e >bladderwort contains the forbidden incantation der >chrysanthemum begins with a lower case letter >chrysanthemum contains an e >Zanzibar either begins with a or an upper case letter print 'This test hangs the shell when it fails...' >&8 name=0 # The number 4375 here is chosen to produce more than 16384 bytes of output while (( name < 4375 )); do print -n $name (( name++ )) done < /dev/null | { read name; print done } 0:Bug regression: `while' loop with redirection and pipeline >done # This used to be buggy and print X at the end of each iteration. for f in 1 2 3 4; do print $f || break done && print X 0:Handling of ||'s and &&'s with a for loop in between >1 >2 >3 >4 >X # Same bug for &&, used to print `no' at the end of each iteration for f in 1 2 3 4; do false && print strange done || print no 0:Handling of &&'s and ||'s with a for loop in between >no $ZTST_testdir/../Src/zsh -f unmatched_quote.txt 1:Parse error with file causes non-zero exit status ?unmatched_quote.txt:2: unmatched ' $ZTST_testdir/../Src/zsh -f