1 #!/bin/bash
2 #
3 # Extended assignment language, e.g. typeset, declare, arrays, etc.
4 # Things that dash doesn't support.
5
6 #### local -a
7 # nixpkgs setup.sh uses this (issue #26)
8 f() {
9 local -a array=(x y z)
10 argv.py "${array[@]}"
11 }
12 f
13 ## stdout: ['x', 'y', 'z']
14 ## N-I mksh stdout-json: ""
15 ## N-I mksh status: 1
16
17 #### declare -a
18 # nixpkgs setup.sh uses this (issue #26)
19 declare -a array=(x y z)
20 argv.py "${array[@]}"
21 ## stdout: ['x', 'y', 'z']
22 ## N-I mksh stdout-json: ""
23 ## N-I mksh status: 1
24
25 #### typeset -a a[1]=a a[3]=c
26 # declare works the same way in bash, but not mksh.
27 # spaces are NOT allowed here.
28 typeset -a a[1*1]=x a[1+2]=z
29 argv.py "${a[@]}"
30 ## stdout: ['x', 'z']
31
32 #### indexed LHS without spaces is allowed
33 a[1 * 1]=x a[ 1 + 2 ]=z
34 argv.py "${a[@]}"
35 ## stdout: ['x', 'z']
36
37 #### declare -f exit code indicates function existence
38 func2=x # var names are NOT found
39 declare -f myfunc func2
40 echo $?
41
42 myfunc() { echo myfunc; }
43 # This prints the source code.
44 declare -f myfunc func2 > /dev/null
45 echo $?
46
47 func2() { echo func2; }
48 declare -f myfunc func2 > /dev/null
49 echo $?
50 ## STDOUT:
51 1
52 1
53 0
54 ## END
55 ## N-I mksh STDOUT:
56 127
57 127
58 127
59 ## END
60
61 #### declare -F prints function names
62 add () { expr 4 + 4; }
63 div () { expr 6 / 2; }
64 ek () { echo hello; }
65 __ec () { echo hi; }
66 _ab () { expr 10 % 3; }
67
68 declare -F
69 ## STDOUT:
70 declare -f __ec
71 declare -f _ab
72 declare -f add
73 declare -f div
74 declare -f ek
75 ## END
76 ## N-I mksh stdout-json: ""
77 ## N-I mksh status: 127
78
79 #### declare -p
80 var1() { echo func; } # function names are NOT found.
81 declare -p var1 var2 >/dev/null
82 echo $?
83
84 var1=x
85 declare -p var1 var2 >/dev/null
86 echo $?
87
88 var2=y
89 declare -p var1 var2 >/dev/null
90 echo $?
91 ## STDOUT:
92 1
93 1
94 0
95 ## N-I mksh STDOUT:
96 127
97 127
98 127
99 ## END
100
101 #### typeset -f
102 # mksh implement typeset but not declare
103 typeset -f myfunc func2
104 echo $?
105
106 myfunc() { echo myfunc; }
107 # This prints the source code.
108 typeset -f myfunc func2 > /dev/null
109 echo $?
110
111 func2() { echo func2; }
112 typeset -f myfunc func2 > /dev/null
113 echo $?
114 ## STDOUT:
115 1
116 1
117 0
118 ## END
119
120 #### typeset -p
121 var1() { echo func; } # function names are NOT found.
122 typeset -p var1 var2 >/dev/null
123 echo $?
124
125 var1=x
126 typeset -p var1 var2 >/dev/null
127 echo $?
128
129 var2=y
130 typeset -p var1 var2 >/dev/null
131 echo $?
132 ## STDOUT:
133 1
134 1
135 0
136 ## BUG mksh STDOUT:
137 # mksh doesn't respect exit codes
138 0
139 0
140 0
141 ## END
142
143 #### typeset -r makes a string readonly
144 typeset -r s1='12'
145 typeset -r s2='34'
146
147 s1='c'
148 echo status=$?
149 s2='d'
150 echo status=$?
151
152 s1+='e'
153 echo status=$?
154 s2+='f'
155 echo status=$?
156
157 unset s1
158 echo status=$?
159 unset s2
160 echo status=$?
161
162 ## status: 1
163 ## stdout-json: ""
164 ## OK mksh status: 2
165 ## OK bash status: 0
166 ## OK bash STDOUT:
167 status=1
168 status=1
169 status=1
170 status=1
171 status=1
172 status=1
173 ## END
174
175 #### typeset -ar makes it readonly
176 typeset -a -r array1=(1 2)
177 typeset -ar array2=(3 4)
178
179 array1=('c')
180 echo status=$?
181 array2=('d')
182 echo status=$?
183
184 array1+=('e')
185 echo status=$?
186 array2+=('f')
187 echo status=$?
188
189 unset array1
190 echo status=$?
191 unset array2
192 echo status=$?
193
194 ## status: 1
195 ## stdout-json: ""
196 ## OK bash status: 0
197 ## OK bash STDOUT:
198 status=1
199 status=1
200 status=1
201 status=1
202 status=1
203 status=1
204 ## END
205 ## N-I mksh status: 1
206 ## N-I mksh stdout-json: ""
207
208 #### typeset -x makes it exported
209 typeset -rx PYTHONPATH=lib/
210 printenv.py PYTHONPATH
211 ## STDOUT:
212 lib/
213 ## END
214
215 #### Multiple assignments / array assignments on a line
216 a=1 b[0+0]=2 c=3
217 echo $a $b $c
218 ## stdout: 1 2 3
219
220 #### Env bindings shouldn't contain array assignments
221 a=1 b[0]=2 c=3 printenv.py a b c
222 ## status: 2
223 ## stdout-json: ""
224 ## OK bash STDOUT:
225 1
226 None
227 3
228 ## END
229 ## OK bash status: 0
230 ## BUG mksh STDOUT:
231 1
232 2
233 3
234 ## END
235 ## OK mksh status: 0
236
237 #### syntax error in array assignment
238 a=x b[0+]=y c=z
239 echo $a $b $c
240 ## status: 2
241 ## stdout-json: ""
242 ## BUG bash stdout: x
243 ## BUG bash status: 0
244 ## OK mksh stdout-json: ""
245 ## OK mksh status: 1
246
247 #### declare -g (bash-specific; bash-completion uses it)
248 f() {
249 declare -g G=42
250 declare L=99
251
252 declare -Ag dict
253 dict["foo"]=bar
254
255 declare -A localdict
256 localdict["spam"]=Eggs
257
258 # For bash-completion
259 eval 'declare -Ag ev'
260 ev["ev1"]=ev2
261 }
262 f
263 argv.py "$G" "$L"
264 argv.py "${dict["foo"]}" "${localdict["spam"]}"
265 argv.py "${ev["ev1"]}"
266 ## STDOUT:
267 ['42', '']
268 ['bar', '']
269 ['ev2']
270 ## END
271 ## N-I mksh STDOUT:
272 ['', '']
273
274 ## END
275 ## N-I mksh status: 1
276