OILS / spec / append.test.sh View on Github | oilshell.org

303 lines, 121 significant
1# spec/append.test.sh: Test +=
2
3## compare_shells: bash mksh zsh
4
5#### Append string to string
6s='abc'
7s+=d
8echo $s
9## stdout: abcd
10
11#### Append array to array
12a=(x y )
13a+=(t 'u v')
14argv.py "${a[@]}"
15## stdout: ['x', 'y', 't', 'u v']
16
17#### Append string to undefined variable
18
19s+=foo
20echo 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
25set -u
26
27t+=foo
28echo t=$t
29t+=foo
30echo t=$t
31## STDOUT:
32s=foo
33t=foo
34t=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
42y+=(c d)
43argv.py "${y[@]}"
44## STDOUT:
45['c', 'd']
46## END
47
48#### error: s+=(my array)
49s='abc'
50s+=(d e f)
51echo $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.
63a=(x y )
64a+=z
65argv.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)
74typeset s='abc'
75echo $s
76
77typeset s+=(d e f)
78echo status=$?
79argv.py "${s[@]}"
80
81## status: 1
82## STDOUT:
83abc
84## END
85## OK bash status: 0
86## OK bash STDOUT:
87abc
88status=0
89['abc', 'd', 'e', 'f']
90## END
91
92#### error: typeset myarray+=s
93typeset a=(x y)
94argv.py "${a[@]}"
95typeset a+=s
96argv.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.
112A=a
113A+=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.
123a=(x y )
124a[1]+=z
125argv.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?
133a=(1 '2 3')
134a[-1]+=' 4'
135argv.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!
143a=(1 '2 3')
144a[-1]+=(4 5)
145argv.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
163s1='abc'
164s2=$s1
165s1+='d'
166echo $s1 $s2
167## stdout: abcd abc
168
169#### typeset s+=
170
171typeset s+=foo
172echo 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
177set -u
178
179typeset t+=foo
180echo t=$t
181typeset t+=foo
182echo t=$t
183## STDOUT:
184s=foo
185t=foo
186t=foofoo
187## END
188## N-I zsh status: 1
189## N-I zsh stdout-json: ""
190
191#### typeset s${dyn}+=
192
193dyn=x
194
195typeset s${dyn}+=foo
196echo 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
201set -u
202
203typeset t${dyn}+=foo
204echo tx=$tx
205typeset t${dyn}+=foo
206echo tx=$tx
207## STDOUT:
208sx=foo
209tx=foo
210tx=foofoo
211## END
212## N-I zsh status: 1
213## N-I zsh stdout-json: ""
214
215#### export readonly +=
216
217export e+=foo
218echo e=$e
219
220readonly r+=bar
221echo r=$r
222
223set -u
224
225export e+=foo
226echo e=$e
227
228#readonly r+=foo
229#echo r=$e
230
231## STDOUT:
232e=foo
233r=bar
234e=foofoo
235## END
236## N-I zsh status: 1
237## N-I zsh stdout-json: ""
238
239#### local +=
240
241f() {
242 local s+=foo
243 echo s=$s
244
245 set -u
246 local s+=foo
247 echo s=$s
248}
249
250f
251## STDOUT:
252s=foo
253s=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
260declare d+=(d e)
261echo "${d[@]}"
262declare d+=(c l)
263echo "${d[@]}"
264
265readonly r+=(r e)
266echo "${r[@]}"
267# can't do this again
268
269f() {
270 local l+=(l o)
271 echo "${l[@]}"
272
273 local l+=(c a)
274 echo "${l[@]}"
275}
276
277f
278
279## STDOUT:
280d e
281d e c l
282r e
283l o
284l 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)
292shopt -s strict_array
293
294export e+=(e x)
295echo "${e[@]}"
296
297## status: 1
298## STDOUT:
299## END
300## N-I bash status: 0
301## N-I bash STDOUT:
302e x
303## END