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