1 #### cd accepts a block, runs it in different dir
2 shopt -s ysh: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: requires explicit command
31 shopt --set ysh:upgrade
32
33 cd /tmp { echo $PWD }
34
35 HOME=~
36 cd { echo $PWD }
37
38 ## status: 2
39 ## STDOUT:
40 /tmp
41 ## END
42
43 #### cd passed block with return 1
44 shopt -s ysh:all
45
46 f() {
47 cd / {
48 echo block
49 return 1
50 echo 'not reached'
51 }
52 }
53 f
54 echo 'not reached'
55
56 ## status: 1
57 ## STDOUT:
58 block
59 ## END
60
61 #### block doesn't have its own scope
62 shopt -s ysh:all
63 var x = 1
64 echo "x=$x"
65 cd / {
66 #set y = 5 # This would be an error because set doesn't do dynamic lookup
67 var x = 42
68 echo "x=$x"
69 }
70 echo "x=$x"
71 ## STDOUT:
72 x=1
73 x=42
74 x=42
75 ## END
76
77 #### redirects allowed in words, typed args, and after block
78 shopt -s ysh:upgrade
79
80 rm -f out
81 touch out
82
83 cd /tmp >>out {
84 echo 1 $PWD
85 }
86
87 cd /tmp >>out (; ; ^(echo 2 $PWD))
88
89 cd /tmp (; ; ^(echo 3 $PWD)) >>out
90
91 cd /tmp {
92 echo 4 $PWD
93 } >> out
94
95 cat out
96
97 ## STDOUT:
98 1 /tmp
99 2 /tmp
100 3 /tmp
101 4 /tmp
102 ## END
103
104 #### block literal in expression mode: ^(echo $PWD)
105 shopt -s oil:all
106
107 const myblock = ^(echo $PWD | wc -l)
108 eval (myblock)
109
110 const b2 = ^(echo one; echo two)
111 eval (b2)
112
113 ## STDOUT:
114 1
115 one
116 two
117 ## END
118
119 #### block arg as typed expression
120
121 shopt -s oil:all
122
123 # literal
124 cd /tmp (; ; ^(echo $PWD))
125
126 const myblock = ^(echo $PWD)
127 cd /tmp (; ; myblock)
128
129 ## STDOUT:
130 /tmp
131 /tmp
132 ## END
133
134 #### Pass invalid typed args
135
136 cd /tmp (42) # should be a block
137 ## status: 3
138
139 #### Pass too many typed args
140
141 cd /tmp (1, 2)
142 ## status: 3
143
144 #### 'builtin' and 'command' with block
145 shopt --set oil:upgrade
146 builtin cd / {
147 echo "builtin $PWD"
148 }
149 command cd / {
150 echo "command $PWD"
151 }
152 ## STDOUT:
153 builtin /
154 command /
155 ## END
156
157 #### Consistency: Exit Status and Blocks
158 shopt --set parse_brace
159
160 cd / {
161 false
162 }
163 echo cd=$?
164
165 shopt --unset errexit {
166 false
167 }
168 echo shopt=$?
169
170 shvar FOO=foo {
171 echo " FOO=$FOO"
172 false
173 }
174 echo shvar=$?
175
176 try {
177 false
178 }
179 echo try=$?
180
181 ## STDOUT:
182 cd=0
183 shopt=0
184 FOO=foo
185 shvar=0
186 try=0
187 ## END
188
189 #### Consistency: Unwanted Blocks Are Errors
190 shopt --set parse_brace
191
192 true { echo BAD }
193 echo true $?
194
195 false ( 42, 43 )
196 echo false $?
197
198 echo { echo BAD }
199 echo echo block $?
200
201 echo ( 42, 43 )
202 echo echo args $?
203
204 command echo 'command block' { echo BAD }
205 echo command echo $?
206
207 builtin echo 'builtin block' { echo BAD }
208 echo builtin echo $?
209
210 pushd $TMP { echo BAD }
211 echo pushd $?
212
213 ## STDOUT:
214 true 2
215 false 2
216 echo block 2
217 echo args 2
218 command echo 2
219 builtin echo 2
220 pushd 2
221 ## END
222
223 #### Block with Bare Assignments
224
225 # oil:all has parse_equals
226 # is there any way to turn on parse_equals only in config blocks?
227 # but we don't know what's a block ahead of time
228 # I think we would have to check at runtime. Look at VarChecker
229
230 shopt --set oil:all
231
232 proc Rule(s ; ; ; b) {
233 echo "rule $s"
234 }
235
236 proc myrules(name) {
237 Rule $name-python {
238 kind = 'python'
239 }
240
241 Rule $name-cc {
242 kind = 'cc' # should NOT conflict
243 }
244 }
245
246 myrules foo
247 myrules bar
248
249 ## STDOUT:
250 rule foo-python
251 rule foo-cc
252 rule bar-python
253 rule bar-cc
254 ## END
255
256 #### Proc that doesn't take a block
257 shopt --set parse_brace parse_proc parse_paren
258
259 proc task(name ; ; ; b = null) {
260 echo "task name=$name"
261 if (b) {
262 eval (b)
263 return 33
264 } else {
265 echo 'no block'
266 return 44
267 }
268 }
269
270 task spam
271 echo status=$?
272
273 echo
274
275 task foo {
276 echo 'running'
277 echo 'block'
278 }
279 echo status=$?
280
281 ## STDOUT:
282 task name=spam
283 no block
284 status=44
285
286 task name=foo
287 running
288 block
289 status=33
290 ## END
291