OILS / spec / var-op-strip.test.sh View on Github | oils.pub

358 lines, 190 significant
1## compare_shells: dash bash mksh zsh ash
2
3#### Remove const suffix
4v=abcd
5echo ${v%d} ${v%%cd}
6## stdout: abc ab
7
8#### Remove const prefix
9v=abcd
10echo ${v#a} ${v##ab}
11## stdout: bcd cd
12
13#### Remove const suffix is vectorized on user array
14a=(1a 2a 3a)
15argv.py ${a[@]%a}
16## stdout: ['1', '2', '3']
17## status: 0
18## N-I dash/mksh/ash stdout-json: ""
19## N-I dash/ash status: 2
20## N-I mksh status: 1
21
22#### Remove const suffix is vectorized on $@ array
23set -- 1a 2a 3a
24argv.py ${@%a}
25## stdout: ['1', '2', '3']
26## status: 0
27## N-I dash/ash stdout: ['1a', '2a', '3']
28## N-I dash/ash status: 0
29## N-I mksh stdout-json: ""
30## N-I mksh status: 1
31
32#### Remove const suffix from undefined
33echo ${undef%suffix}
34## stdout:
35
36#### Remove shortest glob suffix
37v=aabbccdd
38echo ${v%c*}
39## stdout: aabbc
40
41#### Remove longest glob suffix
42v=aabbccdd
43echo ${v%%c*}
44## stdout: aabb
45
46#### Remove shortest glob prefix
47v=aabbccdd
48echo ${v#*b}
49## stdout: bccdd
50
51#### Remove longest glob prefix
52v=aabbccdd
53echo ${v##*b}
54## stdout: ccdd
55
56#### Strip char class
57v=abc
58echo ${v%[[:alpha:]]}
59## stdout: ab
60## N-I mksh stdout: abc
61
62#### Strip unicode prefix
63# NOTE: LANG is set to utf-8.
64v='μ-'
65echo ${v#?} # ? is a glob that stands for one character
66echo ${v##?}
67v=''
68echo ${v%?} # ? is a glob that stands for one character
69echo ${v%%?}
70## STDOUT:
71-
72-
73-
74-
75## BUG dash/mksh/ash stdout-repr: '\xbc-\n\xbc-\n-\xce\n-\xce\n'
76## BUG zsh stdout-repr: '\n\n\n\n'
77
78#### Bug fix: Test that you can remove everything with glob
79s='--x--'
80argv.py "${s%%-*}" "${s%-*}" "${s#*-}" "${s##*-}"
81## STDOUT:
82['', '--x-', '-x--', '']
83## END
84
85#### Test that you can remove everything with const
86s='abcd'
87argv.py "${s%%abcd}" "${s%abcd}" "${s#abcd}" "${s##abcd}"
88# failure case:
89argv.py "${s%%abcde}" "${s%abcde}" "${s#abcde}" "${s##abcde}"
90## STDOUT:
91['', '', '', '']
92['abcd', 'abcd', 'abcd', 'abcd']
93## END
94
95#### Prepend using replacement of #
96# This case was found in Kubernetes and others
97array=(aa bb '')
98argv.py ${array[@]/#/prefix-}
99## STDOUT:
100['prefix-aa', 'prefix-bb', 'prefix-']
101## END
102## N-I dash/ash status: 2
103## N-I dash/ash stdout-json: ""
104## N-I mksh status: 1
105## N-I mksh stdout-json: ""
106
107#### Append using replacement of %
108array=(aa bb '')
109argv.py ${array[@]/%/-suffix}
110## STDOUT:
111['aa-suffix', 'bb-suffix', '-suffix']
112## END
113## N-I dash/ash status: 2
114## N-I dash/ash stdout-json: ""
115## N-I mksh status: 1
116## N-I mksh stdout-json: ""
117
118#### strip unquoted and quoted [
119# I guess dash and mksh treat unquoted [ as an invalid glob?
120var='[foo]'
121echo ${var#[}
122echo ${var#"["}
123echo "${var#[}"
124echo "${var#"["}"
125## STDOUT:
126foo]
127foo]
128foo]
129foo]
130## END
131## OK mksh STDOUT:
132[foo]
133foo]
134[foo]
135foo]
136## END
137## BUG zsh stdout-json: ""
138## BUG zsh status: 1
139
140#### strip unquoted and quoted []
141# LooksLikeGlob('[]') is true
142# I guess dash, mksh, and zsh treat unquoted [ as an invalid glob?
143var='[]foo[]'
144echo ${var#[]}
145echo ${var#"[]"}
146echo "${var#[]}"
147echo "${var#"[]"}"
148## STDOUT:
149foo[]
150foo[]
151foo[]
152foo[]
153## END
154## OK mksh/zsh STDOUT:
155[]foo[]
156foo[]
157[]foo[]
158foo[]
159## END
160
161#### strip unquoted and quoted ?
162var='[foo]'
163echo ${var#?}
164echo ${var#"?"}
165echo "${var#?}"
166echo "${var#"?"}"
167## STDOUT:
168foo]
169[foo]
170foo]
171[foo]
172## END
173
174#### strip unquoted and quoted [a]
175var='[a]foo[]'
176echo ${var#[a]}
177echo ${var#"[a]"}
178echo "${var#[a]}"
179echo "${var#"[a]"}"
180## STDOUT:
181[a]foo[]
182foo[]
183[a]foo[]
184foo[]
185## END
186
187#### Nested % and # operators (bug reported by Crestwave)
188var=$'\n'
189argv.py "${var#?}"
190argv.py "${var%''}"
191argv.py "${var%"${var#?}"}"
192var='a'
193argv.py "${var#?}"
194argv.py "${var%''}"
195argv.py "${var%"${var#?}"}"
196## STDOUT:
197['']
198['\n']
199['\n']
200['']
201['a']
202['a']
203## END
204## N-I dash STDOUT:
205['\\n']
206['$\\n']
207['$']
208['']
209['a']
210['a']
211## END
212
213#### strip * (bug regression)
214x=abc
215argv.py "${x#*}"
216argv.py "${x##*}"
217argv.py "${x%*}"
218argv.py "${x%%*}"
219## STDOUT:
220['abc']
221['']
222['abc']
223['']
224## END
225## BUG zsh STDOUT:
226['abc']
227['']
228['ab']
229['']
230## END
231
232#### strip ?
233x=abc
234argv.py "${x#?}"
235argv.py "${x##?}"
236argv.py "${x%?}"
237argv.py "${x%%?}"
238## STDOUT:
239['bc']
240['bc']
241['ab']
242['ab']
243## END
244
245#### strip all
246x=abc
247argv.py "${x#abc}"
248argv.py "${x##abc}"
249argv.py "${x%abc}"
250argv.py "${x%%abc}"
251## STDOUT:
252['']
253['']
254['']
255['']
256## END
257
258#### strip none
259x=abc
260argv.py "${x#}"
261argv.py "${x##}"
262argv.py "${x%}"
263argv.py "${x%%}"
264## STDOUT:
265['abc']
266['abc']
267['abc']
268['abc']
269## END
270
271#### strip all unicode
272x=μabcμ
273echo "${x#?abc?}"
274echo "${x##?abc?}"
275echo "${x%?abc?}"
276echo "${x%%?abc?}"
277## STDOUT:
278
279
280
281
282## BUG dash/mksh/ash STDOUT:
283μabcμ
284μabcμ
285μabcμ
286μabcμ
287## END
288
289#### strip none unicode
290x=μabcμ
291argv.py "${x#}"
292argv.py "${x##}"
293argv.py "${x%}"
294argv.py "${x%%}"
295## STDOUT:
296['\xce\xbcabc\xce\xbc']
297['\xce\xbcabc\xce\xbc']
298['\xce\xbcabc\xce\xbc']
299['\xce\xbcabc\xce\xbc']
300## END
301
302#### Strip Right Brace (#702)
303var='$foo'
304echo 1 "${var#$foo}"
305echo 2 "${var#\$foo}"
306
307var='}'
308echo 10 "${var#}}"
309echo 11 "${var#\}}"
310echo 12 "${var#'}'}"
311echo 13 "${var#"}"}"
312## STDOUT:
3131 $foo
3142
31510 }}
31611
31712
31813
319## END
320## BUG zsh STDOUT:
3211 $foo
3222
32310 }}
32411
32512 }'}
32613
327## END
328
329#### \(\) in pattern (regression)
330x='foo()'
331echo 1 ${x%*\(\)}
332echo 2 ${x%%*\(\)}
333echo 3 ${x#*\(\)}
334echo 4 ${x##*\(\)}
335## STDOUT:
3361 foo
3372
3383
3394
340## END
341
342#### extglob in pattern
343case $SH in (dash|zsh|ash) exit ;; esac
344
345shopt -s extglob
346
347x='foo()'
348echo 1 ${x%*(foo|bar)'()'}
349echo 2 ${x%%*(foo|bar)'()'}
350echo 3 ${x#*(foo|bar)'()'}
351echo 4 ${x##*(foo|bar)'()'}
352## STDOUT:
3531 foo
3542
3553
3564
357## END
358## N-I dash/zsh/ash stdout-json: ""