26754: tweak zgetdir() and test for realpath()
[zsh.git] / Test / A01grammar.ztst
bloba1ec2cc00c5261579d35e8800cef9b1fccbe2a09
2 # This file contains tests corresponding to the `Shell Grammar' texinfo node.
5 %prep
7   mkdir basic.tmp && cd basic.tmp
9   touch foo bar
10   echo "'" >unmatched_quote.txt
12 %test
14 # Tests for `Simple Commands and Pipelines'
16   echo foo | cat | sed 's/foo/bar/'
17 0:Basic pipeline handling
18 >bar
20   false | true
21 0:Exit status of pipeline with builtins (true)
23   true | false
24 1:Exit status of pipeline with builtins (false)
26   fn() { local foo; read foo; print $foo; }
27   coproc fn
28   print -p coproc test output
29   read -p bar
30   print $bar
31 0:Basic coprocess handling
32 >coproc test output
34   true | false && print true || print false
35 0:Basic sublist (i)
36 >false
38   false | true && print true || print false
39 0:Basic sublist (ii)
40 >true
42   (cd /NonExistentDirectory >&/dev/null) || print false
43 0:Basic subshell list with error
44 >false
46   { cd /NonExistentDirectory >&/dev/null } || print false
47 0:Basic current shell list with error
48 >false
51 # Tests for `Precommand Modifiers'
53   - $ZTST_testdir/../Src/zsh -fc "[[ \$0 = \"-$ZTST_testdir/../Src/zsh\" ]]"
54 0:`-' precommand modifier
56   echo f*
57   noglob echo f*
58 0:`noglob' precommand modifier
59 >foo
60 >f*
62   (exec /bin/sh; echo bar)
63 0:`exec' precommand modifier
65   (exec -l /bin/sh -c 'echo $0')
66 0:`exec' with -l option
67 >-/bin/sh
69   (exec -a /bin/SPLATTER /bin/sh -c 'echo $0')
70 0:`exec' with -a option
71 >/bin/SPLATTER
73   (exec -a/bin/SPLOOSH /bin/sh -c 'echo $0')
74 0:`exec' with -a option, no space
75 >/bin/SPLOOSH
77   (export FOO=bar; exec -c /bin/sh -c 'echo x${FOO}x')
78 0:`exec' with -c option
79 >xx
81   cat() { echo Function cat executed; }
82   command cat && unfunction cat
83 0:`command' precommand modifier
84 <External command cat executed
85 >External command cat executed
87   cd() { echo Not cd at all; }
88   builtin cd . && unfunction cd
89 0:`builtin' precommand modifier
92 # Tests for `Complex Commands'
95   if true; then
96     print true-1
97   elif true; then
98     print true-2
99   else
100     print false
101   fi
102 0:`if ...' (i)
103 >true-1
105   if false; then
106     print true-1
107   elif true; then
108     print true-2
109   else
110     print false
111   fi
112 0:`if ...' (ii)
113 >true-2
115   if false; then
116     print true-1
117   elif false; then
118     print true-2
119   else
120     print false
121   fi
122 0:`if ...' (iii)
123 >false
125   if true;
126     :
127   fi
128 1d:`if ...' (iv)
129 ?(eval):3: parse error near `fi'
131   for name in word to term; do
132     print $name
133   done
134 0:`for' loop
135 >word
137 >term
139   for name
140   in word to term; do
141     print $name
142   done
143 0:`for' loop with newline before in keyword
144 >word
146 >term
148   for (( name = 0; name < 3; name++ )); do
149     print $name
150   done
151 0:arithmetic `for' loop
156   for keyvar valvar in key1 val1 key2 val2; do
157      print key=$keyvar val=$valvar
158   done
159 0:enhanced `for' syntax with two loop variables
160 >key=key1 val=val1
161 >key=key2 val=val2
163   for keyvar valvar stuffvar in keyA valA stuffA keyB valB stuffB; do
164      print key=$keyvar val=$valvar stuff=$stuffvar
165   done
166 0:enhanced `for' syntax with three loop variables
167 >key=keyA val=valA stuff=stuffA
168 >key=keyB val=valB stuff=stuffB
170   for in in in in in stop; do
171     print in=$in
172   done
173 0:compatibility of enhanced `for' syntax with standard syntax
174 >in=in
175 >in=in
176 >in=in
177 >in=stop
179   name=0
180   while (( name < 3 )); do
181     print $name
182     (( name++ ))
183   done
184 0:`while' loop
189   name=0
190   until (( name == 3 )); do
191     print $name
192     (( name++ ))
193   done
194 0:`until' loop
199   repeat 3 do
200     echo over and over
201   done
202 0:`repeat' loop
203 >over and over
204 >over and over
205 >over and over
207   word=Trinity
208   case $word in
209     Michaelmas) print 0
210                 ;;
211     Hilary) print 1
212             ;;
213     Trinity) print 2
214              ;;
215     *) print 3
216        ;;
217   esac
218 0:`case', old syntax
221   word=Trinity
222   case $word in
223     (Michaelmas) print 0
224                 ;;
225     (Hilary) print 1
226             ;;
227     (Trinity) print 2
228              ;;
229     (*) print 3
230        ;;
231   esac
232 0:`case', new syntax
235   word=Hilary
236   case $word in
237     (Michaelmas) print 0
238                 ;;
239     (Hilary) print 1
240             ;&
241     (Trinity) print 2
242              ;&
243     (*) print 3
244        ;;
245   esac
246 0:`case', new syntax, cascaded
251 ## Select now reads from stdin if the shell is not interactive.
252 ## Its own output goes to stderr.
253   (COLUMNS=80
254   PS3="input> "
255   select name in one two three; do
256     print $name
257   done)
258 0:`select' loop
260 ?1) one     2) two     3) three   
261 ?input> input> 
262 >two
264   function name1 name2 () { print This is $0; }
265   name2
266   name1 name2() { print This is still $0; }
267   name2
268 0:`function' keyword
269 >This is name2
270 >This is still name2
272   (time cat) >&/dev/null
273 0:`time' keyword (status only)
275   if [[ -f foo && -d . && -n $ZTST_testdir ]]; then
276     true
277   else
278     false
279   fi
280 0:basic [[ ... ]] test
283 # Current shell execution with try/always form.
284 # We put those with errors in subshells so that any unhandled error doesn't
285 # propagate.
288   {
289      print The try block.
290   } always {
291      print The always block.
292   }
293   print After the always block.
294 0:Basic `always' syntax
295 >The try block.
296 >The always block.
297 >After the always block.
299   ({
300     print Position one.
301     print ${*this is an error*}
302     print Position two.
303   } always {
304     if (( TRY_BLOCK_ERROR )); then
305       print An error occurred.
306     else
307       print No error occurred.
308     fi
309   }
310   print Position three)
311 1:Always block with error not reset
312 >Position one.
313 >An error occurred.
314 ?(eval):3: bad substitution
316   ({
317     print Stelle eins.
318     print ${*voici une erreur}
319     print Posizione due.
320   } always {
321     if (( TRY_BLOCK_ERROR )); then
322       print Erratum factum est. Retro ponetur.
323       (( TRY_BLOCK_ERROR = 0 ))
324     else
325       print unray touay foay anguageslay
326     fi
327   }
328   print Status after always block is $?.)
329 0:Always block with error reset
330 >Stelle eins.
331 >Erratum factum est. Retro ponetur.
332 >Status after always block is 1.
333 ?(eval):3: bad substitution
335   fn() { { return } always { echo always 1 }; echo not executed }
336   fn
337   fn() { { echo try 2 } always { return }; echo not executed }
338   fn
339 0:Always block interaction with return
340 >always 1
341 >try 2
343 # Outputting of structures from the wordcode is distinctly non-trivial,
344 # we probably ought to have more like the following...
345   fn1() { { echo foo; } }
346   fn2() { { echo foo; } always { echo bar; } }
347   fn3() { ( echo foo; ) }
348   functions fn1 fn2 fn3
349 0:Output of syntactic structures with and without always blocks
350 >fn1 () {
351 >       {
352 >               echo foo
353 >       }
355 >fn2 () {
356 >       {
357 >               echo foo
358 >       } always {
359 >               echo bar
360 >       }
362 >fn3 () {
363 >       (
364 >               echo foo
365 >       )
370 # Tests for `Alternate Forms For Complex Commands'
373   if (true) { print true-1 } elif (true) { print true-2 } else { print false }
374   if (false) { print true-1 } elif (true) { print true-2 } else { print false }
375   if (false) { print true-1 } elif (false) { print true-2 } else { print false }
376 0:Alternate `if' with braces
377 >true-1
378 >true-2
379 >false
381   if true; print true
382 0:Short form of `if'
383 >true
385   for name ( word1 word2 word3 ) print $name
386 0:Form of `for' with parentheses.
387 >word1
388 >word2
389 >word3
391   for name in alpha beta gamma; print $name
392 0:Short form of `for'
393 >alpha
394 >beta
395 >gamma
397   for (( val = 2; val < 10; val *= val )) print $val
398 0:Short arithmetic `for'
402   foreach name ( verbiage words periphrasis )
403     print $name
404   end
405 0:Csh-like `for'
406 >verbiage
407 >words
408 >periphrasis
410 # see comment with braces used in if loops
411   val=0;
412   while (( val < 2 )) { print $((val++)); }
413 0:Alternative `while'
417   val=2;
418   until (( val == 0 )) { print $((val--)); }
419 0:Alternative `until'
423   repeat 3 print Hip hip hooray
424 0:Short `repeat'
425 >Hip hip hooray
426 >Hip hip hooray
427 >Hip hip hooray
429   case bravo {
430     (alpha) print schmalpha
431             ;;
432     (bravo) print schmavo
433             ;;
434     (charlie) print schmarlie
435             ;;
436   }
437 0:`case' with braces
438 >schmavo
440   for word in artichoke bladderwort chrysanthemum Zanzibar
441   case $word in
442     (*der*) print $word contains the forbidden incantation der
443          ;;
444     (a*) print $word begins with a
445          ;&
446     ([[:upper:]]*) print $word either begins with a or an upper case letter
447          ;|
448     ([[:lower:]]*) print $word begins with a lower case letter
449          ;|
450     (*e*) print $word contains an e
451          ;;
452   esac
453 0:`case' with mixed ;& and ;|
454 >artichoke begins with a
455 >artichoke either begins with a or an upper case letter
456 >artichoke begins with a lower case letter
457 >artichoke contains an e
458 >bladderwort contains the forbidden incantation der
459 >chrysanthemum begins with a lower case letter
460 >chrysanthemum contains an e
461 >Zanzibar either begins with a or an upper case letter
463   print -u $ZTST_fd 'This test hangs the shell when it fails...'
464   name=0
465 # The number 4375 here is chosen to produce more than 16384 bytes of output
466   while (( name < 4375 )); do
467     print -n $name
468     (( name++ ))
469   done < /dev/null | { read name; print done }
470 0:Bug regression: `while' loop with redirection and pipeline
471 >done
473 # This used to be buggy and print X at the end of each iteration.
474   for f in 1 2 3 4; do
475     print $f || break
476   done && print X
477 0:Handling of ||'s and &&'s with a for loop in between
484 # Same bug for &&, used to print `no' at the end of each iteration
485   for f in 1 2 3 4; do
486     false && print strange
487   done || print no
488 0:Handling of &&'s and ||'s with a for loop in between
491   $ZTST_testdir/../Src/zsh -f unmatched_quote.txt
492 1:Parse error with file causes non-zero exit status
493 ?unmatched_quote.txt:2: unmatched '
495   $ZTST_testdir/../Src/zsh -f <unmatched_quote.txt
496 1:Parse error on standard input causes non-zero exit status
497 ?zsh: unmatched '
499   $ZTST_testdir/../Src/zsh -f -c "'"
500 1:Parse error on inline command causes non-zero exit status
501 ?zsh:1: unmatched '
503   $ZTST_testdir/../Src/zsh -f NonExistentScript
504 127q:Non-existent script causes exit status 127
505 ?$ZTST_testdir/../Src/zsh: can't open input file: NonExistentScript
507   (setopt nonomatch
508   # use this to get stuff at start of line
509   contents=$'# comment \'\necho value #with " stuff\n# comment\n#comment
510   echo not#comment\n'
511   eval 'VAR=$('"$contents"')'
512   print -l $VAR)
513 0:comments within $(...)
514 >value
515 >not#comment
517