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