1 | # spec/append.test.sh: Test +=
|
2 |
|
3 | ## compare_shells: bash mksh zsh
|
4 |
|
5 | #### Append string to string
|
6 | s='abc'
|
7 | s+=d
|
8 | echo $s
|
9 | ## stdout: abcd
|
10 |
|
11 | #### Append array to array
|
12 | a=(x y )
|
13 | a+=(t 'u v')
|
14 | argv.py "${a[@]}"
|
15 | ## stdout: ['x', 'y', 't', 'u v']
|
16 |
|
17 | #### Append string to undefined variable
|
18 |
|
19 | s+=foo
|
20 | echo s=$s
|
21 |
|
22 | # bash and mksh agree that this does NOT respect set -u.
|
23 | # I think that's a mistake, but += is a legacy construct, so let's copy it.
|
24 |
|
25 | set -u
|
26 |
|
27 | t+=foo
|
28 | echo t=$t
|
29 | t+=foo
|
30 | echo t=$t
|
31 | ## STDOUT:
|
32 | s=foo
|
33 | t=foo
|
34 | t=foofoo
|
35 | ## END
|
36 |
|
37 | #### Append to array to undefined variable
|
38 |
|
39 | # I wonder if Oil should have accumulators:
|
40 | # auto y += %(c d) or something
|
41 |
|
42 | y+=(c d)
|
43 | argv.py "${y[@]}"
|
44 | ## STDOUT:
|
45 | ['c', 'd']
|
46 | ## END
|
47 |
|
48 | #### error: s+=(my array)
|
49 | s='abc'
|
50 | s+=(d e f)
|
51 | echo $s
|
52 | ## status: 1
|
53 | ## stdout-json: ""
|
54 | ## BUG bash/mksh status: 0
|
55 | ## BUG bash/mksh stdout: abc
|
56 | ## OK zsh status: 0
|
57 | ## OK zsh stdout: abc d e f
|
58 |
|
59 | #### error: myarray+=s
|
60 |
|
61 | # They treat this as implicit index 0. We disallow this on the LHS, so we will
|
62 | # also disallow it on the RHS.
|
63 | a=(x y )
|
64 | a+=z
|
65 | argv.py "${a[@]}"
|
66 | ## status: 1
|
67 | ## stdout-json: ""
|
68 | ## OK bash/mksh status: 0
|
69 | ## OK bash/mksh stdout: ['xz', 'y']
|
70 | ## OK zsh status: 0
|
71 | ## OK zsh stdout: ['x', 'y', 'z']
|
72 |
|
73 | #### typeset s+=(my array)
|
74 | typeset s='abc'
|
75 | echo $s
|
76 |
|
77 | typeset s+=(d e f)
|
78 | echo status=$?
|
79 | argv.py "${s[@]}"
|
80 |
|
81 | ## status: 1
|
82 | ## STDOUT:
|
83 | abc
|
84 | ## END
|
85 | ## OK bash status: 0
|
86 | ## OK bash STDOUT:
|
87 | abc
|
88 | status=0
|
89 | ['abc', 'd', 'e', 'f']
|
90 | ## END
|
91 |
|
92 | #### error: typeset myarray+=s
|
93 | typeset a=(x y)
|
94 | argv.py "${a[@]}"
|
95 | typeset a+=s
|
96 | argv.py "${a[@]}"
|
97 |
|
98 | ## status: 1
|
99 | ## STDOUT:
|
100 | ['x', 'y']
|
101 | ## END
|
102 | ## BUG bash status: 0
|
103 | ## BUG bash STDOUT:
|
104 | ['x', 'y']
|
105 | ['xs', 'y']
|
106 | ## END
|
107 | ## N-I mksh STDOUT:
|
108 | ## END
|
109 |
|
110 | #### error: append used like env prefix
|
111 | # This should be an error in other shells but it's not.
|
112 | A=a
|
113 | A+=a printenv.py A
|
114 | ## status: 2
|
115 | ## BUG bash/zsh status: 0
|
116 | ## BUG bash/zsh stdout: aa
|
117 | ## BUG mksh status: 0
|
118 | ## BUG mksh stdout: a
|
119 |
|
120 | #### myarray[1]+=s - Append to element
|
121 | # They treat this as implicit index 0. We disallow this on the LHS, so we will
|
122 | # also disallow it on the RHS.
|
123 | a=(x y )
|
124 | a[1]+=z
|
125 | argv.py "${a[@]}"
|
126 | ## status: 0
|
127 | ## stdout: ['x', 'yz']
|
128 | ## BUG zsh stdout: ['xz', 'y']
|
129 |
|
130 | #### myarray[-1]+=s - Append to last element
|
131 | # Works in bash, but not mksh. It seems like bash is doing the right thing.
|
132 | # a[-1] is allowed on the LHS. mksh doesn't have negative indexing?
|
133 | a=(1 '2 3')
|
134 | a[-1]+=' 4'
|
135 | argv.py "${a[@]}"
|
136 | ## stdout: ['1', '2 3 4']
|
137 | ## BUG mksh stdout: ['1', '2 3', ' 4']
|
138 |
|
139 | #### Try to append list to element
|
140 | # bash - runtime error: cannot assign list to array number
|
141 | # mksh - a[-1]+: is not an identifier
|
142 | # osh - parse error -- could be better!
|
143 | a=(1 '2 3')
|
144 | a[-1]+=(4 5)
|
145 | argv.py "${a[@]}"
|
146 |
|
147 | ## stdout-json: ""
|
148 | ## status: 2
|
149 |
|
150 | ## OK bash status: 0
|
151 | ## OK bash STDOUT:
|
152 | ['1', '2 3']
|
153 | ## END
|
154 |
|
155 | ## OK zsh status: 0
|
156 | ## OK zsh STDOUT:
|
157 | ['1', '2 3', '4', '5']
|
158 | ## END
|
159 |
|
160 | ## N-I mksh status: 1
|
161 |
|
162 | #### Strings have value semantics, not reference semantics
|
163 | s1='abc'
|
164 | s2=$s1
|
165 | s1+='d'
|
166 | echo $s1 $s2
|
167 | ## stdout: abcd abc
|
168 |
|
169 | #### typeset s+=
|
170 |
|
171 | typeset s+=foo
|
172 | echo s=$s
|
173 |
|
174 | # bash and mksh agree that this does NOT respect set -u.
|
175 | # I think that's a mistake, but += is a legacy construct, so let's copy it.
|
176 |
|
177 | set -u
|
178 |
|
179 | typeset t+=foo
|
180 | echo t=$t
|
181 | typeset t+=foo
|
182 | echo t=$t
|
183 | ## STDOUT:
|
184 | s=foo
|
185 | t=foo
|
186 | t=foofoo
|
187 | ## END
|
188 | ## N-I zsh status: 1
|
189 | ## N-I zsh stdout-json: ""
|
190 |
|
191 | #### typeset s${dyn}+=
|
192 |
|
193 | dyn=x
|
194 |
|
195 | typeset s${dyn}+=foo
|
196 | echo sx=$sx
|
197 |
|
198 | # bash and mksh agree that this does NOT respect set -u.
|
199 | # I think that's a mistake, but += is a legacy construct, so let's copy it.
|
200 |
|
201 | set -u
|
202 |
|
203 | typeset t${dyn}+=foo
|
204 | echo tx=$tx
|
205 | typeset t${dyn}+=foo
|
206 | echo tx=$tx
|
207 | ## STDOUT:
|
208 | sx=foo
|
209 | tx=foo
|
210 | tx=foofoo
|
211 | ## END
|
212 | ## N-I zsh status: 1
|
213 | ## N-I zsh stdout-json: ""
|
214 |
|
215 | #### export readonly +=
|
216 |
|
217 | export e+=foo
|
218 | echo e=$e
|
219 |
|
220 | readonly r+=bar
|
221 | echo r=$r
|
222 |
|
223 | set -u
|
224 |
|
225 | export e+=foo
|
226 | echo e=$e
|
227 |
|
228 | #readonly r+=foo
|
229 | #echo r=$e
|
230 |
|
231 | ## STDOUT:
|
232 | e=foo
|
233 | r=bar
|
234 | e=foofoo
|
235 | ## END
|
236 | ## N-I zsh status: 1
|
237 | ## N-I zsh stdout-json: ""
|
238 |
|
239 | #### local +=
|
240 |
|
241 | f() {
|
242 | local s+=foo
|
243 | echo s=$s
|
244 |
|
245 | set -u
|
246 | local s+=foo
|
247 | echo s=$s
|
248 | }
|
249 |
|
250 | f
|
251 | ## STDOUT:
|
252 | s=foo
|
253 | s=foofoo
|
254 | ## END
|
255 | ## N-I zsh status: 1
|
256 | ## N-I zsh stdout-json: ""
|
257 |
|
258 | #### assign builtin appending array: declare d+=(d e)
|
259 |
|
260 | declare d+=(d e)
|
261 | echo "${d[@]}"
|
262 | declare d+=(c l)
|
263 | echo "${d[@]}"
|
264 |
|
265 | readonly r+=(r e)
|
266 | echo "${r[@]}"
|
267 | # can't do this again
|
268 |
|
269 | f() {
|
270 | local l+=(l o)
|
271 | echo "${l[@]}"
|
272 |
|
273 | local l+=(c a)
|
274 | echo "${l[@]}"
|
275 | }
|
276 |
|
277 | f
|
278 |
|
279 | ## STDOUT:
|
280 | d e
|
281 | d e c l
|
282 | r e
|
283 | l o
|
284 | l o c a
|
285 | ## END
|
286 | ## N-I mksh status: 1
|
287 | ## N-I mksh stdout-json: ""
|
288 | ## N-I zsh status: 1
|
289 | ## N-I zsh stdout-json: ""
|
290 |
|
291 | #### export+=array disallowed (strict_array)
|
292 | shopt -s strict_array
|
293 |
|
294 | export e+=(e x)
|
295 | echo "${e[@]}"
|
296 |
|
297 | ## status: 1
|
298 | ## STDOUT:
|
299 | ## END
|
300 | ## N-I bash status: 0
|
301 | ## N-I bash STDOUT:
|
302 | e x
|
303 | ## END
|