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-json: "123:123\n321:321\n"
45 ## BUG ash stdout-json: "123:123\n321:123\n"
46 ## N-I dash status: 2
47 ## N-I dash stdout-json: ""
48 ## N-I yash stdout-json: "a=123:0\na=321:0\n"
49
50 #### recursive arith: side effects
51 # In Zsh and Busybox sh, the side effect of inner arithmetic
52 # evaluations seems to take effect only after the whole evaluation.
53 shopt -s eval_unsafe_arith
54 a='b=c' c='d=123'
55 echo $((a,d)):$((d))
56 ## stdout: 123:123
57 ## BUG zsh/ash stdout: 0:123
58 ## N-I dash/yash status: 2
59 ## N-I dash/yash stdout-json: ""
60
61 #### recursive arith: recursion
62 shopt -s eval_unsafe_arith
63 loop='i<=100&&(s+=i,i++,loop)' s=0 i=0
64 echo $((a=loop,s))
65 ## stdout: 5050
66 ## N-I mksh status: 1
67 ## N-I mksh stdout-json: ""
68 ## N-I ash/dash/yash status: 2
69 ## N-I ash/dash/yash stdout-json: ""
70
71 #### recursive arith: array elements
72 shopt -s eval_unsafe_arith
73 text[1]='d=123'
74 text[2]='text[1]'
75 text[3]='text[2]'
76 echo $((a=text[3]))
77 ## stdout: 123
78 ## N-I ash/dash/yash status: 2
79 ## N-I ash/dash/yash stdout-json: ""
80
81 #### dynamic arith varname: assign
82 shopt -s parse_dynamic_arith # for LHS
83
84 vec2_set () {
85 local this=$1 x=$2 y=$3
86 : $(( ${this}_x = $2 ))
87 : $(( ${this}_y = y ))
88 }
89 vec2_set a 3 4
90 vec2_set b 5 12
91 echo a_x=$a_x a_y=$a_y
92 echo b_x=$b_x b_y=$b_y
93 ## STDOUT:
94 a_x=3 a_y=4
95 b_x=5 b_y=12
96 ## END
97
98 #### dynamic arith varname: read
99 shopt -s eval_unsafe_arith # for RHS
100
101 vec2_load() {
102 local this=$1
103 x=$(( ${this}_x ))
104 : $(( y = ${this}_y ))
105 }
106 a_x=12 a_y=34
107 vec2_load a
108 echo x=$x y=$y
109 ## STDOUT:
110 x=12 y=34
111 ## END
112
113 #### dynamic arith varname: copy/add
114 shopt -s parse_dynamic_arith # for LHS
115 shopt -s eval_unsafe_arith # for RHS
116
117 vec2_copy () {
118 local this=$1 rhs=$2
119 : $(( ${this}_x = $(( ${rhs}_x )) ))
120 : $(( ${this}_y = ${rhs}_y ))
121 }
122 vec2_add () {
123 local this=$1 rhs=$2
124 : $(( ${this}_x += $(( ${rhs}_x )) ))
125 : $(( ${this}_y += ${rhs}_y ))
126 }
127 a_x=3 a_y=4
128 b_x=4 b_y=20
129 vec2_copy c a
130 echo c_x=$c_x c_y=$c_y
131 vec2_add c b
132 echo c_x=$c_x c_y=$c_y
133 ## STDOUT:
134 c_x=3 c_y=4
135 c_x=7 c_y=24
136 ## END
137
138 #### is-array with ${var@a}
139 case $SH in (mksh|ash|dash|yash) exit 1 ;; esac
140
141 function ble/is-array { [[ ${!1@a} == *a* ]]; }
142
143 ble/is-array undef
144 echo undef $?
145
146 string=''
147 ble/is-array string
148 echo string $?
149
150 array=(one two three)
151 ble/is-array array
152 echo array $?
153 ## STDOUT:
154 undef 1
155 string 1
156 array 0
157 ## END
158 ## N-I zsh/mksh/ash/dash/yash status: 1
159 ## N-I zsh/mksh/ash/dash/yash stdout-json: ""