1 ## compare_shells: bash zsh mksh ash
2 ## oils_failures_allowed: 9
3
4 # Note: this file elaborates on spec/ble-idioms.test.sh
5
6 #### Indexed LHS without spaces, and +=
7 a[1]=x
8 echo status=$?
9 argv.py "${a[@]}"
10
11 a[0+2]=y
12 #a[2|3]=y # zsh doesn't allow this
13 argv.py "${a[@]}"
14
15 # += does appending
16 a[0+2]+=z
17 argv.py "${a[@]}"
18
19 ## STDOUT:
20 status=0
21 ['x']
22 ['x', 'y']
23 ['x', 'yz']
24 ## END
25
26 ## N-I ash status: 2
27 ## N-I ash STDOUT:
28 status=127
29 ## END
30
31 #### Indexed LHS with spaces
32 case $SH in zsh|ash) exit ;; esac
33
34 a[1 * 1]=x
35 a[ 1 + 2 ]=z
36 echo status=$?
37
38 argv.py "${a[@]}"
39 ## STDOUT:
40 status=0
41 ['x', 'z']
42 ## END
43 ## N-I zsh/ash STDOUT:
44 ## END
45
46 #### Nested a[i[0]]=0
47 case $SH in zsh|ash) exit ;; esac
48
49 i=(0 1 2)
50
51 a[i[0]]=0
52 a[ i[1] ]=1
53 a[ i[2] ]=2
54 a[ i[1]+i[2] ]=3
55
56 argv.py "${a[@]}"
57
58 ## STDOUT:
59 ['0', '1', '2', '3']
60 ## END
61 ## N-I zsh/ash STDOUT:
62 ## END
63
64 #### Multiple LHS array words
65 case $SH in zsh|ash) exit ;; esac
66
67 a=(0 1 2)
68 b=(3 4 5)
69
70 #declare -p a b
71
72 HOME=/home/spec-test
73
74 # empty string, and tilde sub
75 a[0 + 1]= b[2 + 0]=~/src
76
77 typeset -p a b
78
79 echo ---
80
81 # In bash, this bad prefix binding prints an error, but nothing fails
82 a[0 + 1]='foo' argv.py b[2 + 0]='bar'
83 echo status=$?
84
85 typeset -p a b
86
87 ## STDOUT:
88 declare -a a=([0]="0" [1]="" [2]="2")
89 declare -a b=([0]="3" [1]="4" [2]="/home/spec-test/src")
90 ---
91 ['b[2', '+', '0]=bar']
92 status=0
93 declare -a a=([0]="0" [1]="" [2]="2")
94 declare -a b=([0]="3" [1]="4" [2]="/home/spec-test/src")
95 ## END
96
97 ## OK mksh STDOUT:
98 set -A a
99 typeset a[0]=0
100 typeset a[1]=
101 typeset a[2]=2
102 set -A b
103 typeset b[0]=3
104 typeset b[1]=4
105 typeset b[2]=/home/spec-test/src
106 ---
107 ['b[2', '+', '0]=bar']
108 status=0
109 set -A a
110 typeset a[0]=0
111 typeset a[1]=
112 typeset a[2]=2
113 set -A b
114 typeset b[0]=3
115 typeset b[1]=4
116 typeset b[2]=/home/spec-test/src
117 ## END
118
119 ## N-I zsh/ash STDOUT:
120 ## END
121
122 #### LHS array is protected with shopt -s eval_unsafe_arith, e.g. 'a[$(echo 2)]'
123 case $SH in zsh|ash) exit ;; esac
124
125 a=(0 1 2)
126 b=(3 4 5)
127 typeset -p b
128
129 expr='a[$(echo 2)]'
130
131 echo 'get' "${b[expr]}"
132
133 b[expr]=zzz
134
135 echo 'set' "${b[expr]}"
136 typeset -p b
137
138 ## STDOUT:
139 declare -a b=([0]="3" [1]="4" [2]="5")
140 get 5
141 set zzz
142 declare -a b=([0]="3" [1]="4" [2]="zzz")
143 ## END
144
145 ## OK mksh STDOUT:
146 set -A b
147 typeset b[0]=3
148 typeset b[1]=4
149 typeset b[2]=5
150 get 5
151 set zzz
152 set -A b
153 typeset b[0]=3
154 typeset b[1]=4
155 typeset b[2]=zzz
156 ## END
157
158 ## N-I zsh/ash STDOUT:
159 ## END
160
161 #### file named a[ is not executed
162 case $SH in zsh|ash) exit ;; esac
163
164 PATH=".:$PATH"
165
166 for name in 'a[' 'a[5'; do
167 echo "echo hi from $name: \$# args: \$@" > "$name"
168 chmod +x "$name"
169 done
170
171 # this does not executed a[5
172 a[5 + 1]=
173 a[5 / 1]=y
174 echo len=${#a[@]}
175
176 # Not detected as assignment because there's a non-arith character
177 # bash and mksh both give a syntax error
178 a[5 # 1]=
179
180 ## status: 1
181 ## STDOUT:
182 len=2
183 ## END
184
185 ## N-I zsh/ash status: 0
186 ## N-I zsh/ash STDOUT:
187 ## END
188
189 #### More fragments like a[ a[5 a[5 + a[5 + 3]
190
191 for name in 'a[' 'a[5'; do
192 echo "echo hi from $name: \$# args: \$@" > "$name"
193 chmod +x "$name"
194 done
195
196 # syntax error in bash
197 $SH -c 'a['
198 echo "a[ status=$?"
199
200 $SH -c 'a[5'
201 echo "a[5 status=$?"
202
203 # 1 arg +
204 $SH -c 'a[5 +'
205 echo "a[5 + status=$?"
206
207 # 2 args
208 $SH -c 'a[5 + 3]'
209 echo "a[5 + 3] status=$?"
210
211 $SH -c 'a[5 + 3]='
212 echo "a[5 + 3]= status=$?"
213
214 $SH -c 'a[5 + 3]+'
215 echo "a[5 + 3]+ status=$?"
216
217 $SH -c 'a[5 + 3]+='
218 echo "a[5 + 3]+= status=$?"
219
220 # mksh doesn't issue extra parse errors
221 # and it doesn't turn a[5 + 3] and a[5 + 3]+ into commands!
222
223 ## STDOUT:
224 a[ status=127
225 a[5 status=127
226 a[5 + status=127
227 a[5 + 3] status=127
228 a[5 + 3]= status=0
229 a[5 + 3]+ status=127
230 a[5 + 3]+= status=0
231 ## END
232
233 ## BUG bash STDOUT:
234 a[ status=2
235 a[5 status=2
236 a[5 + status=2
237 a[5 + 3] status=127
238 a[5 + 3]= status=0
239 a[5 + 3]+ status=127
240 a[5 + 3]+= status=0
241 ## END
242
243 # in zsh, everything becomes "bad pattern"
244
245 ## BUG-2 zsh STDOUT:
246 a[ status=1
247 a[5 status=1
248 a[5 + status=1
249 a[5 + 3] status=1
250 a[5 + 3]= status=1
251 a[5 + 3]+ status=1
252 a[5 + 3]+= status=1
253 ## END
254
255 # ash behavior is consistent
256
257 ## N-I ash STDOUT:
258 a[ status=127
259 a[5 status=127
260 a[5 + status=127
261 a[5 + 3] status=127
262 a[5 + 3]= status=127
263 a[5 + 3]+ status=127
264 a[5 + 3]+= status=127
265 ## END
266
267 #### Are quotes allowed?
268
269 # double quotes allowed in bash
270 a["1"]=2
271 echo status=$? len=${#a[@]}
272
273 a['2']=3
274 echo status=$? len=${#a[@]}
275
276 # allowed in bash
277 a[2 + "3"]=5
278 echo status=$? len=${#a[@]}
279
280 a[3 + '4']=5
281 echo status=$? len=${#a[@]}
282
283 ## status: 1
284 ## STDOUT:
285 ## END
286
287 ## OK ash status: 2
288
289 # syntax errors are not fatal in bash
290
291 ## BUG bash status: 0
292 ## BUG bash STDOUT:
293 status=0 len=1
294 status=1 len=1
295 status=0 len=2
296 status=1 len=2
297 ## END
298
299 #### Tricky parsing - a[ a[0]=1 ]=X a[ a[0]+=1 ]+=X
300 case $SH in zsh|mksh|ash) exit ;; esac
301
302 # the nested [] means we can't use regular language lookahead?
303
304 echo assign=$(( z[0] = 42 ))
305
306 a[a[0]=1]=X
307 declare -p a
308
309 a[ a[2]=3 ]=Y
310 declare -p a
311
312 echo ---
313
314 a[ a[0]+=1 ]+=X
315 declare -p a
316
317 ## STDOUT:
318 assign=42
319 declare -a a=([0]="1" [1]="X")
320 declare -a a=([0]="1" [1]="X" [2]="3" [3]="Y")
321 ---
322 declare -a a=([0]="2" [1]="X" [2]="3X" [3]="Y")
323 ## END
324
325 ## N-I zsh/mksh/ash STDOUT:
326 ## END
327
328 #### argv.py a[1 + 2]=
329 case $SH in zsh|ash) exit ;; esac
330
331 # This tests that the worse parser doesn't unconditinoally treat a[ as special
332
333 a[1 + 2]= argv.py a[1 + 2]=
334 echo status=$?
335
336 a[1 + 2]+= argv.py a[1 + 2]+=
337 echo status=$?
338
339 argv.py a[3 + 4]=
340
341 argv.py a[3 + 4]+=
342
343 ## STDOUT:
344 ['a[1', '+', '2]=']
345 status=0
346 ['a[1', '+', '2]+=']
347 status=0
348 ['a[3', '+', '4]=']
349 ['a[3', '+', '4]+=']
350 ## END
351
352 ## N-I zsh/ash STDOUT:
353 ## END
354
355 #### declare builtin doesn't allow spaces
356 case $SH in zsh|mksh|ash) exit ;; esac
357
358 # OSH doesn't allow this
359 declare a[a[0]=1]=X
360 declare -p a
361
362 # neither bash nor OSH allow this
363 declare a[ a[2]=3 ]=Y
364 declare -p a
365
366 ## STDOUT:
367 declare -a a=([0]="1" [1]="X")
368 declare -a a=([0]="1" [1]="X" [2]="3")
369 ## END
370
371 ## OK osh status: 1
372 ## OK osh STDOUT:
373 ## END
374
375 ## N-I zsh/mksh/ash STDOUT:
376 ## END