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: ""