From e43b2acd67a7b06d4653ff910af1b4b51aedcdfe Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 1 Apr 2005 10:30:08 +0000 Subject: 21078: parse errors didn't cause non-zero exit status --- Test/A01grammar.ztst | 450 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 Test/A01grammar.ztst (limited to 'Test') diff --git a/Test/A01grammar.ztst b/Test/A01grammar.ztst new file mode 100644 index 000000000..81a963b05 --- /dev/null +++ b/Test/A01grammar.ztst @@ -0,0 +1,450 @@ +# +# 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 + + 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