1 #!/bin/bash
2 #
3 # Test matching with case
4 #
5 # Usage:
6 # ./extglob-match.test.sh <function name>
7
8 #### @ matches exactly one
9 shopt -s extglob # needed for Oil, not bash
10 [[ --verbose == --@(help|verbose) ]] && echo TRUE
11 [[ --oops == --@(help|verbose) ]] || echo FALSE
12 ## STDOUT:
13 TRUE
14 FALSE
15 ## END
16
17 #### @() with variable arms
18 shopt -s extglob # needed for Oil, not bash
19 choice1='help'
20 choice2='verbose'
21 [[ --verbose == --@($choice1|$choice2) ]] && echo TRUE
22 [[ --oops == --@($choice1|$choice2) ]] || echo FALSE
23 ## STDOUT:
24 TRUE
25 FALSE
26 ## END
27
28 #### extglob in variable
29 shopt -s extglob
30 g=--@(help|verbose) # this syntax requires extglob in bash!!
31 quoted='--@(help|verbose)'
32 [[ --help == $g ]] && echo TRUE
33 [[ --verbose == $g ]] && echo TRUE
34 [[ -- == $g ]] || echo FALSE
35 [[ --help == $q ]] || echo FALSE
36 [[ -- == $q ]] || echo FALSE
37 ## STDOUT:
38 TRUE
39 TRUE
40 FALSE
41 FALSE
42 FALSE
43 ## END
44 ## N-I mksh STDOUT:
45 FALSE
46 FALSE
47 FALSE
48 ## END
49
50 #### nested @()
51 shopt -s extglob
52 pat='--@(help|verbose|no-@(long|short)-option)'
53 [[ --no-long-option == $pat ]] && echo TRUE
54 [[ --no-short-option == $pat ]] && echo TRUE
55 [[ --help == $pat ]] && echo TRUE
56 [[ --oops == $pat ]] || echo FALSE
57 ## STDOUT:
58 TRUE
59 TRUE
60 TRUE
61 FALSE
62 ## END
63 ## BUG mksh STDOUT:
64 FALSE
65 ## END
66
67 #### nested @() with quotes and vars
68 shopt -s extglob
69 prefix=no
70 [[ --no-long-option == --@(help|verbose|$prefix-@(long|short)-'option') ]] &&
71 echo TRUE
72 ## STDOUT:
73 TRUE
74 ## END
75
76 #### ? matches 0 or 1
77 shopt -s extglob # needed for Oil, not bash
78 [[ -- == --?(help|verbose) ]] && echo TRUE
79 [[ --oops == --?(help|verbose) ]] || echo FALSE
80 ## STDOUT:
81 TRUE
82 FALSE
83 ## END
84
85 #### + matches 1 or more
86 shopt -s extglob # needed for Oil, not bash
87 [[ --helphelp == --+(help|verbose) ]] && echo TRUE
88 [[ -- == --+(help|verbose) ]] || echo FALSE
89 ## STDOUT:
90 TRUE
91 FALSE
92 ## END
93
94 #### * matches 0 or more
95 shopt -s extglob # needed for Oil, not bash
96 [[ -- == --*(help|verbose) ]] && echo TRUE
97 [[ --oops == --*(help|verbose) ]] || echo FALSE
98 ## STDOUT:
99 TRUE
100 FALSE
101 ## END
102
103 #### simple repetition with *(foo) and +(Foo)
104 shopt -s extglob # needed for Oil, not bash
105 [[ foofoo == *(foo) ]] && echo TRUE
106 [[ foofoo == +(foo) ]] && echo TRUE
107 ## STDOUT:
108 TRUE
109 TRUE
110 ## END
111
112 #### ! matches none
113 shopt -s extglob # needed for Oil, not bash
114 [[ --oops == --!(help|verbose) ]] && echo TRUE
115 [[ --help == --!(help|verbose) ]] || echo FALSE
116 ## STDOUT:
117 TRUE
118 FALSE
119 ## END
120
121 #### match is anchored
122 shopt -s extglob # needed for Oil, not bash
123 [[ foo_ == @(foo) ]] || echo FALSE
124 [[ _foo == @(foo) ]] || echo FALSE
125 [[ foo == @(foo) ]] && echo TRUE
126 ## STDOUT:
127 FALSE
128 FALSE
129 TRUE
130 ## END
131
132 #### repeated match is anchored
133 shopt -s extglob # needed for Oil, not bash
134 [[ foofoo_ == +(foo) ]] || echo FALSE
135 [[ _foofoo == +(foo) ]] || echo FALSE
136 [[ foofoo == +(foo) ]] && echo TRUE
137 ## STDOUT:
138 FALSE
139 FALSE
140 TRUE
141 ## END
142
143 #### repetition with glob
144 shopt -s extglob # needed for Oil, not bash
145
146 # NOTE that * means two different things here
147 [[ foofoo_foo__foo___ == *(foo*) ]] && echo TRUE
148 [[ Xoofoo_foo__foo___ == *(foo*) ]] || echo FALSE
149 ## STDOUT:
150 TRUE
151 FALSE
152 ## END
153
154 #### No brace expansion in ==
155 shopt -s extglob # needed for Oil, not bash
156
157 [[ --X{a,b}X == --@(help|X{a,b}X) ]] && echo TRUE
158 [[ --oops == --@(help|X{a,b}X) ]] || echo FALSE
159 ## STDOUT:
160 TRUE
161 FALSE
162 ## END
163
164 #### adjacent extglob
165 shopt -s extglob # needed for Oil, not bash
166
167 [[ --help == @(--|++)@(help|verbose) ]] && echo TRUE
168 [[ ++verbose == @(--|++)@(help|verbose) ]] && echo TRUE
169 ## STDOUT:
170 TRUE
171 TRUE
172 ## END
173
174 #### nested extglob
175 shopt -s extglob # needed for Oil, not bash
176
177 [[ --help == --@(help|verbose=@(1|2)) ]] && echo TRUE
178 [[ --verbose=1 == --@(help|verbose=@(1|2)) ]] && echo TRUE
179 [[ --verbose=2 == --@(help|verbose=@(1|2)) ]] && echo TRUE
180 [[ --verbose == --@(help|verbose=@(1|2)) ]] || echo FALSE
181 ## STDOUT:
182 TRUE
183 TRUE
184 TRUE
185 FALSE
186 ## END
187
188 #### extglob empty string
189 shopt -s extglob
190 [[ '' == @(foo|bar) ]] || echo FALSE
191 [[ '' == @(foo||bar) ]] && echo TRUE
192 ## STDOUT:
193 FALSE
194 TRUE
195 ## END
196
197 #### extglob empty pattern
198 shopt -s extglob
199 [[ '' == @() ]] && echo TRUE
200 [[ '' == @(||) ]] && echo TRUE
201 [[ X == @() ]] || echo FALSE
202 [[ '|' == @(||) ]] || echo FALSE
203 ## STDOUT:
204 TRUE
205 TRUE
206 FALSE
207 FALSE
208 ## END
209
210 #### case with extglob
211 shopt -s extglob
212 for word in --help --verbose --unmatched -- -zxzx -; do
213 case $word in
214 --@(help|verbose) )
215 echo A
216 continue
217 ;;
218 ( --?(b|c) )
219 echo B
220 continue
221 ;;
222 ( -+(x|z) )
223 echo C
224 continue
225 ;;
226 ( -*(x|z) )
227 echo D
228 continue
229 ;;
230 *)
231 echo U
232 continue
233 ;;
234 esac
235 done
236 ## STDOUT:
237 A
238 A
239 U
240 B
241 C
242 D
243 ## END
244
245 #### [[ $x == !($str) ]]
246 shopt -s extglob
247 empty=''
248 str='x'
249 [[ $empty == !($str) ]] && echo TRUE # test glob match
250 [[ $str == !($str) ]] || echo FALSE
251 ## STDOUT:
252 TRUE
253 FALSE
254 ## END
255
256 #### Turning extglob on changes the meaning of [[ !(str) ]] in bash
257 empty=''
258 str='x'
259 [[ !($empty) ]] && echo TRUE # test if $empty is empty
260 [[ !($str) ]] || echo FALSE # test if $str is empty
261 shopt -s extglob # mksh doesn't have this
262 [[ !($empty) ]] && echo TRUE # negated glob
263 [[ !($str) ]] && echo TRUE # negated glob
264 ## STDOUT:
265 TRUE
266 FALSE
267 TRUE
268 TRUE
269 ## END
270 ## OK osh/mksh STDOUT:
271 TRUE
272 TRUE
273 TRUE
274 ## END
275
276 #### With extglob on, !($str) on the left or right of == has different meanings
277 shopt -s extglob
278 empty=''
279 str='x'
280 [[ 1 == !($str) ]] && echo TRUE # glob match
281 [[ !($str) == 1 ]] || echo FALSE # test if empty
282 # NOTE: There cannot be a space between ! and (?
283 ## STDOUT:
284 TRUE
285 FALSE
286 ## END
287
288 #### extglob inside arg word
289 shopt -s extglob
290 [[ foo == @(foo|bar) ]] && echo TRUE
291 [[ foo == ${unset:-@(foo|bar)} ]] && echo TRUE
292 [[ fo == ${unset:-@(foo|bar)} ]] || echo FALSE
293 ## STDOUT:
294 TRUE
295 TRUE
296 FALSE
297 ## END
298 ## BUG mksh STDOUT:
299 TRUE
300 FALSE
301 ## END
302
303 #### extglob is not detected in regex!
304 shopt -s extglob
305 [[ foo =~ ^@(foo|bar)$ ]] || echo FALSE
306 ## STDOUT:
307 FALSE
308 ## END
309 ## N-I mksh stdout-json: ""
310 ## N-I mksh status: 1
311
312
313 #### regular glob of single unicode char
314 shopt -s extglob
315 [[ __a__ == __?__ ]]
316 echo $?
317 [[ __μ__ == __?__ ]]
318 echo $?
319 ## STDOUT:
320 0
321 0
322 ## END
323 ## BUG mksh STDOUT:
324 0
325 1
326 ## END
327
328 #### extended glob of single unicode char
329 shopt -s extglob
330 [[ __a__ == @(__?__) ]]
331 echo $?
332 [[ __μ__ == @(__?__) ]]
333 echo $?
334 ## STDOUT:
335 0
336 0
337 ## END
338 ## BUG mksh STDOUT:
339 0
340 1
341 ## END