1 #### cd with block
2 shopt -s oil:all
3
4 const saved = "$PWD"
5
6 # OLDPWD is NOT defined
7 cd / { echo $PWD; echo OLDPWD=${OLDPWD:-} }; echo done
8
9 if ! test "$saved" = $PWD; then
10 echo FAIL
11 fi
12
13 cd /tmp {
14 write PWD=$PWD
15 write --sep ' ' pwd builtin: $(pwd)
16 }
17
18 if ! test "$saved" = $PWD; then
19 echo FAIL
20 fi
21
22 ## STDOUT:
23 /
24 OLDPWD=
25 done
26 PWD=/tmp
27 pwd builtin: /tmp
28 ## END
29
30 #### cd with block: fatal error in block
31 shopt -s oil:all
32 cd / {
33 echo one
34 false
35 echo two
36 }
37 ## status: 1
38 ## STDOUT:
39 one
40 ## END
41
42
43 #### cd with block: return in block
44 shopt -s oil:all
45 f() {
46 cd / {
47 echo one
48 return
49 echo two
50 }
51 echo 'end func'
52 }
53 f
54 ## STDOUT:
55 one
56 end func
57 ## END
58
59 #### cd with block: break in block
60 shopt -s oil:all
61 f() {
62 cd / {
63 echo one
64 for i in 1 2; do
65 echo $i
66 break # break out of loop
67 done
68
69 break # break out of block isn't valid
70 echo two
71 }
72 echo end func
73 }
74 f
75 ## status: 1
76 ## STDOUT:
77 one
78 1
79 ## END
80
81 #### cd with block exits with status 0
82 shopt -s oil:all
83 cd / {
84 echo block
85
86 # This return value is ignored.
87 # Or maybe this should be a runtime error?
88 return 1
89 }
90 echo status=$?
91 ## STDOUT:
92 block
93 status=0
94 ## END
95
96 #### block doesn't have its own scope
97 shopt -s oil:all
98 var x = 1
99 echo "x=$x"
100 cd / {
101 #set y = 5 # This would be an error because set doesn't do dynamic lookup
102 var x = 42
103 echo "x=$x"
104 }
105 echo "x=$x"
106 ## STDOUT:
107 x=1
108 x=42
109 x=42
110 ## END
111
112 #### block literal in expression mode: ^(echo $PWD)
113 shopt -s oil:all
114
115 const myblock = ^(echo $PWD | wc -l)
116 eval (myblock)
117
118 const b2 = ^(echo one; echo two)
119 eval (b2)
120
121 ## STDOUT:
122 1
123 one
124 two
125 ## END
126
127 #### block arg as typed expression
128
129 shopt -s oil:all
130
131 # literal
132 cd /tmp (^(echo $PWD))
133
134 const myblock = ^(echo $PWD)
135 cd /tmp (myblock)
136
137 ## STDOUT:
138 /tmp
139 /tmp
140 ## END
141
142 #### Pass invalid typed args
143
144 cd /tmp (42) # should be a block
145 ## status: 3
146
147 #### Pass too many typed args
148
149 cd /tmp (1, 2)
150 ## status: 3
151
152 #### 'builtin' and 'command' with block
153 shopt --set oil:upgrade
154 builtin cd / {
155 echo "builtin $PWD"
156 }
157 command cd / {
158 echo "command $PWD"
159 }
160 ## STDOUT:
161 builtin /
162 command /
163 ## END
164
165
166 #### Consistency: Control Flow and Blocks
167 shopt --set parse_brace
168
169 # "Invalid control flow at top level"
170 eval '
171 cd / {
172 echo cd
173 break
174 }
175 '
176 echo cd no loop $?
177
178 # warning: "Unexpected control flow in block" (strict_control_flow)
179 eval '
180 while true {
181 cd / {
182 echo cd
183 break
184 }
185 }
186 '
187 echo cd loop $?
188
189 eval '
190 while true {
191 shopt --unset errexit {
192 echo shopt
193 continue
194 }
195 }
196 '
197 echo shopt continue $?
198
199 eval '
200 while true {
201 shvar FOO=foo {
202 echo shvar
203 continue
204 }
205 }
206 '
207 echo shvar continue $?
208
209
210 eval '
211 while true {
212 try {
213 echo try
214 break
215 }
216 }
217 '
218 echo try break $?
219
220 ## STDOUT:
221 cd
222 cd no loop 0
223 cd
224 cd loop 1
225 shopt
226 shopt continue 1
227 shvar
228 shvar continue 1
229 try
230 try break 1
231 ## END
232
233 #### Consistency: Exit Status and Blocks
234 shopt --set parse_brace
235
236 cd / {
237 false
238 }
239 echo cd=$?
240
241 shopt --unset errexit {
242 false
243 }
244 echo shopt=$?
245
246 shvar FOO=foo {
247 echo " FOO=$FOO"
248 false
249 }
250 echo shvar=$?
251
252 try {
253 false
254 }
255 echo try=$?
256
257 ## STDOUT:
258 cd=0
259 shopt=0
260 FOO=foo
261 shvar=0
262 try=0
263 ## END
264
265 #### Consistency: Unwanted Blocks Are Errors
266 shopt --set parse_brace
267
268 true { echo BAD }
269 echo true $?
270
271 false ( 42, 43 )
272 echo false $?
273
274 echo { echo BAD }
275 echo echo block $?
276
277 echo ( 42, 43 )
278 echo echo args $?
279
280 command echo 'command block' { echo BAD }
281 echo command echo $?
282
283 builtin echo 'builtin block' { echo BAD }
284 echo builtin echo $?
285
286 pushd $TMP { echo BAD }
287 echo pushd $?
288
289 ## STDOUT:
290 true 2
291 false 2
292 echo block 2
293 echo args 2
294 command echo 2
295 builtin echo 2
296 pushd 2
297 ## END
298
299 #### Block with Bare Assignments
300
301 # oil:all has parse_equals
302 # is there any way to turn on parse_equals only in config blocks?
303 # but we don't know what's a block ahead of time
304 # I think we would have to check at runtime. Look at VarChecker
305
306 shopt --set oil:all
307
308 proc Rule(s ; ; ; b) {
309 echo "rule $s"
310 }
311
312 proc myrules(name) {
313 Rule $name-python {
314 kind = 'python'
315 }
316
317 Rule $name-cc {
318 kind = 'cc' # should NOT conflict
319 }
320 }
321
322 myrules foo
323 myrules bar
324
325 ## STDOUT:
326 rule foo-python
327 rule foo-cc
328 rule bar-python
329 rule bar-cc
330 ## END
331
332 #### Proc that doesn't take a block
333 shopt --set parse_brace parse_proc parse_paren
334
335 proc task(name ; ; ; b = null) {
336 echo "task name=$name"
337 if (b) {
338 eval (b)
339 return 33
340 } else {
341 echo 'no block'
342 return 44
343 }
344 }
345
346 task spam
347 echo status=$?
348
349 echo
350
351 task foo {
352 echo 'running'
353 echo 'block'
354 }
355 echo status=$?
356
357 ## STDOUT:
358 task name=spam
359 no block
360 status=44
361
362 task name=foo
363 running
364 block
365 status=33
366 ## END
367