1 ## compare_shells: bash
2 ## oils_failures_allowed: 6
3
4 #### Lower Case with , and ,,
5 x='ABC DEF'
6 echo ${x,}
7 echo ${x,,}
8 echo empty=${empty,}
9 echo empty=${empty,,}
10 ## STDOUT:
11 aBC DEF
12 abc def
13 empty=
14 empty=
15 ## END
16
17 #### Upper Case with ^ and ^^
18 x='abc def'
19 echo ${x^}
20 echo ${x^^}
21 echo empty=${empty^}
22 echo empty=${empty^^}
23 ## STDOUT:
24 Abc def
25 ABC DEF
26 empty=
27 empty=
28 ## END
29
30 #### Case folding - Unicode characters
31
32 # https://www.utf8-chartable.de/unicode-utf8-table.pl
33
34 x=$'\u00C0\u00C8' # upper grave
35 y=$'\u00E1\u00E9' # lower acute
36
37 echo u ${x^}
38 echo U ${x^^}
39
40 echo l ${x,}
41 echo L ${x,,}
42
43 echo u ${y^}
44 echo U ${y^^}
45
46 echo l ${y,}
47 echo L ${y,,}
48
49 ## STDOUT:
50 u ÀÈ
51 U ÀÈ
52 l àÈ
53 L àè
54 u Áé
55 U ÁÉ
56 l áé
57 L áé
58 ## END
59
60 #### Case folding - multi code point
61
62 echo shell
63 small=$'\u00DF'
64 echo u ${small^}
65 echo U ${small^^}
66
67 echo l ${small,}
68 echo L ${small,,}
69 echo
70
71 echo python2
72 python2 -c '
73 small = u"\u00DF"
74 print(small.upper().encode("utf-8"))
75 print(small.lower().encode("utf-8"))
76 '
77 echo
78
79 # Not in the container images, but python 3 DOES support it!
80 # This is moved to demo/survey-case-fold.sh
81
82 if false; then
83 echo python3
84 python3 -c '
85 import sys
86 small = u"\u00DF"
87 sys.stdout.buffer.write(small.upper().encode("utf-8") + b"\n")
88 sys.stdout.buffer.write(small.lower().encode("utf-8") + b"\n")
89 '
90 fi
91
92 if false; then
93 # Yes, supported
94 echo node.js
95
96 nodejs -e '
97 var small = "\u00DF"
98 console.log(small.toUpperCase())
99 console.log(small.toLowerCase())
100 '
101 fi
102
103 ## STDOUT:
104 ## END
105 ## BUG bash STDOUT:
106 shell
107 u ß
108 U ß
109 l ß
110 L ß
111
112 python2
113 ß
114 ß
115
116 ## END
117
118 #### Case folding that depends on locale (not enabled, requires Turkish locale)
119
120 # Hm this works in demo/survey-case-fold.sh
121 # Is this a bash 4.4 thing?
122
123 #export LANG='tr_TR.UTF-8'
124 #echo $LANG
125
126 x='i'
127
128 echo u ${x^}
129 echo U ${x^^}
130
131 echo l ${x,}
132 echo L ${x,,}
133
134 ## OK bash/osh STDOUT:
135 u I
136 U I
137 l i
138 L i
139 ## END
140
141 #### Lower Case with constant string (VERY WEIRD)
142 x='AAA ABC DEF'
143 echo ${x,A}
144 echo ${x,,A} # replaces every A only?
145 ## STDOUT:
146 aAA ABC DEF
147 aaa aBC DEF
148 ## END
149
150 #### Lower Case glob
151
152 # Hm with C.UTF-8, this does no case folding?
153 export LC_ALL=en_US.UTF-8
154
155 x='ABC DEF'
156 echo ${x,[d-f]}
157 echo ${x,,[d-f]} # This seems buggy, it doesn't include F?
158 ## STDOUT:
159 ABC DEF
160 ABC deF
161 ## END
162
163 #### ${x@u} U l L upper / lower case (bash 5.1 feature)
164
165 # https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
166
167 x='abc def'
168 echo "${x@u}"
169
170 # TODO: we need to upgrade the spec tests to bash 5.1 (or bash 5.2 is coming
171 # out soon)
172
173 ## N-I bash status: 1
174 ## N-I bash STDOUT:
175 ## END
176
177
178 #### ${x@Q}
179 x="FOO'BAR spam\"eggs"
180 eval "new=${x@Q}"
181 test "$x" = "$new" && echo OK
182 ## STDOUT:
183 OK
184 ## END
185
186 #### ${array@Q} and ${array[@]@Q}
187 array=(x 'y\nz')
188 echo ${array[@]@Q}
189 echo ${array@Q}
190 echo ${array@Q}
191 ## STDOUT:
192 'x' 'y\nz'
193 'x'
194 'x'
195 ## END
196 ## OK osh STDOUT:
197 x $'y\\nz'
198 x
199 x
200 ## END
201
202 #### ${!prefix@} ${!prefix*} yields sorted array of var names
203 ZOO=zoo
204 ZIP=zip
205 ZOOM='one two'
206 Z='three four'
207
208 z=lower
209
210 argv.py ${!Z*}
211 argv.py ${!Z@}
212 argv.py "${!Z*}"
213 argv.py "${!Z@}"
214 for i in 1 2; do argv.py ${!Z*} ; done
215 for i in 1 2; do argv.py ${!Z@} ; done
216 for i in 1 2; do argv.py "${!Z*}"; done
217 for i in 1 2; do argv.py "${!Z@}"; done
218 ## STDOUT:
219 ['Z', 'ZIP', 'ZOO', 'ZOOM']
220 ['Z', 'ZIP', 'ZOO', 'ZOOM']
221 ['Z ZIP ZOO ZOOM']
222 ['Z', 'ZIP', 'ZOO', 'ZOOM']
223 ['Z', 'ZIP', 'ZOO', 'ZOOM']
224 ['Z', 'ZIP', 'ZOO', 'ZOOM']
225 ['Z', 'ZIP', 'ZOO', 'ZOOM']
226 ['Z', 'ZIP', 'ZOO', 'ZOOM']
227 ['Z ZIP ZOO ZOOM']
228 ['Z ZIP ZOO ZOOM']
229 ['Z', 'ZIP', 'ZOO', 'ZOOM']
230 ['Z', 'ZIP', 'ZOO', 'ZOOM']
231 ## END
232
233 #### ${!prefix@} matches var name (regression)
234 hello1=1 hello2=2 hello3=3
235 echo ${!hello@}
236 hello=()
237 echo ${!hello@}
238 ## STDOUT:
239 hello1 hello2 hello3
240 hello hello1 hello2 hello3
241 ## END
242
243 #### ${var@a} for attributes
244 array=(one two)
245 echo ${array@a}
246 declare -r array=(one two)
247 echo ${array@a}
248 declare -rx PYTHONPATH=hi
249 echo ${PYTHONPATH@a}
250
251 # bash and osh differ here
252 #declare -rxn x=z
253 #echo ${x@a}
254 ## STDOUT:
255 a
256 ar
257 rx
258 ## END
259
260 #### ${var@a} error conditions
261 echo [${?@a}]
262 ## STDOUT:
263 []
264 ## END
265
266 #### undef and @P @Q @a
267 $SH -c 'echo ${undef@P}'
268 echo status=$?
269 $SH -c 'echo ${undef@Q}'
270 echo status=$?
271 $SH -c 'echo ${undef@a}'
272 echo status=$?
273 ## STDOUT:
274
275 status=0
276
277 status=0
278
279 status=0
280 ## END
281 ## OK osh STDOUT:
282
283 status=0
284 ''
285 status=0
286
287 status=0
288 ## END
289
290
291 #### argv array and @P @Q @a
292 $SH -c 'echo ${@@P}' dummy a b c
293 echo status=$?
294 $SH -c 'echo ${@@Q}' dummy a 'b\nc'
295 echo status=$?
296 $SH -c 'echo ${@@a}' dummy a b c
297 echo status=$?
298 ## STDOUT:
299 a b c
300 status=0
301 'a' 'b\nc'
302 status=0
303
304 status=0
305 ## END
306 ## OK osh STDOUT:
307 status=1
308 a $'b\\nc'
309 status=0
310 a
311 status=0
312 ## END
313
314 #### assoc array and @P @Q @a
315
316 # note: "y z" causes a bug!
317 $SH -c 'declare -A A=(["x"]="y"); echo ${A@P} - ${A[@]@P}'
318 echo status=$?
319
320 # note: "y z" causes a bug!
321 $SH -c 'declare -A A=(["x"]="y"); echo ${A@Q} - ${A[@]@Q}'
322 echo status=$?
323
324 $SH -c 'declare -A A=(["x"]=y); echo ${A@a} - ${A[@]@a}'
325 echo status=$?
326 ## STDOUT:
327 - y
328 status=0
329 - 'y'
330 status=0
331 A - A
332 status=0
333 ## END
334 ## OK osh STDOUT:
335 status=1
336 status=1
337 A - A
338 status=0
339 ## END
340
341 #### ${!var[@]@X}
342 # note: "y z" causes a bug!
343 $SH -c 'declare -A A=(["x"]="y"); echo ${!A[@]@P}'
344 if test $? -ne 0; then echo fail; fi
345
346 # note: "y z" causes a bug!
347 $SH -c 'declare -A A=(["x y"]="y"); echo ${!A[@]@Q}'
348 if test $? -ne 0; then echo fail; fi
349
350 $SH -c 'declare -A A=(["x"]=y); echo ${!A[@]@a}'
351 if test $? -ne 0; then echo fail; fi
352 # STDOUT:
353
354
355
356 # END
357 ## OK osh STDOUT:
358 fail
359 'x y'
360 a
361 ## END
362
363 #### ${#var@X} is a parse error
364 # note: "y z" causes a bug!
365 $SH -c 'declare -A A=(["x"]="y"); echo ${#A[@]@P}'
366 if test $? -ne 0; then echo fail; fi
367
368 # note: "y z" causes a bug!
369 $SH -c 'declare -A A=(["x"]="y"); echo ${#A[@]@Q}'
370 if test $? -ne 0; then echo fail; fi
371
372 $SH -c 'declare -A A=(["x"]=y); echo ${#A[@]@a}'
373 if test $? -ne 0; then echo fail; fi
374 ## STDOUT:
375 fail
376 fail
377 fail
378 ## END
379
380 #### ${!A@a} and ${!A[@]@a}
381 declare -A A=(["x"]=y)
382 echo x=${!A[@]@a}
383 echo x=${!A@a}
384
385 # OSH prints 'a' for indexed array because the AssocArray with ! turns into
386 # it. Disallowing it would be the other reasonable behavior.
387
388 ## STDOUT:
389 x=
390 x=
391 ## END