OILS / spec / array-sparse.test.sh View on Github | oils.pub

1224 lines, 710 significant
1## compare_shells: bash mksh
2## oils_cpp_failures_allowed: 2
3
4#### Performance demo
5
6case $SH in bash|mksh) exit ;; esac
7
8#pp test_ (a)
9
10sp=( foo {25..27} bar )
11
12sp[10]='sparse'
13
14echo $[type(sp)]
15
16echo len: "${#sp[@]}"
17
18#echo $[len(sp)]
19
20shopt -s ysh:upgrade
21
22echo subst: "${sp[@]}"
23echo keys: "${!sp[@]}"
24
25echo slice: "${sp[@]:2:3}"
26
27sp[0]=set0
28
29echo get0: "${sp[0]}"
30echo get1: "${sp[1]}"
31echo ---
32
33to_append=(x y)
34echo append
35sp+=("${to_append[@]}")
36echo subst: "${sp[@]}"
37echo keys: "${!sp[@]}"
38echo ---
39
40echo unset
41unset -v 'sp[11]'
42echo subst: "${sp[@]}"
43echo keys: "${!sp[@]}"
44
45## STDOUT:
46BashArray
47len: 6
48subst: foo 25 26 27 bar sparse
49keys: 0 1 2 3 4 10
50slice: 26 27 bar
51get0: set0
52get1: 25
53---
54append
55subst: set0 25 26 27 bar sparse x y
56keys: 0 1 2 3 4 10 11 12
57---
58unset
59subst: set0 25 26 27 bar sparse y
60keys: 0 1 2 3 4 10 12
61## END
62
63## N-I bash/mksh STDOUT:
64## END
65
66
67#### test length
68sp=(x y z)
69
70sp[5]=z
71
72echo len=${#sp[@]}
73
74sp[10]=z
75
76echo len=${#sp[@]}
77
78## STDOUT:
79len=4
80len=5
81## END
82
83
84#### test "declare -p sp"
85a0=()
86a1=(1)
87a2=(1 2)
88a=(x y z w)
89a[500]=100
90a[1000]=100
91
92case $SH in
93bash|mksh)
94 typeset -p a0 a1 a2 a
95 exit ;;
96esac
97
98declare -p a0 a1 a2 a
99
100## STDOUT:
101declare -a a0=()
102declare -a a1=(1)
103declare -a a2=(1 2)
104declare -a a=([0]=x [1]=y [2]=z [3]=w [500]=100 [1000]=100)
105## END
106
107## OK bash STDOUT:
108declare -a a0=()
109declare -a a1=([0]="1")
110declare -a a2=([0]="1" [1]="2")
111declare -a a=([0]="x" [1]="y" [2]="z" [3]="w" [500]="100" [1000]="100")
112## END
113
114## OK mksh STDOUT:
115set -A a1
116typeset a1[0]=1
117set -A a2
118typeset a2[0]=1
119typeset a2[1]=2
120set -A a
121typeset a[0]=x
122typeset a[1]=y
123typeset a[2]=z
124typeset a[3]=w
125typeset a[500]=100
126typeset a[1000]=100
127## END
128
129#### +=
130sp1[10]=a
131sp1[20]=b
132sp1[99]=c
133typeset -p sp1 | sed 's/"//g'
134sp1+=(1 2 3)
135typeset -p sp1 | sed 's/"//g'
136
137## STDOUT:
138declare -a sp1=([10]=a [20]=b [99]=c)
139declare -a sp1=([10]=a [20]=b [99]=c [100]=1 [101]=2 [102]=3)
140## END
141
142
143## OK mksh STDOUT:
144set -A sp1
145typeset sp1[10]=a
146typeset sp1[20]=b
147typeset sp1[99]=c
148set -A sp1
149typeset sp1[10]=a
150typeset sp1[20]=b
151typeset sp1[99]=c
152typeset sp1[100]=1
153typeset sp1[101]=2
154typeset sp1[102]=3
155## END
156
157
158#### a[i]=v
159sp1[10]=a
160sp1[20]=b
161sp1[30]=c
162typeset -p sp1 | sed 's/"//g'
163sp1[10]=X
164sp1[25]=Y
165sp1[90]=Z
166typeset -p sp1 | sed 's/"//g'
167
168## STDOUT:
169declare -a sp1=([10]=a [20]=b [30]=c)
170declare -a sp1=([10]=X [20]=b [25]=Y [30]=c [90]=Z)
171## END
172
173## OK mksh STDOUT:
174set -A sp1
175typeset sp1[10]=a
176typeset sp1[20]=b
177typeset sp1[30]=c
178set -A sp1
179typeset sp1[10]=X
180typeset sp1[20]=b
181typeset sp1[25]=Y
182typeset sp1[30]=c
183typeset sp1[90]=Z
184## END
185
186
187#### Negative index with a[i]=v
188case $SH in mksh) exit ;; esac
189
190sp1[9]=x
191typeset -p sp1 | sed 's/"//g'
192
193sp1[-1]=A
194sp1[-4]=B
195sp1[-8]=C
196sp1[-10]=D
197typeset -p sp1 | sed 's/"//g'
198
199## STDOUT:
200declare -a sp1=([9]=x)
201declare -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
209case $SH in mksh) exit ;; esac
210
211sp1[1]=x
212sp1[5]=y
213sp1[9]=z
214
215echo "${#sp1[@]}"
216sp1[0x7FFFFFFFFFFFFFFF]=a
217echo "${#sp1[@]}"
218sp1[0x7FFFFFFFFFFFFFFE]=b
219echo "${#sp1[@]}"
220sp1[0x7FFFFFFFFFFFFFFD]=c
221echo "${#sp1[@]}"
222
223## STDOUT:
2243
2254
2265
2276
228## END
229
230## N-I mksh STDOUT:
231## END
232
233
234#### Negative out-of-bound index with a[i]=v (1/2)
235case $SH in mksh) exit ;; esac
236
237sp1[9]=x
238sp1[-11]=E
239declare -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:
252declare -a sp1=([9]="x")
253## END
254## OK bash STDERR:
255bash: 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)
264case $SH in mksh) exit ;; esac
265
266sp1[9]=x
267
268sp1[-21]=F
269declare -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:
282declare -a sp1=([9]="x")
283## END
284## OK bash STDERR:
285bash: 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
296sp1=(1)
297set -x
298sp1+=(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]
310a=(1 2 3 4 5 6 7 8 9)
311typeset -p a
312unset -v "a[1]"
313typeset -p a
314unset -v "a[9]"
315typeset -p a
316unset -v "a[0]"
317typeset -p a
318
319## STDOUT:
320declare -a a=(1 2 3 4 5 6 7 8 9)
321declare -a a=([0]=1 [2]=3 [3]=4 [4]=5 [5]=6 [6]=7 [7]=8 [8]=9)
322declare -a a=([0]=1 [2]=3 [3]=4 [4]=5 [5]=6 [6]=7 [7]=8 [8]=9)
323declare -a a=([2]=3 [3]=4 [4]=5 [5]=6 [6]=7 [7]=8 [8]=9)
324## END
325
326## OK bash STDOUT:
327declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
328declare -a a=([0]="1" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
329declare -a a=([0]="1" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
330declare -a a=([2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")
331## END
332
333## OK mksh STDOUT:
334set -A a
335typeset a[0]=1
336typeset a[1]=2
337typeset a[2]=3
338typeset a[3]=4
339typeset a[4]=5
340typeset a[5]=6
341typeset a[6]=7
342typeset a[7]=8
343typeset a[8]=9
344set -A a
345typeset a[0]=1
346typeset a[2]=3
347typeset a[3]=4
348typeset a[4]=5
349typeset a[5]=6
350typeset a[6]=7
351typeset a[7]=8
352typeset a[8]=9
353set -A a
354typeset a[0]=1
355typeset a[2]=3
356typeset a[3]=4
357typeset a[4]=5
358typeset a[5]=6
359typeset a[6]=7
360typeset a[7]=8
361typeset a[8]=9
362set -A a
363typeset a[2]=3
364typeset a[3]=4
365typeset a[4]=5
366typeset a[5]=6
367typeset a[6]=7
368typeset a[7]=8
369typeset a[8]=9
370## END
371
372
373#### unset -v a[i] with out-of-bound negative index
374case $SH in mksh) exit ;; esac
375
376a=(1)
377
378unset -v "a[-2]"
379unset -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:
394bash: line 5: unset: [-2]: bad array subscript
395bash: 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
404case $SH in mksh) exit ;; esac
405
406a=({1..9})
407unset -v 'a[-1]'
408a[-1]=x
409declare -p a
410unset -v 'a[-1]'
411a[-1]=x
412declare -p a
413
414## STDOUT:
415declare -a a=(1 2 3 4 5 6 7 x)
416declare -a a=(1 2 3 4 5 6 x)
417## END
418
419## OK bash STDOUT:
420declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="x")
421declare -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] ]]
429case $SH in mksh) exit ;; esac
430
431sp1=()
432[[ -v sp1[0] ]]; echo "$? (expect 1)"
433[[ -v sp1[9] ]]; echo "$? (expect 1)"
434
435sp2=({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
443sp3=({1..9})
444unset -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:
4551 (expect 1)
4561 (expect 1)
4570 (expect 0)
4580 (expect 0)
4591 (expect 1)
4600 (expect 0)
4610 (expect 0)
4620 (expect 0)
4630 (expect 0)
4641 (expect 1)
4650 (expect 0)
4660 (expect 0)
4670 (expect 0)
4681 (expect 1)
4690 (expect 0)
4700 (expect 0)
471## END
472
473## N-I mksh STDOUT:
474## END
475
476
477#### [[ -v a[i] ]] with invalid negative index
478case $SH in mksh) exit ;; esac
479
480sp1=()
481([[ -v sp1[-1] ]]; echo "$? (expect 1)")
482sp2=({1..9})
483([[ -v sp2[-10] ]]; echo "$? (expect 1)")
484sp3=({1..9})
485unset -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:
5051 (expect 1)
5061 (expect 1)
5071 (expect 1)
508## END
509## OK bash STDERR:
510bash: line 4: sp1: bad array subscript
511bash: line 6: sp2: bad array subscript
512bash: 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]++))
521a=(1 2 3 4 5 6 7 8 9)
522unset -v 'a[2]' 'a[3]' 'a[7]'
523
524echo $((a[0]))
525echo $((a[1]))
526echo $((a[2]))
527echo $((a[3]))
528echo $((a[7]))
529
530echo $((a[1]++))
531echo $((a[2]++))
532echo $((a[3]++))
533echo $((a[7]++))
534
535echo $((++a[1]))
536echo $((++a[2]))
537echo $((++a[3]))
538echo $((++a[7]))
539
540echo $((a[1] = 100, a[1]))
541echo $((a[2] = 100, a[2]))
542echo $((a[3] = 100, a[3]))
543echo $((a[7] = 100, a[7]))
544
545## STDOUT:
5461
5472
5480
5490
5500
5512
5520
5530
5540
5554
5562
5572
5582
559100
560100
561100
562100
563## END
564
565
566#### ((sp[i])) and ((sp[i]++)) with invalid negative index
567case $SH in mksh) exit ;; esac
568
569a=({1..9})
570unset -v 'a[2]' 'a[3]' 'a[7]'
571
572echo $((a[-10]))
573
574## STDOUT:
5750
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:
584bash: 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]}
594case $SH in mksh) exit ;; esac
595
596sp=({1..9})
597unset -v 'sp[2]'
598unset -v 'sp[3]'
599unset -v 'sp[7]'
600
601echo "sp[0]: '${sp[0]}', ${sp[0]:-(empty)}, ${sp[0]+set}."
602echo "sp[1]: '${sp[1]}', ${sp[1]:-(empty)}, ${sp[1]+set}."
603echo "sp[8]: '${sp[8]}', ${sp[8]:-(empty)}, ${sp[8]+set}."
604echo "sp[2]: '${sp[2]}', ${sp[2]:-(empty)}, ${sp[2]+set}."
605echo "sp[3]: '${sp[3]}', ${sp[3]:-(empty)}, ${sp[3]+set}."
606echo "sp[7]: '${sp[7]}', ${sp[7]:-(empty)}, ${sp[7]+set}."
607
608echo "sp[-1]: '${sp[-1]}'."
609echo "sp[-2]: '${sp[-2]}'."
610echo "sp[-3]: '${sp[-3]}'."
611echo "sp[-4]: '${sp[-4]}'."
612echo "sp[-9]: '${sp[-9]}'."
613
614## STDOUT:
615sp[0]: '1', 1, set.
616sp[1]: '2', 2, set.
617sp[8]: '9', 9, set.
618sp[2]: '', (empty), .
619sp[3]: '', (empty), .
620sp[7]: '', (empty), .
621sp[-1]: '9'.
622sp[-2]: ''.
623sp[-3]: '7'.
624sp[-4]: '6'.
625sp[-9]: '1'.
626## END
627
628## N-I mksh STDOUT:
629## END
630
631
632#### ${sp[i]} with negative invalid index
633case $SH in mksh) exit ;; esac
634
635sp=({1..9})
636unset -v 'sp[2]'
637unset -v 'sp[3]'
638unset -v 'sp[7]'
639
640echo "sp[-10]: '${sp[-10]}'."
641echo "sp[-11]: '${sp[-11]}'."
642echo "sp[-19]: '${sp[-19]}'."
643
644## STDOUT:
645sp[-10]: ''.
646sp[-11]: ''.
647sp[-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:
662bash: line 8: sp: bad array subscript
663bash: line 9: sp: bad array subscript
664bash: 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}
674case $SH in mksh) exit ;; esac
675
676a=(v{0..9})
677unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
678
679echo '==== ${a[@]:offset} ===='
680echo "[${a[@]:0}][${a[*]:0}]"
681echo "[${a[@]:2}][${a[*]:2}]"
682echo "[${a[@]:3}][${a[*]:3}]"
683echo "[${a[@]:5}][${a[*]:5}]"
684echo "[${a[@]:9}][${a[*]:9}]"
685echo "[${a[@]:10}][${a[*]:10}]"
686echo "[${a[@]:11}][${a[*]:11}]"
687
688echo '==== ${a[@]:negative} ===='
689echo "[${a[@]: -1}][${a[*]: -1}]"
690echo "[${a[@]: -2}][${a[*]: -2}]"
691echo "[${a[@]: -5}][${a[*]: -5}]"
692echo "[${a[@]: -9}][${a[*]: -9}]"
693echo "[${a[@]: -10}][${a[*]: -10}]"
694echo "[${a[@]: -11}][${a[*]: -11}]"
695echo "[${a[@]: -21}][${a[*]: -21}]"
696
697echo '==== ${a[@]:offset:length} ===='
698echo "[${a[@]:0:0}][${a[*]:0:0}]"
699echo "[${a[@]:0:1}][${a[*]:0:1}]"
700echo "[${a[@]:0:3}][${a[*]:0:3}]"
701echo "[${a[@]:2:1}][${a[*]:2:1}]"
702echo "[${a[@]:2:4}][${a[*]:2:4}]"
703echo "[${a[@]:3:4}][${a[*]:3:4}]"
704echo "[${a[@]:5:4}][${a[*]:5:4}]"
705echo "[${a[@]:5:0}][${a[*]:5:0}]"
706echo "[${a[@]:9:1}][${a[*]:9:1}]"
707echo "[${a[@]:9:2}][${a[*]:9:2}]"
708echo "[${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}
746case $SH in mksh) exit ;; esac
747
748set -- 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}
792case $SH in mksh) exit ;; esac
793
794case $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]
811EOF
812 exit
813 fi
814 # Actual STDOUT of buggy bash builds:
815 # [][]
816 # [][]
817 # [][]
818 # [][]
819 ;;
820esac
821
822a=(1 2 3)
823a[0x7FFFFFFFFFFFFFFF]=x
824a[0x7FFFFFFFFFFFFFFE]=y
825a[0x7FFFFFFFFFFFFFFD]=z
826
827echo "[${a[@]: -1}][${a[*]: -1}]"
828echo "[${a[@]: -2}][${a[*]: -2}]"
829echo "[${a[@]: -3}][${a[*]: -3}]"
830echo "[${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[@]}
847a=(v{0,1,2,3,4,5,6,7,8,9})
848unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
849
850argv.py "${a[@]}"
851argv.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[@]#...}
860case $SH in mksh) exit ;; esac
861
862a=(v{0..9})
863unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
864
865argv.py "${a[@]#v}"
866argv.py "abc${a[@]#v}xyz"
867argv.py "${a[@]%[0-5]}"
868argv.py "abc${a[@]%[0-5]}xyz"
869argv.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
885case $SH in mksh) exit ;; esac
886
887a=(v{0..9})
888unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
889
890argv.py "${a[@]/?}"
891argv.py "${a[@]//?}"
892argv.py "${a[@]/#?}"
893argv.py "${a[@]/%?}"
894
895argv.py "${a[@]/v/x}"
896argv.py "${a[@]//v/x}"
897argv.py "${a[@]/[0-5]/D}"
898argv.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}
916case $SH in mksh) exit ;; esac
917
918a=(v{0..9})
919unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
920
921argv.py "${a[@]@P}"
922argv.py "${a[*]@P}"
923argv.py "${a[@]@Q}"
924argv.py "${a[*]@Q}"
925argv.py "${a[@]@a}"
926argv.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.
951a1=()
952a2=("")
953a3=("" "")
954
955echo "a1 unset: [${a1[@]-unset}]"
956echo "a1 empty: [${a1[@]:-empty}]"
957echo "a2 unset: [${a2[@]-unset}]"
958echo "a2 empty: [${a2[@]:-empty}]"
959echo "a3 unset: [${a3[@]-unset}]"
960echo "a3 empty: [${a3[@]:-empty}]"
961
962## STDOUT:
963a1 unset: [unset]
964a1 empty: [empty]
965a2 unset: []
966a2 empty: [empty]
967a3 unset: [ ]
968a3 empty: [ ]
969## END
970
971
972#### ${a-}
973a1=()
974a2=("" "")
975a3=(foo bar)
976
977echo "$a1, ${a1-(unset)}, ${a1:-(empty)};"
978echo "$a2, ${a2-(unset)}, ${a2:-(empty)};"
979echo "$a3, ${a3-(unset)}, ${a3:-(empty)};"
980
981## STDOUT:
982, (unset), (empty);
983, , (empty);
984foo, foo, foo;
985## END
986
987
988#### ${!a[0]}
989case $SH in mksh) exit ;; esac
990
991v1=hello v2=world
992a=(v1 v2)
993
994echo "${!a[0]}, ${!a[1]}"
995
996## STDOUT:
997hello, world
998## END
999
1000## N-I mksh STDOUT:
1001## END
1002
1003
1004#### ${!a[@]}
1005case $SH in mksh) exit ;; esac
1006
1007a=(v{0..9})
1008unset -v 'a[3]' 'a[4]' 'a[7]' 'a[9]'
1009
1010argv.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[*]}"
1021a=(v{0,1,2,3,4,5,6,7,8,9})
1022unset -v 'a[3]' 'a[4]' 'a[7]' 'a[9]'
1023
1024echo "${a[*]}"
1025IFS=
1026echo "${a[*]}"
1027IFS=/
1028echo "${a[*]}"
1029
1030## STDOUT:
1031v0 v1 v2 v5 v6 v8
1032v0v1v2v5v6v8
1033v0/v1/v2/v5/v6/v8
1034## END
1035
1036
1037#### compgen -F _set_COMPREPLY
1038case $SH in mksh) exit ;; esac
1039
1040_set_COMPREPLY() {
1041 COMPREPLY=({0..9})
1042 unset -v 'COMPREPLY[2]' 'COMPREPLY[4]' 'COMPREPLY[6]'
1043}
1044
1045compgen -F _set_COMPREPLY
1046
1047## STDOUT:
10480
10491
10503
10515
10527
10538
10549
1055## END
1056
1057## N-I mksh STDOUT:
1058## END
1059
1060
1061#### compadjust
1062case $SH in bash|mksh) exit ;; esac
1063
1064COMP_ARGV=(echo 'Hello,' 'Bash' 'world!')
1065compadjust cur prev words cword
1066argv.py "$cur" "$prev" "$cword"
1067argv.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
1079case $SH in bash|mksh) exit ;; esac
1080
1081a=({0..5})
1082unset -v 'a[1]' 'a[2]' 'a[4]'
1083
1084shopt -s parse_at
1085argv.py @[a]
1086argv.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]
1097case $SH in bash|mksh) exit ;; esac
1098
1099a1=(1 2 3)
1100unset -v 'a1[1]'
1101a2=(1 2 3)
1102unset -v 'a2[1]'
1103a3=(1 2 4)
1104unset -v 'a3[1]'
1105a4=(1 2 3)
1106
1107echo $[a1 === a1]
1108echo $[a1 === a2]
1109echo $[a1 === a3]
1110echo $[a1 === a4]
1111echo $[a2 === a1]
1112echo $[a3 === a1]
1113echo $[a4 === a1]
1114
1115## STDOUT:
1116true
1117true
1118false
1119false
1120true
1121false
1122false
1123## END
1124
1125## N-I bash/mksh STDOUT:
1126## END
1127
1128
1129#### (YSH) append v1 v2... (a)
1130case $SH in bash|mksh) exit ;; esac
1131
1132a=(1 2 3)
1133unset -v 'a[1]'
1134append '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)]
1146case $SH in bash|mksh) exit ;; esac
1147
1148a1=()
1149a2=(0)
1150a3=(0 1 2)
1151a4=(0 0)
1152unset -v 'a4[0]'
1153
1154echo $[bool(a1)]
1155echo $[bool(a2)]
1156echo $[bool(a3)]
1157echo $[bool(a4)]
1158
1159## STDOUT:
1160false
1161true
1162true
1163true
1164## END
1165
1166## N-I bash/mksh STDOUT:
1167## END
1168
1169
1170#### crash dump
1171case $SH in bash|mksh) exit ;; esac
1172
1173OILS_CRASH_DUMP_DIR=$TMP $SH -ec 'a=({0..3}); unset -v "a[2]"; false'
1174json read (&crash_dump) < $TMP/*.json
1175json 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
1195case $SH in mksh) exit 99;; esac
1196
1197a[-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:
1208bash: 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)
1215case $SH in mksh) exit 99;; esac
1216declare -a a=([xx]=1 [yy]=2 [zz]=3)
1217echo status=$?
1218argv.py "${a[@]}"
1219## STDOUT:
1220status=0
1221['3']
1222## END
1223## N-I mksh status: 99
1224## N-I mksh stdout-json: ""