1 | ## compare_shells: bash mksh
|
2 | ## oils_cpp_failures_allowed: 2
|
3 |
|
4 | #### Performance demo
|
5 |
|
6 | case $SH in bash|mksh) exit ;; esac
|
7 |
|
8 | #pp test_ (a)
|
9 |
|
10 | sp=( foo {25..27} bar )
|
11 |
|
12 | sp[10]='sparse'
|
13 |
|
14 | echo $[type(sp)]
|
15 |
|
16 | echo len: "${#sp[@]}"
|
17 |
|
18 | #echo $[len(sp)]
|
19 |
|
20 | shopt -s ysh:upgrade
|
21 |
|
22 | echo subst: "${sp[@]}"
|
23 | echo keys: "${!sp[@]}"
|
24 |
|
25 | echo slice: "${sp[@]:2:3}"
|
26 |
|
27 | sp[0]=set0
|
28 |
|
29 | echo get0: "${sp[0]}"
|
30 | echo get1: "${sp[1]}"
|
31 | echo ---
|
32 |
|
33 | to_append=(x y)
|
34 | echo append
|
35 | sp+=("${to_append[@]}")
|
36 | echo subst: "${sp[@]}"
|
37 | echo keys: "${!sp[@]}"
|
38 | echo ---
|
39 |
|
40 | echo unset
|
41 | unset -v 'sp[11]'
|
42 | echo subst: "${sp[@]}"
|
43 | echo keys: "${!sp[@]}"
|
44 |
|
45 | ## STDOUT:
|
46 | BashArray
|
47 | len: 6
|
48 | subst: foo 25 26 27 bar sparse
|
49 | keys: 0 1 2 3 4 10
|
50 | slice: 26 27 bar
|
51 | get0: set0
|
52 | get1: 25
|
53 | ---
|
54 | append
|
55 | subst: set0 25 26 27 bar sparse x y
|
56 | keys: 0 1 2 3 4 10 11 12
|
57 | ---
|
58 | unset
|
59 | subst: set0 25 26 27 bar sparse y
|
60 | keys: 0 1 2 3 4 10 12
|
61 | ## END
|
62 |
|
63 | ## N-I bash/mksh STDOUT:
|
64 | ## END
|
65 |
|
66 |
|
67 | #### test length
|
68 | sp=(x y z)
|
69 |
|
70 | sp[5]=z
|
71 |
|
72 | echo len=${#sp[@]}
|
73 |
|
74 | sp[10]=z
|
75 |
|
76 | echo len=${#sp[@]}
|
77 |
|
78 | ## STDOUT:
|
79 | len=4
|
80 | len=5
|
81 | ## END
|
82 |
|
83 |
|
84 | #### test "declare -p sp"
|
85 | a0=()
|
86 | a1=(1)
|
87 | a2=(1 2)
|
88 | a=(x y z w)
|
89 | a[500]=100
|
90 | a[1000]=100
|
91 |
|
92 | case $SH in
|
93 | bash|mksh)
|
94 | typeset -p a0 a1 a2 a
|
95 | exit ;;
|
96 | esac
|
97 |
|
98 | declare -p a0 a1 a2 a
|
99 |
|
100 | ## STDOUT:
|
101 | declare -a a0=()
|
102 | declare -a a1=(1)
|
103 | declare -a a2=(1 2)
|
104 | declare -a a=([0]=x [1]=y [2]=z [3]=w [500]=100 [1000]=100)
|
105 | ## END
|
106 |
|
107 | ## OK bash STDOUT:
|
108 | declare -a a0=()
|
109 | declare -a a1=([0]="1")
|
110 | declare -a a2=([0]="1" [1]="2")
|
111 | declare -a a=([0]="x" [1]="y" [2]="z" [3]="w" [500]="100" [1000]="100")
|
112 | ## END
|
113 |
|
114 | ## OK mksh STDOUT:
|
115 | set -A a1
|
116 | typeset a1[0]=1
|
117 | set -A a2
|
118 | typeset a2[0]=1
|
119 | typeset a2[1]=2
|
120 | set -A a
|
121 | typeset a[0]=x
|
122 | typeset a[1]=y
|
123 | typeset a[2]=z
|
124 | typeset a[3]=w
|
125 | typeset a[500]=100
|
126 | typeset a[1000]=100
|
127 | ## END
|
128 |
|
129 | #### +=
|
130 | sp1[10]=a
|
131 | sp1[20]=b
|
132 | sp1[99]=c
|
133 | typeset -p sp1 | sed 's/"//g'
|
134 | sp1+=(1 2 3)
|
135 | typeset -p sp1 | sed 's/"//g'
|
136 |
|
137 | ## STDOUT:
|
138 | declare -a sp1=([10]=a [20]=b [99]=c)
|
139 | declare -a sp1=([10]=a [20]=b [99]=c [100]=1 [101]=2 [102]=3)
|
140 | ## END
|
141 |
|
142 |
|
143 | ## OK mksh STDOUT:
|
144 | set -A sp1
|
145 | typeset sp1[10]=a
|
146 | typeset sp1[20]=b
|
147 | typeset sp1[99]=c
|
148 | set -A sp1
|
149 | typeset sp1[10]=a
|
150 | typeset sp1[20]=b
|
151 | typeset sp1[99]=c
|
152 | typeset sp1[100]=1
|
153 | typeset sp1[101]=2
|
154 | typeset sp1[102]=3
|
155 | ## END
|
156 |
|
157 |
|
158 | #### a[i]=v
|
159 | sp1[10]=a
|
160 | sp1[20]=b
|
161 | sp1[30]=c
|
162 | typeset -p sp1 | sed 's/"//g'
|
163 | sp1[10]=X
|
164 | sp1[25]=Y
|
165 | sp1[90]=Z
|
166 | typeset -p sp1 | sed 's/"//g'
|
167 |
|
168 | ## STDOUT:
|
169 | declare -a sp1=([10]=a [20]=b [30]=c)
|
170 | declare -a sp1=([10]=X [20]=b [25]=Y [30]=c [90]=Z)
|
171 | ## END
|
172 |
|
173 | ## OK mksh STDOUT:
|
174 | set -A sp1
|
175 | typeset sp1[10]=a
|
176 | typeset sp1[20]=b
|
177 | typeset sp1[30]=c
|
178 | set -A sp1
|
179 | typeset sp1[10]=X
|
180 | typeset sp1[20]=b
|
181 | typeset sp1[25]=Y
|
182 | typeset sp1[30]=c
|
183 | typeset sp1[90]=Z
|
184 | ## END
|
185 |
|
186 |
|
187 | #### Negative index with a[i]=v
|
188 | case $SH in mksh) exit ;; esac
|
189 |
|
190 | sp1[9]=x
|
191 | typeset -p sp1 | sed 's/"//g'
|
192 |
|
193 | sp1[-1]=A
|
194 | sp1[-4]=B
|
195 | sp1[-8]=C
|
196 | sp1[-10]=D
|
197 | typeset -p sp1 | sed 's/"//g'
|
198 |
|
199 | ## STDOUT:
|
200 | declare -a sp1=([9]=x)
|
201 | declare -a sp1=([0]=D [2]=C [6]=B [9]=A)
|
202 | ## END
|
203 |
|
204 | ## N-I mksh STDOUT:
|
205 | ## END
|
206 |
|
207 |
|
208 | #### a[i]=v with BigInt
|
209 | case $SH in mksh) exit ;; esac
|
210 |
|
211 | sp1[1]=x
|
212 | sp1[5]=y
|
213 | sp1[9]=z
|
214 |
|
215 | echo "${#sp1[@]}"
|
216 | sp1[0x7FFFFFFFFFFFFFFF]=a
|
217 | echo "${#sp1[@]}"
|
218 | sp1[0x7FFFFFFFFFFFFFFE]=b
|
219 | echo "${#sp1[@]}"
|
220 | sp1[0x7FFFFFFFFFFFFFFD]=c
|
221 | echo "${#sp1[@]}"
|
222 |
|
223 | ## STDOUT:
|
224 | 3
|
225 | 4
|
226 | 5
|
227 | 6
|
228 | ## END
|
229 |
|
230 | ## N-I mksh STDOUT:
|
231 | ## END
|
232 |
|
233 |
|
234 | #### Negative out-of-bound index with a[i]=v (1/2)
|
235 | case $SH in mksh) exit ;; esac
|
236 |
|
237 | sp1[9]=x
|
238 | sp1[-11]=E
|
239 | declare -p sp1
|
240 |
|
241 | ## status: 1
|
242 | ## STDOUT:
|
243 | ## END
|
244 | ## STDERR:
|
245 | sp1[-11]=E
|
246 | ^~~~
|
247 | [ stdin ]:4: fatal: Index -11 is out of bounds for array of length 10
|
248 | ## END
|
249 |
|
250 | ## OK bash status: 0
|
251 | ## OK bash STDOUT:
|
252 | declare -a sp1=([9]="x")
|
253 | ## END
|
254 | ## OK bash STDERR:
|
255 | bash: line 4: sp1[-11]: bad array subscript
|
256 | ## END
|
257 |
|
258 | ## N-I mksh status: 0
|
259 | ## N-I mksh stdout-json: ""
|
260 | ## N-I mksh stderr-json: ""
|
261 |
|
262 |
|
263 | #### Negative out-of-bound index with a[i]=v (2/2)
|
264 | case $SH in mksh) exit ;; esac
|
265 |
|
266 | sp1[9]=x
|
267 |
|
268 | sp1[-21]=F
|
269 | declare -p sp1
|
270 |
|
271 | ## status: 1
|
272 | ## STDOUT:
|
273 | ## END
|
274 | ## STDERR:
|
275 | sp1[-21]=F
|
276 | ^~~~
|
277 | [ stdin ]:5: fatal: Index -21 is out of bounds for array of length 10
|
278 | ## END
|
279 |
|
280 | ## OK bash status: 0
|
281 | ## OK bash STDOUT:
|
282 | declare -a sp1=([9]="x")
|
283 | ## END
|
284 | ## OK bash STDERR:
|
285 | bash: line 5: sp1[-21]: bad array subscript
|
286 | ## END
|
287 |
|
288 | ## N-I mksh status: 0
|
289 | ## N-I mksh stdout-json: ""
|
290 | ## N-I mksh stderr-json: ""
|
291 |
|
292 |
|
293 | #### xtrace a+=()
|
294 | #case $SH in mksh) exit ;; esac
|
295 |
|
296 | sp1=(1)
|
297 | set -x
|
298 | sp1+=(2)
|
299 |
|
300 | ## STDERR:
|
301 | + sp1+=(2)
|
302 | ## END
|
303 |
|
304 | ## OK mksh STDERR:
|
305 | + set -A sp1+ -- 2
|
306 | ## END
|
307 |
|
308 |
|
309 | #### unset -v a[i]
|
310 | a=(1 2 3 4 5 6 7 8 9)
|
311 | typeset -p a
|
312 | unset -v "a[1]"
|
313 | typeset -p a
|
314 | unset -v "a[9]"
|
315 | typeset -p a
|
316 | unset -v "a[0]"
|
317 | typeset -p a
|
318 |
|
319 | ## STDOUT:
|
320 | declare -a a=(1 2 3 4 5 6 7 8 9)
|
321 | declare -a a=([0]=1 [2]=3 [3]=4 [4]=5 [5]=6 [6]=7 [7]=8 [8]=9)
|
322 | declare -a a=([0]=1 [2]=3 [3]=4 [4]=5 [5]=6 [6]=7 [7]=8 [8]=9)
|
323 | declare -a a=([2]=3 [3]=4 [4]=5 [5]=6 [6]=7 [7]=8 [8]=9)
|
324 | ## END
|
325 |
|
326 | ## OK bash STDOUT:
|
327 | declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
|
328 | declare -a a=([0]="1" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
|
329 | declare -a a=([0]="1" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
|
330 | declare -a a=([2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
|
331 | ## END
|
332 |
|
333 | ## OK mksh STDOUT:
|
334 | set -A a
|
335 | typeset a[0]=1
|
336 | typeset a[1]=2
|
337 | typeset a[2]=3
|
338 | typeset a[3]=4
|
339 | typeset a[4]=5
|
340 | typeset a[5]=6
|
341 | typeset a[6]=7
|
342 | typeset a[7]=8
|
343 | typeset a[8]=9
|
344 | set -A a
|
345 | typeset a[0]=1
|
346 | typeset a[2]=3
|
347 | typeset a[3]=4
|
348 | typeset a[4]=5
|
349 | typeset a[5]=6
|
350 | typeset a[6]=7
|
351 | typeset a[7]=8
|
352 | typeset a[8]=9
|
353 | set -A a
|
354 | typeset a[0]=1
|
355 | typeset a[2]=3
|
356 | typeset a[3]=4
|
357 | typeset a[4]=5
|
358 | typeset a[5]=6
|
359 | typeset a[6]=7
|
360 | typeset a[7]=8
|
361 | typeset a[8]=9
|
362 | set -A a
|
363 | typeset a[2]=3
|
364 | typeset a[3]=4
|
365 | typeset a[4]=5
|
366 | typeset a[5]=6
|
367 | typeset a[6]=7
|
368 | typeset a[7]=8
|
369 | typeset a[8]=9
|
370 | ## END
|
371 |
|
372 |
|
373 | #### unset -v a[i] with out-of-bound negative index
|
374 | case $SH in mksh) exit ;; esac
|
375 |
|
376 | a=(1)
|
377 |
|
378 | unset -v "a[-2]"
|
379 | unset -v "a[-3]"
|
380 |
|
381 | ## status: 1
|
382 | ## STDOUT:
|
383 | ## END
|
384 | ## STDERR:
|
385 | unset -v "a[-2]"
|
386 | ^
|
387 | [ stdin ]:5: a[-2]: Index is out of bounds for array of length 1
|
388 | unset -v "a[-3]"
|
389 | ^
|
390 | [ stdin ]:6: a[-3]: Index is out of bounds for array of length 1
|
391 | ## END
|
392 |
|
393 | ## OK bash STDERR:
|
394 | bash: line 5: unset: [-2]: bad array subscript
|
395 | bash: line 6: unset: [-3]: bad array subscript
|
396 | ## END
|
397 |
|
398 | ## N-I mksh status: 0
|
399 | ## N-I mksh STDERR:
|
400 | ## END
|
401 |
|
402 |
|
403 | #### unset -v a[i] for max index
|
404 | case $SH in mksh) exit ;; esac
|
405 |
|
406 | a=({1..9})
|
407 | unset -v 'a[-1]'
|
408 | a[-1]=x
|
409 | declare -p a
|
410 | unset -v 'a[-1]'
|
411 | a[-1]=x
|
412 | declare -p a
|
413 |
|
414 | ## STDOUT:
|
415 | declare -a a=(1 2 3 4 5 6 7 x)
|
416 | declare -a a=(1 2 3 4 5 6 x)
|
417 | ## END
|
418 |
|
419 | ## OK bash STDOUT:
|
420 | declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="x")
|
421 | declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="x")
|
422 | ## END
|
423 |
|
424 | ## N-I mksh STDOUT:
|
425 | ## END
|
426 |
|
427 |
|
428 | #### [[ -v a[i] ]]
|
429 | case $SH in mksh) exit ;; esac
|
430 |
|
431 | sp1=()
|
432 | [[ -v sp1[0] ]]; echo "$? (expect 1)"
|
433 | [[ -v sp1[9] ]]; echo "$? (expect 1)"
|
434 |
|
435 | sp2=({1..9})
|
436 | [[ -v sp2[0] ]]; echo "$? (expect 0)"
|
437 | [[ -v sp2[8] ]]; echo "$? (expect 0)"
|
438 | [[ -v sp2[9] ]]; echo "$? (expect 1)"
|
439 | [[ -v sp2[-1] ]]; echo "$? (expect 0)"
|
440 | [[ -v sp2[-2] ]]; echo "$? (expect 0)"
|
441 | [[ -v sp2[-9] ]]; echo "$? (expect 0)"
|
442 |
|
443 | sp3=({1..9})
|
444 | unset -v 'sp3[4]'
|
445 | [[ -v sp3[3] ]]; echo "$? (expect 0)"
|
446 | [[ -v sp3[4] ]]; echo "$? (expect 1)"
|
447 | [[ -v sp3[5] ]]; echo "$? (expect 0)"
|
448 | [[ -v sp3[-1] ]]; echo "$? (expect 0)"
|
449 | [[ -v sp3[-4] ]]; echo "$? (expect 0)"
|
450 | [[ -v sp3[-5] ]]; echo "$? (expect 1)"
|
451 | [[ -v sp3[-6] ]]; echo "$? (expect 0)"
|
452 | [[ -v sp3[-9] ]]; echo "$? (expect 0)"
|
453 |
|
454 | ## STDOUT:
|
455 | 1 (expect 1)
|
456 | 1 (expect 1)
|
457 | 0 (expect 0)
|
458 | 0 (expect 0)
|
459 | 1 (expect 1)
|
460 | 0 (expect 0)
|
461 | 0 (expect 0)
|
462 | 0 (expect 0)
|
463 | 0 (expect 0)
|
464 | 1 (expect 1)
|
465 | 0 (expect 0)
|
466 | 0 (expect 0)
|
467 | 0 (expect 0)
|
468 | 1 (expect 1)
|
469 | 0 (expect 0)
|
470 | 0 (expect 0)
|
471 | ## END
|
472 |
|
473 | ## N-I mksh STDOUT:
|
474 | ## END
|
475 |
|
476 |
|
477 | #### [[ -v a[i] ]] with invalid negative index
|
478 | case $SH in mksh) exit ;; esac
|
479 |
|
480 | sp1=()
|
481 | ([[ -v sp1[-1] ]]; echo "$? (expect 1)")
|
482 | sp2=({1..9})
|
483 | ([[ -v sp2[-10] ]]; echo "$? (expect 1)")
|
484 | sp3=({1..9})
|
485 | unset -v 'sp3[4]'
|
486 | ([[ -v sp3[-10] ]]; echo "$? (expect 1)")
|
487 |
|
488 | ## status: 1
|
489 | ## STDOUT:
|
490 | ## END
|
491 | ## STDERR:
|
492 | ([[ -v sp1[-1] ]]; echo "$? (expect 1)")
|
493 | ^~~
|
494 | [ stdin ]:4: fatal: -v got index -1, which is out of bounds for array of length 0
|
495 | ([[ -v sp2[-10] ]]; echo "$? (expect 1)")
|
496 | ^~~
|
497 | [ stdin ]:6: fatal: -v got index -10, which is out of bounds for array of length 9
|
498 | ([[ -v sp3[-10] ]]; echo "$? (expect 1)")
|
499 | ^~~
|
500 | [ stdin ]:9: fatal: -v got index -10, which is out of bounds for array of length 9
|
501 | ## END
|
502 |
|
503 | ## OK bash status: 0
|
504 | ## OK bash STDOUT:
|
505 | 1 (expect 1)
|
506 | 1 (expect 1)
|
507 | 1 (expect 1)
|
508 | ## END
|
509 | ## OK bash STDERR:
|
510 | bash: line 4: sp1: bad array subscript
|
511 | bash: line 6: sp2: bad array subscript
|
512 | bash: line 9: sp3: bad array subscript
|
513 | ## END
|
514 |
|
515 | ## N-I mksh status: 0
|
516 | ## N-I mksh stdout-json: ""
|
517 | ## N-I mksh stderr-json: ""
|
518 |
|
519 |
|
520 | #### ((sp[i])) and ((sp[i]++))
|
521 | a=(1 2 3 4 5 6 7 8 9)
|
522 | unset -v 'a[2]' 'a[3]' 'a[7]'
|
523 |
|
524 | echo $((a[0]))
|
525 | echo $((a[1]))
|
526 | echo $((a[2]))
|
527 | echo $((a[3]))
|
528 | echo $((a[7]))
|
529 |
|
530 | echo $((a[1]++))
|
531 | echo $((a[2]++))
|
532 | echo $((a[3]++))
|
533 | echo $((a[7]++))
|
534 |
|
535 | echo $((++a[1]))
|
536 | echo $((++a[2]))
|
537 | echo $((++a[3]))
|
538 | echo $((++a[7]))
|
539 |
|
540 | echo $((a[1] = 100, a[1]))
|
541 | echo $((a[2] = 100, a[2]))
|
542 | echo $((a[3] = 100, a[3]))
|
543 | echo $((a[7] = 100, a[7]))
|
544 |
|
545 | ## STDOUT:
|
546 | 1
|
547 | 2
|
548 | 0
|
549 | 0
|
550 | 0
|
551 | 2
|
552 | 0
|
553 | 0
|
554 | 0
|
555 | 4
|
556 | 2
|
557 | 2
|
558 | 2
|
559 | 100
|
560 | 100
|
561 | 100
|
562 | 100
|
563 | ## END
|
564 |
|
565 |
|
566 | #### ((sp[i])) and ((sp[i]++)) with invalid negative index
|
567 | case $SH in mksh) exit ;; esac
|
568 |
|
569 | a=({1..9})
|
570 | unset -v 'a[2]' 'a[3]' 'a[7]'
|
571 |
|
572 | echo $((a[-10]))
|
573 |
|
574 | ## STDOUT:
|
575 | 0
|
576 | ## END
|
577 | ## STDERR:
|
578 | echo $((a[-10]))
|
579 | ^
|
580 | [ stdin ]:6: Index -10 out of bounds for array of length 9
|
581 | ## END
|
582 |
|
583 | ## OK bash STDERR:
|
584 | bash: line 6: a: bad array subscript
|
585 | ## END
|
586 |
|
587 | ## N-I mksh STDOUT:
|
588 | ## END
|
589 | ## N-I mksh STDERR:
|
590 | ## END
|
591 |
|
592 |
|
593 | #### ${sp[i]}
|
594 | case $SH in mksh) exit ;; esac
|
595 |
|
596 | sp=({1..9})
|
597 | unset -v 'sp[2]'
|
598 | unset -v 'sp[3]'
|
599 | unset -v 'sp[7]'
|
600 |
|
601 | echo "sp[0]: '${sp[0]}', ${sp[0]:-(empty)}, ${sp[0]+set}."
|
602 | echo "sp[1]: '${sp[1]}', ${sp[1]:-(empty)}, ${sp[1]+set}."
|
603 | echo "sp[8]: '${sp[8]}', ${sp[8]:-(empty)}, ${sp[8]+set}."
|
604 | echo "sp[2]: '${sp[2]}', ${sp[2]:-(empty)}, ${sp[2]+set}."
|
605 | echo "sp[3]: '${sp[3]}', ${sp[3]:-(empty)}, ${sp[3]+set}."
|
606 | echo "sp[7]: '${sp[7]}', ${sp[7]:-(empty)}, ${sp[7]+set}."
|
607 |
|
608 | echo "sp[-1]: '${sp[-1]}'."
|
609 | echo "sp[-2]: '${sp[-2]}'."
|
610 | echo "sp[-3]: '${sp[-3]}'."
|
611 | echo "sp[-4]: '${sp[-4]}'."
|
612 | echo "sp[-9]: '${sp[-9]}'."
|
613 |
|
614 | ## STDOUT:
|
615 | sp[0]: '1', 1, set.
|
616 | sp[1]: '2', 2, set.
|
617 | sp[8]: '9', 9, set.
|
618 | sp[2]: '', (empty), .
|
619 | sp[3]: '', (empty), .
|
620 | sp[7]: '', (empty), .
|
621 | sp[-1]: '9'.
|
622 | sp[-2]: ''.
|
623 | sp[-3]: '7'.
|
624 | sp[-4]: '6'.
|
625 | sp[-9]: '1'.
|
626 | ## END
|
627 |
|
628 | ## N-I mksh STDOUT:
|
629 | ## END
|
630 |
|
631 |
|
632 | #### ${sp[i]} with negative invalid index
|
633 | case $SH in mksh) exit ;; esac
|
634 |
|
635 | sp=({1..9})
|
636 | unset -v 'sp[2]'
|
637 | unset -v 'sp[3]'
|
638 | unset -v 'sp[7]'
|
639 |
|
640 | echo "sp[-10]: '${sp[-10]}'."
|
641 | echo "sp[-11]: '${sp[-11]}'."
|
642 | echo "sp[-19]: '${sp[-19]}'."
|
643 |
|
644 | ## STDOUT:
|
645 | sp[-10]: ''.
|
646 | sp[-11]: ''.
|
647 | sp[-19]: ''.
|
648 | ## END
|
649 | ## STDERR:
|
650 | echo "sp[-10]: '${sp[-10]}'."
|
651 | ^~
|
652 | [ stdin ]:8: Index -10 out of bounds for array of length 9
|
653 | echo "sp[-11]: '${sp[-11]}'."
|
654 | ^~
|
655 | [ stdin ]:9: Index -11 out of bounds for array of length 9
|
656 | echo "sp[-19]: '${sp[-19]}'."
|
657 | ^~
|
658 | [ stdin ]:10: Index -19 out of bounds for array of length 9
|
659 | ## END
|
660 |
|
661 | ## OK bash STDERR:
|
662 | bash: line 8: sp: bad array subscript
|
663 | bash: line 9: sp: bad array subscript
|
664 | bash: line 10: sp: bad array subscript
|
665 | ## END
|
666 |
|
667 | ## N-I mksh STDOUT:
|
668 | ## END
|
669 | ## N-I mksh STDERR:
|
670 | ## END
|
671 |
|
672 |
|
673 | #### ${a[@]:offset:length}
|
674 | case $SH in mksh) exit ;; esac
|
675 |
|
676 | a=(v{0..9})
|
677 | unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
|
678 |
|
679 | echo '==== ${a[@]:offset} ===='
|
680 | echo "[${a[@]:0}][${a[*]:0}]"
|
681 | echo "[${a[@]:2}][${a[*]:2}]"
|
682 | echo "[${a[@]:3}][${a[*]:3}]"
|
683 | echo "[${a[@]:5}][${a[*]:5}]"
|
684 | echo "[${a[@]:9}][${a[*]:9}]"
|
685 | echo "[${a[@]:10}][${a[*]:10}]"
|
686 | echo "[${a[@]:11}][${a[*]:11}]"
|
687 |
|
688 | echo '==== ${a[@]:negative} ===='
|
689 | echo "[${a[@]: -1}][${a[*]: -1}]"
|
690 | echo "[${a[@]: -2}][${a[*]: -2}]"
|
691 | echo "[${a[@]: -5}][${a[*]: -5}]"
|
692 | echo "[${a[@]: -9}][${a[*]: -9}]"
|
693 | echo "[${a[@]: -10}][${a[*]: -10}]"
|
694 | echo "[${a[@]: -11}][${a[*]: -11}]"
|
695 | echo "[${a[@]: -21}][${a[*]: -21}]"
|
696 |
|
697 | echo '==== ${a[@]:offset:length} ===='
|
698 | echo "[${a[@]:0:0}][${a[*]:0:0}]"
|
699 | echo "[${a[@]:0:1}][${a[*]:0:1}]"
|
700 | echo "[${a[@]:0:3}][${a[*]:0:3}]"
|
701 | echo "[${a[@]:2:1}][${a[*]:2:1}]"
|
702 | echo "[${a[@]:2:4}][${a[*]:2:4}]"
|
703 | echo "[${a[@]:3:4}][${a[*]:3:4}]"
|
704 | echo "[${a[@]:5:4}][${a[*]:5:4}]"
|
705 | echo "[${a[@]:5:0}][${a[*]:5:0}]"
|
706 | echo "[${a[@]:9:1}][${a[*]:9:1}]"
|
707 | echo "[${a[@]:9:2}][${a[*]:9:2}]"
|
708 | echo "[${a[@]:10:1}][${a[*]:10:1}]"
|
709 |
|
710 | ## STDOUT:
|
711 | ==== ${a[@]:offset} ====
|
712 | [v0 v1 v5 v6 v8 v9][v0 v1 v5 v6 v8 v9]
|
713 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
714 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
715 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
716 | [v9][v9]
|
717 | [][]
|
718 | [][]
|
719 | ==== ${a[@]:negative} ====
|
720 | [v9][v9]
|
721 | [v8 v9][v8 v9]
|
722 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
723 | [v1 v5 v6 v8 v9][v1 v5 v6 v8 v9]
|
724 | [v0 v1 v5 v6 v8 v9][v0 v1 v5 v6 v8 v9]
|
725 | [][]
|
726 | [][]
|
727 | ==== ${a[@]:offset:length} ====
|
728 | [][]
|
729 | [v0][v0]
|
730 | [v0 v1 v5][v0 v1 v5]
|
731 | [v5][v5]
|
732 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
733 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
734 | [v5 v6 v8 v9][v5 v6 v8 v9]
|
735 | [][]
|
736 | [v9][v9]
|
737 | [v9][v9]
|
738 | [][]
|
739 | ## END
|
740 |
|
741 | ## N-I mksh STDOUT:
|
742 | ## END
|
743 |
|
744 |
|
745 | #### ${@:offset:length}
|
746 | case $SH in mksh) exit ;; esac
|
747 |
|
748 | set -- v{1..9}
|
749 |
|
750 | {
|
751 | echo '==== ${@:offset:length} ===='
|
752 | echo "[${*:0:3}][${*:0:3}]"
|
753 | echo "[${*:1:3}][${*:1:3}]"
|
754 | echo "[${*:3:3}][${*:3:3}]"
|
755 | echo "[${*:5:10}][${*:5:10}]"
|
756 |
|
757 | echo '==== ${@:negative} ===='
|
758 | echo "[${*: -1}][${*: -1}]"
|
759 | echo "[${*: -3}][${*: -3}]"
|
760 | echo "[${*: -9}][${*: -9}]"
|
761 | echo "[${*: -10}][${*: -10}]"
|
762 | echo "[${*: -11}][${*: -11}]"
|
763 | echo "[${*: -3:2}][${*: -3:2}]"
|
764 | echo "[${*: -9:4}][${*: -9:4}]"
|
765 | echo "[${*: -10:4}][${*: -10:4}]"
|
766 | echo "[${*: -11:4}][${*: -11:4}]"
|
767 | } | sed "s:$SH:\$SH:g;s:${SH##*/}:\$SH:g"
|
768 |
|
769 | ## STDOUT:
|
770 | ==== ${@:offset:length} ====
|
771 | [$SH v1 v2][$SH v1 v2]
|
772 | [v1 v2 v3][v1 v2 v3]
|
773 | [v3 v4 v5][v3 v4 v5]
|
774 | [v5 v6 v7 v8 v9][v5 v6 v7 v8 v9]
|
775 | ==== ${@:negative} ====
|
776 | [v9][v9]
|
777 | [v7 v8 v9][v7 v8 v9]
|
778 | [v1 v2 v3 v4 v5 v6 v7 v8 v9][v1 v2 v3 v4 v5 v6 v7 v8 v9]
|
779 | [$SH v1 v2 v3 v4 v5 v6 v7 v8 v9][$SH v1 v2 v3 v4 v5 v6 v7 v8 v9]
|
780 | [][]
|
781 | [v7 v8][v7 v8]
|
782 | [v1 v2 v3 v4][v1 v2 v3 v4]
|
783 | [$SH v1 v2 v3][$SH v1 v2 v3]
|
784 | [][]
|
785 | ## END
|
786 |
|
787 | ## N-I mksh STDOUT:
|
788 | ## END
|
789 |
|
790 |
|
791 | #### ${a[@]:BigInt}
|
792 | case $SH in mksh) exit ;; esac
|
793 |
|
794 | case $SH in
|
795 | bash)
|
796 | # disabled with soil-ovm-tarball image 2025-04-30b - the CI runs on Debian 12
|
797 | # now
|
798 | exit
|
799 |
|
800 | # Work around bash integer overflow bug that only happens on say Debian 10,
|
801 | # but NOT Debian 12. The bug exists in bash 5.2. It's unclear why it
|
802 | # depends on the OS version.
|
803 | v='/etc/debian_version'
|
804 | # debian version 10 / debian buster
|
805 | if test -f $v && grep -E 'buster/sid|^10' $v >/dev/null; then
|
806 | cat << 'EOF'
|
807 | [x][x]
|
808 | [y x][y x]
|
809 | [z y x][z y x]
|
810 | [z y x][z y x]
|
811 | EOF
|
812 | exit
|
813 | fi
|
814 | # Actual STDOUT of buggy bash builds:
|
815 | # [][]
|
816 | # [][]
|
817 | # [][]
|
818 | # [][]
|
819 | ;;
|
820 | esac
|
821 |
|
822 | a=(1 2 3)
|
823 | a[0x7FFFFFFFFFFFFFFF]=x
|
824 | a[0x7FFFFFFFFFFFFFFE]=y
|
825 | a[0x7FFFFFFFFFFFFFFD]=z
|
826 |
|
827 | echo "[${a[@]: -1}][${a[*]: -1}]"
|
828 | echo "[${a[@]: -2}][${a[*]: -2}]"
|
829 | echo "[${a[@]: -3}][${a[*]: -3}]"
|
830 | echo "[${a[@]: -4}][${a[*]: -4}]"
|
831 |
|
832 | ## STDOUT:
|
833 | [x][x]
|
834 | [y x][y x]
|
835 | [z y x][z y x]
|
836 | [z y x][z y x]
|
837 | ## END
|
838 |
|
839 | ## N-I mksh STDOUT:
|
840 | ## END
|
841 |
|
842 | ## BUG bash STDOUT:
|
843 | ## END
|
844 |
|
845 |
|
846 | #### ${a[@]}
|
847 | a=(v{0,1,2,3,4,5,6,7,8,9})
|
848 | unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
|
849 |
|
850 | argv.py "${a[@]}"
|
851 | argv.py "abc${a[@]}xyz"
|
852 |
|
853 | ## STDOUT:
|
854 | ['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
|
855 | ['abcv0', 'v1', 'v5', 'v6', 'v8', 'v9xyz']
|
856 | ## END
|
857 |
|
858 |
|
859 | #### ${a[@]#...}
|
860 | case $SH in mksh) exit ;; esac
|
861 |
|
862 | a=(v{0..9})
|
863 | unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
|
864 |
|
865 | argv.py "${a[@]#v}"
|
866 | argv.py "abc${a[@]#v}xyz"
|
867 | argv.py "${a[@]%[0-5]}"
|
868 | argv.py "abc${a[@]%[0-5]}xyz"
|
869 | argv.py "${a[@]#v?}"
|
870 |
|
871 | ## STDOUT:
|
872 | ['0', '1', '5', '6', '8', '9']
|
873 | ['abc0', '1', '5', '6', '8', '9xyz']
|
874 | ['v', 'v', 'v', 'v6', 'v8', 'v9']
|
875 | ['abcv', 'v', 'v', 'v6', 'v8', 'v9xyz']
|
876 | ['', '', '', '', '', '']
|
877 | ## END
|
878 |
|
879 | ## N-I mksh STDOUT:
|
880 | ## END
|
881 |
|
882 |
|
883 | #### ${a[@]/pat/rep}
|
884 |
|
885 | case $SH in mksh) exit ;; esac
|
886 |
|
887 | a=(v{0..9})
|
888 | unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
|
889 |
|
890 | argv.py "${a[@]/?}"
|
891 | argv.py "${a[@]//?}"
|
892 | argv.py "${a[@]/#?}"
|
893 | argv.py "${a[@]/%?}"
|
894 |
|
895 | argv.py "${a[@]/v/x}"
|
896 | argv.py "${a[@]//v/x}"
|
897 | argv.py "${a[@]/[0-5]/D}"
|
898 | argv.py "${a[@]//[!0-5]/_}"
|
899 |
|
900 | ## STDOUT:
|
901 | ['0', '1', '5', '6', '8', '9']
|
902 | ['', '', '', '', '', '']
|
903 | ['0', '1', '5', '6', '8', '9']
|
904 | ['v', 'v', 'v', 'v', 'v', 'v']
|
905 | ['x0', 'x1', 'x5', 'x6', 'x8', 'x9']
|
906 | ['x0', 'x1', 'x5', 'x6', 'x8', 'x9']
|
907 | ['vD', 'vD', 'vD', 'v6', 'v8', 'v9']
|
908 | ['_0', '_1', '_5', '__', '__', '__']
|
909 | ## END
|
910 |
|
911 | ## N-I mksh STDOUT:
|
912 | ## END
|
913 |
|
914 |
|
915 | #### ${a[@]@P}, ${a[@]@Q}, and ${a[@]@a}
|
916 | case $SH in mksh) exit ;; esac
|
917 |
|
918 | a=(v{0..9})
|
919 | unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
|
920 |
|
921 | argv.py "${a[@]@P}"
|
922 | argv.py "${a[*]@P}"
|
923 | argv.py "${a[@]@Q}"
|
924 | argv.py "${a[*]@Q}"
|
925 | argv.py "${a[@]@a}"
|
926 | argv.py "${a[*]@a}"
|
927 |
|
928 | ## STDOUT:
|
929 | ['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
|
930 | ['v0 v1 v5 v6 v8 v9']
|
931 | ['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
|
932 | ['v0 v1 v5 v6 v8 v9']
|
933 | ['a', 'a', 'a', 'a', 'a', 'a']
|
934 | ['a a a a a a']
|
935 | ## END
|
936 |
|
937 | ## OK bash STDOUT:
|
938 | ['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
|
939 | ['v0 v1 v5 v6 v8 v9']
|
940 | ["'v0'", "'v1'", "'v5'", "'v6'", "'v8'", "'v9'"]
|
941 | ["'v0' 'v1' 'v5' 'v6' 'v8' 'v9'"]
|
942 | ['a', 'a', 'a', 'a', 'a', 'a']
|
943 | ['a a a a a a']
|
944 | ## END
|
945 |
|
946 | ## N-I mksh STDOUT:
|
947 | ## END
|
948 |
|
949 |
|
950 | #### ${a[@]-unset}, ${a[@]:-empty}, etc.
|
951 | a1=()
|
952 | a2=("")
|
953 | a3=("" "")
|
954 |
|
955 | echo "a1 unset: [${a1[@]-unset}]"
|
956 | echo "a1 empty: [${a1[@]:-empty}]"
|
957 | echo "a2 unset: [${a2[@]-unset}]"
|
958 | echo "a2 empty: [${a2[@]:-empty}]"
|
959 | echo "a3 unset: [${a3[@]-unset}]"
|
960 | echo "a3 empty: [${a3[@]:-empty}]"
|
961 |
|
962 | ## STDOUT:
|
963 | a1 unset: [unset]
|
964 | a1 empty: [empty]
|
965 | a2 unset: []
|
966 | a2 empty: [empty]
|
967 | a3 unset: [ ]
|
968 | a3 empty: [ ]
|
969 | ## END
|
970 |
|
971 |
|
972 | #### ${a-}
|
973 | a1=()
|
974 | a2=("" "")
|
975 | a3=(foo bar)
|
976 |
|
977 | echo "$a1, ${a1-(unset)}, ${a1:-(empty)};"
|
978 | echo "$a2, ${a2-(unset)}, ${a2:-(empty)};"
|
979 | echo "$a3, ${a3-(unset)}, ${a3:-(empty)};"
|
980 |
|
981 | ## STDOUT:
|
982 | , (unset), (empty);
|
983 | , , (empty);
|
984 | foo, foo, foo;
|
985 | ## END
|
986 |
|
987 |
|
988 | #### ${!a[0]}
|
989 | case $SH in mksh) exit ;; esac
|
990 |
|
991 | v1=hello v2=world
|
992 | a=(v1 v2)
|
993 |
|
994 | echo "${!a[0]}, ${!a[1]}"
|
995 |
|
996 | ## STDOUT:
|
997 | hello, world
|
998 | ## END
|
999 |
|
1000 | ## N-I mksh STDOUT:
|
1001 | ## END
|
1002 |
|
1003 |
|
1004 | #### ${!a[@]}
|
1005 | case $SH in mksh) exit ;; esac
|
1006 |
|
1007 | a=(v{0..9})
|
1008 | unset -v 'a[3]' 'a[4]' 'a[7]' 'a[9]'
|
1009 |
|
1010 | argv.py "${!a[@]}"
|
1011 |
|
1012 | ## STDOUT:
|
1013 | ['0', '1', '2', '5', '6', '8']
|
1014 | ## END
|
1015 |
|
1016 | ## N-I mksh STDOUT:
|
1017 | ## END
|
1018 |
|
1019 |
|
1020 | #### "${a[*]}"
|
1021 | a=(v{0,1,2,3,4,5,6,7,8,9})
|
1022 | unset -v 'a[3]' 'a[4]' 'a[7]' 'a[9]'
|
1023 |
|
1024 | echo "${a[*]}"
|
1025 | IFS=
|
1026 | echo "${a[*]}"
|
1027 | IFS=/
|
1028 | echo "${a[*]}"
|
1029 |
|
1030 | ## STDOUT:
|
1031 | v0 v1 v2 v5 v6 v8
|
1032 | v0v1v2v5v6v8
|
1033 | v0/v1/v2/v5/v6/v8
|
1034 | ## END
|
1035 |
|
1036 |
|
1037 | #### compgen -F _set_COMPREPLY
|
1038 | case $SH in mksh) exit ;; esac
|
1039 |
|
1040 | _set_COMPREPLY() {
|
1041 | COMPREPLY=({0..9})
|
1042 | unset -v 'COMPREPLY[2]' 'COMPREPLY[4]' 'COMPREPLY[6]'
|
1043 | }
|
1044 |
|
1045 | compgen -F _set_COMPREPLY
|
1046 |
|
1047 | ## STDOUT:
|
1048 | 0
|
1049 | 1
|
1050 | 3
|
1051 | 5
|
1052 | 7
|
1053 | 8
|
1054 | 9
|
1055 | ## END
|
1056 |
|
1057 | ## N-I mksh STDOUT:
|
1058 | ## END
|
1059 |
|
1060 |
|
1061 | #### compadjust
|
1062 | case $SH in bash|mksh) exit ;; esac
|
1063 |
|
1064 | COMP_ARGV=(echo 'Hello,' 'Bash' 'world!')
|
1065 | compadjust cur prev words cword
|
1066 | argv.py "$cur" "$prev" "$cword"
|
1067 | argv.py "${words[@]}"
|
1068 |
|
1069 | ## STDOUT:
|
1070 | ['world!', 'Bash', '3']
|
1071 | ['echo', 'Hello,', 'Bash', 'world!']
|
1072 | ## END
|
1073 |
|
1074 | ## N-I bash/mksh STDOUT:
|
1075 | ## END
|
1076 |
|
1077 |
|
1078 | #### (YSH) @[sp] and @sp
|
1079 | case $SH in bash|mksh) exit ;; esac
|
1080 |
|
1081 | a=({0..5})
|
1082 | unset -v 'a[1]' 'a[2]' 'a[4]'
|
1083 |
|
1084 | shopt -s parse_at
|
1085 | argv.py @[a]
|
1086 | argv.py @a
|
1087 | ## STDOUT:
|
1088 | ['0', '3', '5']
|
1089 | ['0', '3', '5']
|
1090 | ## END
|
1091 |
|
1092 | ## N-I bash/mksh STDOUT:
|
1093 | ## END
|
1094 |
|
1095 |
|
1096 | #### (YSH) $[a1 === a2]
|
1097 | case $SH in bash|mksh) exit ;; esac
|
1098 |
|
1099 | a1=(1 2 3)
|
1100 | unset -v 'a1[1]'
|
1101 | a2=(1 2 3)
|
1102 | unset -v 'a2[1]'
|
1103 | a3=(1 2 4)
|
1104 | unset -v 'a3[1]'
|
1105 | a4=(1 2 3)
|
1106 |
|
1107 | echo $[a1 === a1]
|
1108 | echo $[a1 === a2]
|
1109 | echo $[a1 === a3]
|
1110 | echo $[a1 === a4]
|
1111 | echo $[a2 === a1]
|
1112 | echo $[a3 === a1]
|
1113 | echo $[a4 === a1]
|
1114 |
|
1115 | ## STDOUT:
|
1116 | true
|
1117 | true
|
1118 | false
|
1119 | false
|
1120 | true
|
1121 | false
|
1122 | false
|
1123 | ## END
|
1124 |
|
1125 | ## N-I bash/mksh STDOUT:
|
1126 | ## END
|
1127 |
|
1128 |
|
1129 | #### (YSH) append v1 v2... (a)
|
1130 | case $SH in bash|mksh) exit ;; esac
|
1131 |
|
1132 | a=(1 2 3)
|
1133 | unset -v 'a[1]'
|
1134 | append 'x' 'y' 'z' (a)
|
1135 | = a
|
1136 |
|
1137 | ## STDOUT:
|
1138 | (BashArray [0]='1' [2]='3' [3]='x' [4]='y' [5]='z')
|
1139 | ## END
|
1140 |
|
1141 | ## N-I bash/mksh STDOUT:
|
1142 | ## END
|
1143 |
|
1144 |
|
1145 | #### (YSH) $[bool(a)]
|
1146 | case $SH in bash|mksh) exit ;; esac
|
1147 |
|
1148 | a1=()
|
1149 | a2=(0)
|
1150 | a3=(0 1 2)
|
1151 | a4=(0 0)
|
1152 | unset -v 'a4[0]'
|
1153 |
|
1154 | echo $[bool(a1)]
|
1155 | echo $[bool(a2)]
|
1156 | echo $[bool(a3)]
|
1157 | echo $[bool(a4)]
|
1158 |
|
1159 | ## STDOUT:
|
1160 | false
|
1161 | true
|
1162 | true
|
1163 | true
|
1164 | ## END
|
1165 |
|
1166 | ## N-I bash/mksh STDOUT:
|
1167 | ## END
|
1168 |
|
1169 |
|
1170 | #### crash dump
|
1171 | case $SH in bash|mksh) exit ;; esac
|
1172 |
|
1173 | OILS_CRASH_DUMP_DIR=$TMP $SH -ec 'a=({0..3}); unset -v "a[2]"; false'
|
1174 | json read (&crash_dump) < $TMP/*.json
|
1175 | json write (crash_dump.var_stack[0].a)
|
1176 |
|
1177 | ## STDOUT:
|
1178 | {
|
1179 | "val": {
|
1180 | "type": "BashArray",
|
1181 | "data": {
|
1182 | "0": "0",
|
1183 | "1": "1",
|
1184 | "3": "3"
|
1185 | }
|
1186 | }
|
1187 | }
|
1188 | ## END
|
1189 |
|
1190 | ## N-I bash/mksh STDOUT:
|
1191 | ## END
|
1192 |
|
1193 |
|
1194 | #### Regression: a[-1]=1
|
1195 | case $SH in mksh) exit 99;; esac
|
1196 |
|
1197 | a[-1]=1
|
1198 |
|
1199 | ## status: 1
|
1200 | ## STDOUT:
|
1201 | ## END
|
1202 | ## STDERR:
|
1203 | a[-1]=1
|
1204 | ^~
|
1205 | [ stdin ]:3: fatal: Index %d is out of bounds for array of length 0
|
1206 | ## END
|
1207 | ## OK bash STDERR:
|
1208 | bash: line 3: a[-1]: bad array subscript
|
1209 | ## END
|
1210 | ## N-I mksh status: 99
|
1211 | ## N-I mksh stderr-json: ""
|
1212 |
|
1213 |
|
1214 | #### Initializing indexed array with ([index]=value)
|
1215 | case $SH in mksh) exit 99;; esac
|
1216 | declare -a a=([xx]=1 [yy]=2 [zz]=3)
|
1217 | echo status=$?
|
1218 | argv.py "${a[@]}"
|
1219 | ## STDOUT:
|
1220 | status=0
|
1221 | ['3']
|
1222 | ## END
|
1223 | ## N-I mksh status: 99
|
1224 | ## N-I mksh stdout-json: ""
|