OILS / spec / ble-idioms.test.sh View on Github | oils.pub

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