OILS / spec / ble-idioms.test.sh View on Github | oilshell.org

355 lines, 190 significant
1
2#### recursive arith: one level
3a='b=123'
4echo $((a))
5## stdout: 123
6## N-I dash status: 2
7## N-I dash stdout-json: ""
8## N-I yash stdout: b=123
9
10#### recursive arith: two levels
11a='b=c' c='d=123'
12echo $((a))
13## stdout: 123
14## N-I dash status: 2
15## N-I dash stdout-json: ""
16## N-I yash stdout: b=c
17
18#### recursive arith: short circuit &&, ||
19# Note: mksh R52 has a bug. Even though it supports a short circuit like
20# "echo $((cond&&(a=1)))", it doesn't work with "x=a=1; echo
21# $((cond&&x))". It is fixed at least in mksh R57.
22# Note: "busybox sh" doesn't support short circuit.
23a=b=123
24echo $((1||a)):$((b))
25echo $((0||a)):$((b))
26c=d=321
27echo $((0&&c)):$((d))
28echo $((1&&c)):$((d))
29## STDOUT:
301:0
311:123
320:0
331:321
34## END
35
36## BUG mksh/ash STDOUT:
371:123
381:123
390:321
401:321
41## END
42
43## N-I dash/yash status: 2
44## N-I dash/yash STDOUT:
451:0
46## END
47
48#### recursive arith: short circuit ?:
49# Note: "busybox sh" behaves strangely.
50y=a=123 n=a=321
51echo $((1?(y):(n))):$((a))
52echo $((0?(y):(n))):$((a))
53## STDOUT:
54123:123
55321:321
56## END
57## BUG ash STDOUT:
58123:321
59321:321
60## END
61## N-I dash status: 2
62## N-I dash stdout-json: ""
63## N-I yash STDOUT:
64a=123:0
65a=321:0
66## END
67
68#### recursive arith: side effects
69# In Zsh and Busybox sh, the side effect of inner arithmetic
70# evaluations seems to take effect only after the whole evaluation.
71a='b=c' c='d=123'
72echo $((a,d)):$((d))
73## stdout: 123:123
74## BUG zsh/ash stdout: 0:123
75## N-I dash/yash status: 2
76## N-I dash/yash stdout-json: ""
77
78#### recursive arith: recursion
79loop='i<=100&&(s+=i,i++,loop)' s=0 i=0
80echo $((a=loop,s))
81## stdout: 5050
82## N-I mksh status: 1
83## N-I mksh stdout-json: ""
84## N-I ash/dash/yash status: 2
85## N-I ash/dash/yash stdout-json: ""
86
87#### recursive arith: array elements
88text[1]='d=123'
89text[2]='text[1]'
90text[3]='text[2]'
91echo $((a=text[3]))
92## stdout: 123
93## N-I ash/dash/yash status: 2
94## N-I ash/dash/yash stdout-json: ""
95
96#### dynamic arith varname: assign
97vec2_set () {
98 local this=$1 x=$2 y=$3
99 : $(( ${this}_x = $2 ))
100 : $(( ${this}_y = y ))
101}
102vec2_set a 3 4
103vec2_set b 5 12
104echo a_x=$a_x a_y=$a_y
105echo b_x=$b_x b_y=$b_y
106## STDOUT:
107a_x=3 a_y=4
108b_x=5 b_y=12
109## END
110
111#### dynamic arith varname: read
112
113vec2_load() {
114 local this=$1
115 x=$(( ${this}_x ))
116 : $(( y = ${this}_y ))
117}
118a_x=12 a_y=34
119vec2_load a
120echo x=$x y=$y
121## STDOUT:
122x=12 y=34
123## END
124
125#### dynamic arith varname: copy/add
126shopt -s eval_unsafe_arith # for RHS
127
128vec2_copy () {
129 local this=$1 rhs=$2
130 : $(( ${this}_x = $(( ${rhs}_x )) ))
131 : $(( ${this}_y = ${rhs}_y ))
132}
133vec2_add () {
134 local this=$1 rhs=$2
135 : $(( ${this}_x += $(( ${rhs}_x )) ))
136 : $(( ${this}_y += ${rhs}_y ))
137}
138a_x=3 a_y=4
139b_x=4 b_y=20
140vec2_copy c a
141echo c_x=$c_x c_y=$c_y
142vec2_add c b
143echo c_x=$c_x c_y=$c_y
144## STDOUT:
145c_x=3 c_y=4
146c_x=7 c_y=24
147## END
148
149#### is-array with ${var@a}
150case $SH in (mksh|ash|dash|yash) exit 1 ;; esac
151
152function ble/is-array { [[ ${!1@a} == *a* ]]; }
153
154ble/is-array undef
155echo undef $?
156
157string=''
158ble/is-array string
159echo string $?
160
161array=(one two three)
162ble/is-array array
163echo array $?
164## STDOUT:
165undef 1
166string 1
167array 0
168## END
169## N-I zsh/mksh/ash/dash/yash status: 1
170## N-I zsh/mksh/ash/dash/yash stdout-json: ""
171
172
173#### Sparse array with big index
174
175# TODO: more BashArray idioms / stress tests ?
176
177a=()
178
179if false; then
180 # This takes too long! # From Zulip
181 i=$(( 0x0100000000000000 ))
182else
183 # smaller number that's OK
184 i=$(( 0x0100000 ))
185fi
186
187a[i]=1
188
189echo len=${#a[@]}
190
191## STDOUT:
192len=1
193## END
194
195## N-I ash status: 2
196## N-I ash STDOUT:
197## END
198
199## BUG zsh STDOUT:
200len=1048576
201## END
202
203
204#### shift unshift reverse
205
206case $SH in mksh|ash) exit ;; esac
207
208# https://github.com/akinomyoga/ble.sh/blob/79beebd928cf9f6506a687d395fd450d027dc4cd/src/util.sh#L578-L582
209
210# @fn ble/array#unshift arr value...
211function ble/array#unshift {
212 builtin eval -- "$1=(\"\${@:2}\" \"\${$1[@]}\")"
213}
214# @fn ble/array#shift arr count
215function ble/array#shift {
216 # Note: Bash 4.3 以下では ${arr[@]:${2:-1}} が offset='${2'
217 # length='-1' に解釈されるので、先に算術式展開させる。
218 builtin eval -- "$1=(\"\${$1[@]:$((${2:-1}))}\")"
219}
220# @fn ble/array#reverse arr
221function ble/array#reverse {
222 builtin eval "
223 set -- \"\${$1[@]}\"; $1=()
224 local e$1 i$1=\$#
225 for e$1; do $1[--i$1]=\"\$e$1\"; done"
226}
227
228a=( {1..6} )
229echo "${a[@]}"
230
231ble/array#shift a 1
232echo "${a[@]}"
233
234ble/array#shift a 2
235echo "${a[@]}"
236
237echo ---
238
239ble/array#unshift a 99
240echo "${a[@]}"
241
242echo ---
243
244# doesn't work in zsh!
245ble/array#reverse a
246echo "${a[@]}"
247
248
249## STDOUT:
2501 2 3 4 5 6
2512 3 4 5 6
2524 5 6
253---
25499 4 5 6
255---
2566 5 4 99
257## END
258
259## BUG zsh STDOUT:
2601 2 3 4 5 6
2612 3 4 5 6
2624 5 6
263---
26499 4 5 6
265---
2665 4 99
267## END
268
269## N-I mksh/ash STDOUT:
270## END
271
272
273#### Performance demo
274
275case $SH in bash|zsh|mksh|ash) exit ;; esac
276
277#pp line (a)
278
279a=( foo {25..27} bar )
280
281a[10]='sparse'
282
283var sp = _a2sp(a)
284echo $[type(sp)]
285
286echo len: $[_opsp(sp, 'len')]
287
288#echo $[len(sp)]
289
290shopt -s ysh:upgrade
291
292echo subst: @[_opsp(sp, 'subst')]
293echo keys: @[_opsp(sp, 'keys')]
294
295echo slice: @[_opsp(sp, 'slice', 2, 5)]
296
297call _opsp(sp, 'set', 0, 'set0')
298
299echo get0: $[_opsp(sp, 'get', 0)]
300echo get1: $[_opsp(sp, 'get', 1)]
301echo ---
302
303to_append=(x y)
304echo append
305call _opsp(sp, 'append', to_append)
306echo subst: @[_opsp(sp, 'subst')]
307echo keys: @[_opsp(sp, 'keys')]
308echo ---
309
310echo unset
311call _opsp(sp, 'unset', 11)
312echo subst: @[_opsp(sp, 'subst')]
313echo keys: @[_opsp(sp, 'keys')]
314
315echo ---
316
317# Sparse
318var d = {
319 '1': 'a',
320 '10': 'b',
321 '100': 'c',
322 '1000': 'd',
323 '10000': 'e',
324 '100000': 'f',
325}
326
327var sp2 = _d2sp(d)
328
329echo len: $[_opsp(sp2, 'len')]
330echo subst: @[_opsp(sp2, 'subst')]
331
332
333## STDOUT:
334SparseArray
335len: 6
336subst: foo 25 26 27 bar sparse
337keys: 0 1 2 3 4 10
338slice: 26 27 bar
339get0: set0
340get1: 25
341---
342append
343subst: set0 25 26 27 bar sparse x y
344keys: 0 1 2 3 4 10 11 12
345---
346unset
347subst: set0 25 26 27 bar sparse y
348keys: 0 1 2 3 4 10 12
349---
350len: 6
351subst: a b c d e f
352## END
353
354## N-I bash/zsh/mksh/ash STDOUT:
355## END