1
2 #### recursive arith: one level
3 shopt -s eval_unsafe_arith
4 a='b=123'
5 echo $((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
12 shopt -s eval_unsafe_arith
13 a='b=c' c='d=123'
14 echo $((a))
15 ## stdout: 123
16 ## N-I dash status: 2
17 ## N-I dash stdout-json: ""
18 ## N-I yash stdout: b=c
19
20 #### recursive arith: short circuit &&, ||
21 # Note: mksh R52 has a bug. Even though it supports a short circuit like
22 # "echo $((cond&&(a=1)))", it doesn't work with "x=a=1; echo
23 # $((cond&&x))". It is fixed at least in mksh R57.
24 # Note: "busybox sh" doesn't support short circuit.
25 shopt -s eval_unsafe_arith
26 a=b=123
27 echo $((1||a)):$((b))
28 echo $((0||a)):$((b))
29 c=d=321
30 echo $((0&&c)):$((d))
31 echo $((1&&c)):$((d))
32 ## stdout-json: "1:0\n1:123\n0:0\n1:321\n"
33 ## BUG mksh stdout-json: "1:123\n1:123\n0:321\n1:321\n"
34 ## N-I ash stdout-json: "1:123\n1:123\n0:321\n1:321\n"
35 ## N-I dash/yash status: 2
36 ## N-I dash/yash stdout-json: "1:0\n"
37
38 #### recursive arith: short circuit ?:
39 # Note: "busybox sh" behaves strangely.
40 shopt -s eval_unsafe_arith
41 y=a=123 n=a=321
42 echo $((1?(y):(n))):$((a))
43 echo $((0?(y):(n))):$((a))
44 ## STDOUT:
45 123:123
46 321:321
47 ## END
48 ## BUG ash STDOUT:
49 123:321
50 321:321
51 ## END
52 ## N-I dash status: 2
53 ## N-I dash stdout-json: ""
54 ## N-I yash STDOUT:
55 a=123:0
56 a=321:0
57 ## END
58
59 #### recursive arith: side effects
60 # In Zsh and Busybox sh, the side effect of inner arithmetic
61 # evaluations seems to take effect only after the whole evaluation.
62 shopt -s eval_unsafe_arith
63 a='b=c' c='d=123'
64 echo $((a,d)):$((d))
65 ## stdout: 123:123
66 ## BUG zsh/ash stdout: 0:123
67 ## N-I dash/yash status: 2
68 ## N-I dash/yash stdout-json: ""
69
70 #### recursive arith: recursion
71 shopt -s eval_unsafe_arith
72 loop='i<=100&&(s+=i,i++,loop)' s=0 i=0
73 echo $((a=loop,s))
74 ## stdout: 5050
75 ## N-I mksh status: 1
76 ## N-I mksh stdout-json: ""
77 ## N-I ash/dash/yash status: 2
78 ## N-I ash/dash/yash stdout-json: ""
79
80 #### recursive arith: array elements
81 shopt -s eval_unsafe_arith
82 text[1]='d=123'
83 text[2]='text[1]'
84 text[3]='text[2]'
85 echo $((a=text[3]))
86 ## stdout: 123
87 ## N-I ash/dash/yash status: 2
88 ## N-I ash/dash/yash stdout-json: ""
89
90 #### dynamic arith varname: assign
91 shopt -s parse_dynamic_arith # for LHS
92
93 vec2_set () {
94 local this=$1 x=$2 y=$3
95 : $(( ${this}_x = $2 ))
96 : $(( ${this}_y = y ))
97 }
98 vec2_set a 3 4
99 vec2_set b 5 12
100 echo a_x=$a_x a_y=$a_y
101 echo b_x=$b_x b_y=$b_y
102 ## STDOUT:
103 a_x=3 a_y=4
104 b_x=5 b_y=12
105 ## END
106
107 #### dynamic arith varname: read
108 shopt -s eval_unsafe_arith # for RHS
109
110 vec2_load() {
111 local this=$1
112 x=$(( ${this}_x ))
113 : $(( y = ${this}_y ))
114 }
115 a_x=12 a_y=34
116 vec2_load a
117 echo x=$x y=$y
118 ## STDOUT:
119 x=12 y=34
120 ## END
121
122 #### dynamic arith varname: copy/add
123 shopt -s parse_dynamic_arith # for LHS
124 shopt -s eval_unsafe_arith # for RHS
125
126 vec2_copy () {
127 local this=$1 rhs=$2
128 : $(( ${this}_x = $(( ${rhs}_x )) ))
129 : $(( ${this}_y = ${rhs}_y ))
130 }
131 vec2_add () {
132 local this=$1 rhs=$2
133 : $(( ${this}_x += $(( ${rhs}_x )) ))
134 : $(( ${this}_y += ${rhs}_y ))
135 }
136 a_x=3 a_y=4
137 b_x=4 b_y=20
138 vec2_copy c a
139 echo c_x=$c_x c_y=$c_y
140 vec2_add c b
141 echo c_x=$c_x c_y=$c_y
142 ## STDOUT:
143 c_x=3 c_y=4
144 c_x=7 c_y=24
145 ## END
146
147 #### is-array with ${var@a}
148 case $SH in (mksh|ash|dash|yash) exit 1 ;; esac
149
150 function ble/is-array { [[ ${!1@a} == *a* ]]; }
151
152 ble/is-array undef
153 echo undef $?
154
155 string=''
156 ble/is-array string
157 echo string $?
158
159 array=(one two three)
160 ble/is-array array
161 echo array $?
162 ## STDOUT:
163 undef 1
164 string 1
165 array 0
166 ## END
167 ## N-I zsh/mksh/ash/dash/yash status: 1
168 ## N-I zsh/mksh/ash/dash/yash stdout-json: ""