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

1219 lines, 709 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 # disabled with soil-ovm-tarball image 2025-04-30b - the CI runs on Debian 12
796 # now
797 DISABLED-bash)
798 # Work around bash integer overflow bug that only happens on say Debian 10,
799 # but NOT Debian 12. The bug exists in bash 5.2. It's unclear why it
800 # depends on the OS version.
801 v='/etc/debian_version'
802 # debian version 10 / debian buster
803 if test -f $v && grep -E 'buster/sid|^10' $v >/dev/null; then
804 cat << 'EOF'
805[x][x]
806[y x][y x]
807[z y x][z y x]
808[z y x][z y x]
809EOF
810 exit
811 fi
812 # Actual STDOUT of buggy bash builds:
813 # [][]
814 # [][]
815 # [][]
816 # [][]
817 ;;
818esac
819
820a=(1 2 3)
821a[0x7FFFFFFFFFFFFFFF]=x
822a[0x7FFFFFFFFFFFFFFE]=y
823a[0x7FFFFFFFFFFFFFFD]=z
824
825echo "[${a[@]: -1}][${a[*]: -1}]"
826echo "[${a[@]: -2}][${a[*]: -2}]"
827echo "[${a[@]: -3}][${a[*]: -3}]"
828echo "[${a[@]: -4}][${a[*]: -4}]"
829
830## STDOUT:
831[x][x]
832[y x][y x]
833[z y x][z y x]
834[z y x][z y x]
835## END
836
837## N-I mksh STDOUT:
838## END
839
840
841#### ${a[@]}
842a=(v{0,1,2,3,4,5,6,7,8,9})
843unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
844
845argv.py "${a[@]}"
846argv.py "abc${a[@]}xyz"
847
848## STDOUT:
849['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
850['abcv0', 'v1', 'v5', 'v6', 'v8', 'v9xyz']
851## END
852
853
854#### ${a[@]#...}
855case $SH in mksh) exit ;; esac
856
857a=(v{0..9})
858unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
859
860argv.py "${a[@]#v}"
861argv.py "abc${a[@]#v}xyz"
862argv.py "${a[@]%[0-5]}"
863argv.py "abc${a[@]%[0-5]}xyz"
864argv.py "${a[@]#v?}"
865
866## STDOUT:
867['0', '1', '5', '6', '8', '9']
868['abc0', '1', '5', '6', '8', '9xyz']
869['v', 'v', 'v', 'v6', 'v8', 'v9']
870['abcv', 'v', 'v', 'v6', 'v8', 'v9xyz']
871['', '', '', '', '', '']
872## END
873
874## N-I mksh STDOUT:
875## END
876
877
878#### ${a[@]/pat/rep}
879
880case $SH in mksh) exit ;; esac
881
882a=(v{0..9})
883unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
884
885argv.py "${a[@]/?}"
886argv.py "${a[@]//?}"
887argv.py "${a[@]/#?}"
888argv.py "${a[@]/%?}"
889
890argv.py "${a[@]/v/x}"
891argv.py "${a[@]//v/x}"
892argv.py "${a[@]/[0-5]/D}"
893argv.py "${a[@]//[!0-5]/_}"
894
895## STDOUT:
896['0', '1', '5', '6', '8', '9']
897['', '', '', '', '', '']
898['0', '1', '5', '6', '8', '9']
899['v', 'v', 'v', 'v', 'v', 'v']
900['x0', 'x1', 'x5', 'x6', 'x8', 'x9']
901['x0', 'x1', 'x5', 'x6', 'x8', 'x9']
902['vD', 'vD', 'vD', 'v6', 'v8', 'v9']
903['_0', '_1', '_5', '__', '__', '__']
904## END
905
906## N-I mksh STDOUT:
907## END
908
909
910#### ${a[@]@P}, ${a[@]@Q}, and ${a[@]@a}
911case $SH in mksh) exit ;; esac
912
913a=(v{0..9})
914unset -v 'a[2]' 'a[3]' 'a[4]' 'a[7]'
915
916argv.py "${a[@]@P}"
917argv.py "${a[*]@P}"
918argv.py "${a[@]@Q}"
919argv.py "${a[*]@Q}"
920argv.py "${a[@]@a}"
921argv.py "${a[*]@a}"
922
923## STDOUT:
924['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
925['v0 v1 v5 v6 v8 v9']
926['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
927['v0 v1 v5 v6 v8 v9']
928['a', 'a', 'a', 'a', 'a', 'a']
929['a a a a a a']
930## END
931
932## OK bash STDOUT:
933['v0', 'v1', 'v5', 'v6', 'v8', 'v9']
934['v0 v1 v5 v6 v8 v9']
935["'v0'", "'v1'", "'v5'", "'v6'", "'v8'", "'v9'"]
936["'v0' 'v1' 'v5' 'v6' 'v8' 'v9'"]
937['a', 'a', 'a', 'a', 'a', 'a']
938['a a a a a a']
939## END
940
941## N-I mksh STDOUT:
942## END
943
944
945#### ${a[@]-unset}, ${a[@]:-empty}, etc.
946a1=()
947a2=("")
948a3=("" "")
949
950echo "a1 unset: [${a1[@]-unset}]"
951echo "a1 empty: [${a1[@]:-empty}]"
952echo "a2 unset: [${a2[@]-unset}]"
953echo "a2 empty: [${a2[@]:-empty}]"
954echo "a3 unset: [${a3[@]-unset}]"
955echo "a3 empty: [${a3[@]:-empty}]"
956
957## STDOUT:
958a1 unset: [unset]
959a1 empty: [empty]
960a2 unset: []
961a2 empty: [empty]
962a3 unset: [ ]
963a3 empty: [ ]
964## END
965
966
967#### ${a-}
968a1=()
969a2=("" "")
970a3=(foo bar)
971
972echo "$a1, ${a1-(unset)}, ${a1:-(empty)};"
973echo "$a2, ${a2-(unset)}, ${a2:-(empty)};"
974echo "$a3, ${a3-(unset)}, ${a3:-(empty)};"
975
976## STDOUT:
977, (unset), (empty);
978, , (empty);
979foo, foo, foo;
980## END
981
982
983#### ${!a[0]}
984case $SH in mksh) exit ;; esac
985
986v1=hello v2=world
987a=(v1 v2)
988
989echo "${!a[0]}, ${!a[1]}"
990
991## STDOUT:
992hello, world
993## END
994
995## N-I mksh STDOUT:
996## END
997
998
999#### ${!a[@]}
1000case $SH in mksh) exit ;; esac
1001
1002a=(v{0..9})
1003unset -v 'a[3]' 'a[4]' 'a[7]' 'a[9]'
1004
1005argv.py "${!a[@]}"
1006
1007## STDOUT:
1008['0', '1', '2', '5', '6', '8']
1009## END
1010
1011## N-I mksh STDOUT:
1012## END
1013
1014
1015#### "${a[*]}"
1016a=(v{0,1,2,3,4,5,6,7,8,9})
1017unset -v 'a[3]' 'a[4]' 'a[7]' 'a[9]'
1018
1019echo "${a[*]}"
1020IFS=
1021echo "${a[*]}"
1022IFS=/
1023echo "${a[*]}"
1024
1025## STDOUT:
1026v0 v1 v2 v5 v6 v8
1027v0v1v2v5v6v8
1028v0/v1/v2/v5/v6/v8
1029## END
1030
1031
1032#### compgen -F _set_COMPREPLY
1033case $SH in mksh) exit ;; esac
1034
1035_set_COMPREPLY() {
1036 COMPREPLY=({0..9})
1037 unset -v 'COMPREPLY[2]' 'COMPREPLY[4]' 'COMPREPLY[6]'
1038}
1039
1040compgen -F _set_COMPREPLY
1041
1042## STDOUT:
10430
10441
10453
10465
10477
10488
10499
1050## END
1051
1052## N-I mksh STDOUT:
1053## END
1054
1055
1056#### compadjust
1057case $SH in bash|mksh) exit ;; esac
1058
1059COMP_ARGV=(echo 'Hello,' 'Bash' 'world!')
1060compadjust cur prev words cword
1061argv.py "$cur" "$prev" "$cword"
1062argv.py "${words[@]}"
1063
1064## STDOUT:
1065['world!', 'Bash', '3']
1066['echo', 'Hello,', 'Bash', 'world!']
1067## END
1068
1069## N-I bash/mksh STDOUT:
1070## END
1071
1072
1073#### (YSH) @[sp] and @sp
1074case $SH in bash|mksh) exit ;; esac
1075
1076a=({0..5})
1077unset -v 'a[1]' 'a[2]' 'a[4]'
1078
1079shopt -s parse_at
1080argv.py @[a]
1081argv.py @a
1082## STDOUT:
1083['0', '3', '5']
1084['0', '3', '5']
1085## END
1086
1087## N-I bash/mksh STDOUT:
1088## END
1089
1090
1091#### (YSH) $[a1 === a2]
1092case $SH in bash|mksh) exit ;; esac
1093
1094a1=(1 2 3)
1095unset -v 'a1[1]'
1096a2=(1 2 3)
1097unset -v 'a2[1]'
1098a3=(1 2 4)
1099unset -v 'a3[1]'
1100a4=(1 2 3)
1101
1102echo $[a1 === a1]
1103echo $[a1 === a2]
1104echo $[a1 === a3]
1105echo $[a1 === a4]
1106echo $[a2 === a1]
1107echo $[a3 === a1]
1108echo $[a4 === a1]
1109
1110## STDOUT:
1111true
1112true
1113false
1114false
1115true
1116false
1117false
1118## END
1119
1120## N-I bash/mksh STDOUT:
1121## END
1122
1123
1124#### (YSH) append v1 v2... (a)
1125case $SH in bash|mksh) exit ;; esac
1126
1127a=(1 2 3)
1128unset -v 'a[1]'
1129append 'x' 'y' 'z' (a)
1130= a
1131
1132## STDOUT:
1133(BashArray [0]='1' [2]='3' [3]='x' [4]='y' [5]='z')
1134## END
1135
1136## N-I bash/mksh STDOUT:
1137## END
1138
1139
1140#### (YSH) $[bool(a)]
1141case $SH in bash|mksh) exit ;; esac
1142
1143a1=()
1144a2=(0)
1145a3=(0 1 2)
1146a4=(0 0)
1147unset -v 'a4[0]'
1148
1149echo $[bool(a1)]
1150echo $[bool(a2)]
1151echo $[bool(a3)]
1152echo $[bool(a4)]
1153
1154## STDOUT:
1155false
1156true
1157true
1158true
1159## END
1160
1161## N-I bash/mksh STDOUT:
1162## END
1163
1164
1165#### crash dump
1166case $SH in bash|mksh) exit ;; esac
1167
1168OILS_CRASH_DUMP_DIR=$TMP $SH -ec 'a=({0..3}); unset -v "a[2]"; false'
1169json read (&crash_dump) < $TMP/*.json
1170json write (crash_dump.var_stack[0].a)
1171
1172## STDOUT:
1173{
1174 "val": {
1175 "type": "BashArray",
1176 "data": {
1177 "0": "0",
1178 "1": "1",
1179 "3": "3"
1180 }
1181 }
1182}
1183## END
1184
1185## N-I bash/mksh STDOUT:
1186## END
1187
1188
1189#### Regression: a[-1]=1
1190case $SH in mksh) exit 99;; esac
1191
1192a[-1]=1
1193
1194## status: 1
1195## STDOUT:
1196## END
1197## STDERR:
1198 a[-1]=1
1199 ^~
1200[ stdin ]:3: fatal: Index %d is out of bounds for array of length 0
1201## END
1202## OK bash STDERR:
1203bash: line 3: a[-1]: bad array subscript
1204## END
1205## N-I mksh status: 99
1206## N-I mksh stderr-json: ""
1207
1208
1209#### Initializing indexed array with ([index]=value)
1210case $SH in mksh) exit 99;; esac
1211declare -a a=([xx]=1 [yy]=2 [zz]=3)
1212echo status=$?
1213argv.py "${a[@]}"
1214## STDOUT:
1215status=0
1216['3']
1217## END
1218## N-I mksh status: 99
1219## N-I mksh stdout-json: ""