OILS / spec / loop.test.sh View on Github | oilshell.org

473 lines, 291 significant
1
2#### implicit for loop
3# This is like "for i in $@".
4fun() {
5 for i; do
6 echo $i
7 done
8}
9fun 1 2 3
10## STDOUT:
111
122
133
14## END
15
16#### empty for loop (has "in")
17set -- 1 2 3
18for i in ; do
19 echo $i
20done
21## stdout-json: ""
22
23#### for loop with invalid identifier
24# should be compile time error, but runtime error is OK too
25for - in a b c; do
26 echo hi
27done
28## stdout-json: ""
29## status: 2
30## OK bash/mksh status: 1
31## BUG zsh stdout: hi
32## BUG zsh status: 1
33
34#### the word 'in' can be the loop variable
35
36for in in a b c; do
37 echo $in
38done
39## STDOUT:
40a
41b
42c
43## END
44
45#### Tilde expansion within for loop
46HOME=/home/bob
47for name in ~/src ~/git; do
48 echo $name
49done
50## STDOUT:
51/home/bob/src
52/home/bob/git
53## END
54
55#### Brace Expansion within Array
56for i in -{a,b} {c,d}-; do
57 echo $i
58 done
59## STDOUT:
60-a
61-b
62c-
63d-
64## END
65## N-I dash STDOUT:
66-{a,b}
67{c,d}-
68## END
69
70#### using loop var outside loop
71fun() {
72 for i in a b c; do
73 echo $i
74 done
75 echo $i
76}
77fun
78## status: 0
79## STDOUT:
80a
81b
82c
83c
84## END
85
86#### continue
87for i in a b c; do
88 echo $i
89 if test $i = b; then
90 continue
91 fi
92 echo $i
93done
94## status: 0
95## STDOUT:
96a
97a
98b
99c
100c
101## END
102
103#### break
104for i in a b c; do
105 echo $i
106 if test $i = b; then
107 break
108 fi
109done
110## status: 0
111## STDOUT:
112a
113b
114## END
115
116#### dynamic control flow (KNOWN INCOMPATIBILITY)
117# hm would it be saner to make FATAL builtins called break/continue/etc.?
118# On the other hand, this spits out errors loudly.
119b=break
120for i in 1 2 3; do
121 echo $i
122 $b
123done
124## STDOUT:
1251
126## END
127## OK osh STDOUT:
1281
1292
1303
131## END
132## OK osh status: 127
133
134#### while in while condition
135# This is a consequence of the grammar
136while while true; do echo cond; break; done
137do
138 echo body
139 break
140done
141## STDOUT:
142cond
143body
144## END
145
146#### while in pipe
147x=$(find spec/ | wc -l)
148y=$(find spec/ | while read path; do
149 echo $path
150done | wc -l
151)
152test $x -eq $y
153echo status=$?
154## stdout: status=0
155
156#### while in pipe with subshell
157i=0
158seq 3 | ( while read foo; do
159 i=$((i+1))
160 #echo $i
161done
162echo $i )
163## stdout: 3
164
165#### until loop
166# This is just the opposite of while? while ! cond?
167until false; do
168 echo hi
169 break
170done
171## stdout: hi
172
173#### continue at top level
174if true; then
175 echo one
176 continue
177 echo two
178fi
179## status: 0
180## STDOUT:
181one
182two
183## END
184# zsh behaves like strict_control_flow!
185## OK zsh status: 1
186## OK zsh STDOUT:
187one
188## END
189
190#### continue in subshell
191for i in $(seq 2); do
192 echo "> $i"
193 ( if true; then continue; fi; echo "Should not print" )
194 echo subshell status=$?
195 echo ". $i"
196done
197## STDOUT:
198# osh lets you fail
199> 1
200subshell status=1
201. 1
202> 2
203subshell status=1
204. 2
205## END
206## OK dash/bash/zsh STDOUT:
207> 1
208subshell status=0
209. 1
210> 2
211subshell status=0
212. 2
213## END
214## BUG mksh STDOUT:
215> 1
216Should not print
217subshell status=0
218. 1
219> 2
220Should not print
221subshell status=0
222. 2
223## END
224
225#### continue in subshell aborts with errexit
226# The other shells don't let you recover from this programming error!
227set -o errexit
228for i in $(seq 2); do
229 echo "> $i"
230 ( if true; then continue; fi; echo "Should not print" )
231 echo 'should fail after subshell'
232 echo ". $i"
233done
234## STDOUT:
235> 1
236## END
237## status: 1
238## BUG dash/bash/zsh STDOUT:
239> 1
240should fail after subshell
241. 1
242> 2
243should fail after subshell
244. 2
245## END
246## BUG dash/bash/zsh status: 0
247## BUG mksh STDOUT:
248> 1
249Should not print
250should fail after subshell
251. 1
252> 2
253Should not print
254should fail after subshell
255. 2
256## END
257## BUG mksh status: 0
258
259#### bad arg to break
260x=oops
261while true; do
262 echo hi
263 break $x
264 sleep 0.1
265done
266## stdout: hi
267## status: 1
268## OK dash status: 2
269## OK bash status: 128
270
271#### too many args to continue
272# OSH treats this as a parse error
273for x in a b c; do
274 echo $x
275 # bash breaks rather than continue or fatal error!!!
276 continue 1 2 3
277done
278echo --
279## stdout-json: ""
280## status: 2
281## BUG bash STDOUT:
282a
283--
284## END
285## OK bash status: 0
286## BUG dash/mksh/zsh STDOUT:
287a
288b
289c
290--
291## END
292## BUG dash/mksh/zsh status: 0
293
294#### break in condition of loop
295while break; do
296 echo x
297done
298echo done
299## STDOUT:
300done
301## END
302
303
304#### break in condition of nested loop
305for i in 1 2 3; do
306 echo i=$i
307 while break; do
308 echo x
309 done
310done
311echo done
312## STDOUT:
313i=1
314i=2
315i=3
316done
317## END
318
319#### return within eval
320f() {
321 echo one
322 eval 'return'
323 echo two
324}
325f
326## STDOUT:
327one
328## END
329
330#### break/continue within eval
331# NOTE: This changes things
332# set -e
333f() {
334 for i in $(seq 5); do
335 if test $i = 2; then
336 eval continue
337 fi
338 if test $i = 4; then
339 eval break
340 fi
341 echo $i
342 done
343
344 eval 'return'
345 echo 'done'
346}
347f
348## STDOUT:
3491
3503
351## END
352## BUG mksh STDOUT:
3531
3542
3553
3564
3575
358## END
359
360#### break/continue within source
361# NOTE: This changes things
362# set -e
363
364cd $REPO_ROOT
365f() {
366 for i in $(seq 5); do
367 if test $i = 2; then
368 . spec/testdata/continue.sh
369 fi
370 if test $i = 4; then
371 . spec/testdata/break.sh
372 fi
373 echo $i
374 done
375
376 # Return is different!
377 . spec/testdata/return.sh
378 echo done
379}
380f
381## STDOUT:
3821
3833
384done
385## END
386## BUG zsh/mksh STDOUT:
3871
3882
3893
3904
3915
392done
393## END
394
395#### top-level break/continue/return (without strict_control_flow)
396$SH -c 'break; echo break=$?'
397$SH -c 'continue; echo continue=$?'
398$SH -c 'return; echo return=$?'
399## STDOUT:
400break=0
401continue=0
402## END
403## BUG zsh stdout-json: ""
404## BUG bash STDOUT:
405break=0
406continue=0
407return=1
408## END
409
410
411#### multi-level break with argument
412
413# reported in issue #1459
414
415counterA=100
416counterB=100
417
418while test "$counterA" -gt 0
419do
420 counterA=$((counterA - 1))
421 while test "$counterB" -gt 0
422 do
423 counterB=$((counterB - 1))
424 if test "$counterB" = 50
425 then
426 break 2
427 fi
428 done
429done
430
431echo "$counterA"
432echo "$counterB"
433
434## STDOUT:
43599
43650
437## END
438
439
440#### multi-level continue
441
442for i in 1 2; do
443 for j in a b c; do
444 if test $j = b; then
445 continue
446 fi
447 echo $i $j
448 done
449done
450
451echo ---
452
453for i in 1 2; do
454 for j in a b c; do
455 if test $j = b; then
456 continue 2 # MULTI-LEVEL
457 fi
458 echo $i $j
459 done
460done
461
462
463## STDOUT:
4641 a
4651 c
4662 a
4672 c
468---
4691 a
4702 a
471## END
472
473