xref: /titanic_44/usr/src/lib/libshell/common/tests/glob.sh (revision cb8a054b1ab30d5caa746e6c44f29d4c9d3071c1)
1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                  Common Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#            http://www.opensource.org/licenses/cpl1.0.txt             #
11#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                  David Korn <dgk@research.att.com>                   #
18#                                                                      #
19########################################################################
20function err_exit
21{
22	print -u2 -r $'\t'"${Command}[$1] ${@:2}"
23	((errors++))
24}
25alias err_exit='err_exit $LINENO'
26
27Command=${0##*/}
28integer aware=0 contrary=0 errors=0 ignorant=0
29
30tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
31trap "cd /; rm -rf $tmp" EXIT
32
33function test_glob
34{
35	typeset lineno expected drop arg got sep op val add del
36	lineno=$1
37	shift
38	if	[[ $1 == --* ]]
39	then	del=${1#--}
40		shift
41	fi
42	if	[[ $1 == ++* ]]
43	then	add=${1#++}
44		shift
45	fi
46	expected=$1
47	shift
48	if	(( contrary ))
49	then	if	[[ $expected == "<Beware> "* ]]
50		then	expected=${expected#"<Beware> "}
51			expected="$expected <Beware>"
52		fi
53		if	[[ $expected == *"<aXb> <abd>"* ]]
54		then	expected=${expected/"<aXb> <abd>"/"<abd> <aXb>"}
55		fi
56	fi
57	for arg
58	do	got="$got$sep<$arg>"
59		sep=" "
60	done
61	if	(( ignorant && aware ))
62	then	if	[[ $del ]]
63		then	got="<$del> $got"
64		fi
65		if	[[ $add ]]
66		then	expected="<$add> $expected"
67		fi
68	fi
69	if	[[ $got != "$expected" ]]
70	then	'err_exit' $lineno "glob -- expected '$expected', got '$got'"
71	fi
72}
73alias test_glob='test_glob $LINENO'
74
75function test_case
76{
77	typeset lineno expected subject pattern got
78	lineno=$1 expected=$2 subject=$3 pattern=$4
79	eval "
80		case $subject in
81		$pattern)	got='<match>' ;;
82		*)		got='<nomatch>' ;;
83		esac
84	"
85	if	[[ $got != "$expected" ]]
86	then	'err_exit' $lineno "case $subject in $pattern) -- expected '$expected', got '$got'"
87	fi
88}
89alias test_case='test_case $LINENO'
90
91unset undefined
92
93export LC_COLLATE=C
94
95cd $tmp || { err_exit "cd $tmp failed"; exit 1; }
96
97touch B b
98set -- *
99case $* in
100'b B')	contrary=1 ;;
101b|B)	ignorant=1 ;;
102esac
103set -- $(/bin/sh -c 'echo [a-c]')
104case $* in
105B)	aware=1 ;;
106esac
107rm -rf *
108
109touch a b c d abc abd abe bb bcd ca cb dd de Beware
110mkdir bdir
111
112test_glob '<a> <abc> <abd> <abe> <X*>' a* X*
113test_glob '<a> <abc> <abd> <abe>' \a*
114
115if	( set --nullglob ) 2>/dev/null
116then
117	set --nullglob
118
119	test_glob '<a> <abc> <abd> <abe>' a* X*
120
121	set --nonullglob
122fi
123
124if	( set --failglob ) 2>/dev/null
125then
126	set --failglob
127	mkdir tmp
128	touch tmp/l1 tmp/l2 tmp/l3
129
130	test_glob '' tmp/l[12] tmp/*4 tmp/*3
131	test_glob '' tmp/l[12] tmp/*4 tmp/*3
132
133	rm -r tmp
134	set --nofailglob
135fi
136
137test_glob '<bdir/>' b*/
138test_glob '<*>' \*
139test_glob '<a*>' 'a*'
140test_glob '<a*>' a\*
141test_glob '<c> <ca> <cb> <a*> <*q*>' c* a\* *q*
142test_glob '<**>' "*"*
143test_glob '<**>' \**
144test_glob '<\.\./*/>' "\.\./*/"
145test_glob '<s/\..*//>' 's/\..*//'
146test_glob '</^root:/{s/^[!:]*:[!:]*:\([!:]*\).*$/\1/>' "/^root:/{s/^[!:]*:[!:]*:\([!:]*\).*"'$'"/\1/"
147test_glob '<abc> <abd> <abe> <bb> <cb>' [a-c]b*
148test_glob ++Beware '<abd> <abe> <bb> <bcd> <bdir> <ca> <cb> <dd> <de>' [a-y]*[!c]
149test_glob '<abd> <abe>' a*[!c]
150
151touch a-b aXb
152
153test_glob '<a-b> <aXb>' a[X-]b
154
155touch .x .y
156
157test_glob --Beware '<Beware> <d> <dd> <de>' [!a-c]*
158
159if	mkdir a\*b 2>/dev/null
160then
161	touch a\*b/ooo
162
163	test_glob '<a*b/ooo>' a\*b/*
164	test_glob '<a*b/ooo>' a\*?/*
165	test_case '<match>' '!7' '*\!*'
166	test_case '<match>' 'r.*' '*.\*'
167	test_glob '<abc>' a[b]c
168	test_glob '<abc>' a["b"]c
169	test_glob '<abc>' a[\b]c
170	test_glob '<abc>' a?c
171	test_case '<match>' 'abc' 'a"b"c'
172	test_case '<match>' 'abc' 'a*c'
173	test_case '<nomatch>' 'abc' '"a?c"'
174	test_case '<nomatch>' 'abc' 'a\*c'
175	test_case '<nomatch>' 'abc' 'a\[b]c'
176	test_case '<match>' '"$undefined"' '""'
177	test_case '<match>' 'abc' 'a["\b"]c'
178
179	rm -rf mkdir a\*b
180fi
181
182mkdir man
183mkdir man/man1
184touch man/man1/sh.1
185
186test_glob '<man/man1/sh.1>' */man*/sh.*
187test_glob '<man/man1/sh.1>' $(echo */man*/sh.*)
188test_glob '<man/man1/sh.1>' "$(echo */man*/sh.*)"
189
190test_case '<match>' 'abc' 'a***c'
191test_case '<match>' 'abc' 'a*****?c'
192test_case '<match>' 'abc' '?*****??'
193test_case '<match>' 'abc' '*****??'
194test_case '<match>' 'abc' '*****??c'
195test_case '<match>' 'abc' '?*****?c'
196test_case '<match>' 'abc' '?***?****c'
197test_case '<match>' 'abc' '?***?****?'
198test_case '<match>' 'abc' '?***?****'
199test_case '<match>' 'abc' '*******c'
200test_case '<match>' 'abc' '*******?'
201test_case '<match>' 'abcdecdhjk' 'a*cd**?**??k'
202test_case '<match>' 'abcdecdhjk' 'a**?**cd**?**??k'
203test_case '<match>' 'abcdecdhjk' 'a**?**cd**?**??k***'
204test_case '<match>' 'abcdecdhjk' 'a**?**cd**?**??***k'
205test_case '<match>' 'abcdecdhjk' 'a**?**cd**?**??***k**'
206test_case '<match>' 'abcdecdhjk' 'a****c**?**??*****'
207test_case '<match>' "'-'" '[-abc]'
208test_case '<match>' "'-'" '[abc-]'
209test_case '<match>' "'\\'" '\\'
210test_case '<match>' "'\\'" '[\\]'
211test_case '<match>' "'\\'" "'\\'"
212test_case '<match>' "'['" '[[]'
213test_case '<match>' '[' '[[]'
214test_case '<match>' "'['" '['
215test_case '<match>' '[' '['
216test_case '<match>' "'[abc'" "'['*"
217test_case '<nomatch>' "'[abc'" '[*'
218test_case '<match>' '[abc' "'['*"
219test_case '<nomatch>' '[abc' '[*'
220test_case '<match>' 'abd' "a[b/c]d"
221test_case '<match>' 'a/d' "a[b/c]d"
222test_case '<match>' 'acd' "a[b/c]d"
223test_case '<match>' "']'" '[]]'
224test_case '<match>' "'-'" '[]-]'
225test_case '<match>' 'p' '[a-\z]'
226test_case '<match>' '"/tmp"' '[/\\]*'
227test_case '<nomatch>' 'abc' '??**********?****?'
228test_case '<nomatch>' 'abc' '??**********?****c'
229test_case '<nomatch>' 'abc' '?************c****?****'
230test_case '<nomatch>' 'abc' '*c*?**'
231test_case '<nomatch>' 'abc' 'a*****c*?**'
232test_case '<nomatch>' 'abc' 'a********???*******'
233test_case '<nomatch>' "'a'" '[]'
234test_case '<nomatch>' 'a' '[]'
235test_case '<nomatch>' "'['" '[abc'
236test_case '<nomatch>' '[' '[abc'
237
238test_glob ++Beware '<b> <bb> <bcd> <bdir>' b*
239test_glob '<Beware> <b> <bb> <bcd> <bdir>' [bB]*
240
241if	( set --nocaseglob ) 2>/dev/null
242then
243	set --nocaseglob
244
245	test_glob '<Beware> <b> <bb> <bcd> <bdir>' b*
246	test_glob '<Beware> <b> <bb> <bcd> <bdir>' [b]*
247	test_glob '<Beware> <b> <bb> <bcd> <bdir>' [bB]*
248
249	set --nonocaseglob
250fi
251
252if	( set -f ) 2>/dev/null
253then
254	set -f
255
256	test_glob '<*>' *
257
258	set +f
259fi
260
261if	( set --noglob ) 2>/dev/null
262then
263	set --noglob
264
265	test_glob '<*>' *
266
267	set --glob
268fi
269
270FIGNORE='.*|*'
271test_glob '<*>' *
272
273FIGNORE='.*|*c|*e|?'
274test_glob '<a-b> <aXb> <abd> <bb> <bcd> <bdir> <ca> <cb> <dd> <man>' *
275
276FIGNORE='.*|*b|*d|?'
277test_glob '<Beware> <abc> <abe> <bdir> <ca> <de> <man>' *
278
279FIGNORE=
280test_glob '<man/man1/sh.1>' */man*/sh.*
281
282unset FIGNORE
283test_glob '<bb> <ca> <cb> <dd> <de>' ??
284test_glob '<man/man1/sh.1>' */man*/sh.*
285
286GLOBIGNORE='.*:*'
287set -- *
288if	[[ $1 == '*' ]]
289then
290	GLOBIGNORE='.*:*c:*e:?'
291	test_glob '<>' *
292
293	GLOBIGNORE='.*:*b:*d:?'
294	test_glob '<>' *
295
296	unset GLOBIGNORE
297	test_glob '<>' *
298	test_glob '<man/man1/sh.1>' */man*/sh.*
299
300	GLOBIGNORE=
301	test_glob '<man/man1/sh.1>' */man*/sh.*
302fi
303unset GLOBIGNORE
304
305function test_sub
306{
307	x='${subject'$2'}'
308	eval g=$x
309	if	[[ "$g" != "$3" ]]
310	then	'err_exit' $1 subject="'$subject' $x failed, expected '$3', got '$g'"
311	fi
312}
313alias test_sub='test_sub $LINENO'
314
315set --noglob --nobraceexpand
316
317subject='A regular expressions test'
318
319test_sub '/e/#'               'A r#gular expressions test'
320test_sub '//e/#'              'A r#gular #xpr#ssions t#st'
321test_sub '/[^e]/#'            '# regular expressions test'
322test_sub '//[^e]/#'           '###e######e###e########e##'
323test_sub '/+(e)/#'            'A r#gular expressions test'
324test_sub '//+(e)/#'           'A r#gular #xpr#ssions t#st'
325test_sub '/@-(e)/#'           'A r#gular expressions test'
326test_sub '//@-(e)/#'          'A r#gular #xpr#ssions t#st'
327test_sub '/?(e)/#'            '#A regular expressions test'
328test_sub '//?(e)/#'           '#A# #r#g#u#l#a#r# #x#p#r#s#s#i#o#n#s# #t#s#t#'
329test_sub '/*(e)/#'            '#A regular expressions test'
330test_sub '//*(e)/#'           '#A# #r#g#u#l#a#r# #x#p#r#s#s#i#o#n#s# #t#s#t#'
331test_sub '//@(e)/[\1]'        'A r[e]gular [e]xpr[e]ssions t[e]st'
332test_sub '//@-(e)/[\1]'       'A r[e]gular [e]xpr[e]ssions t[e]st'
333test_sub '//+(e)/[\1]'        'A r[e]gular [e]xpr[e]ssions t[e]st'
334test_sub '//+-(e)/[\1]'       'A r[e]gular [e]xpr[e]ssions t[e]st'
335test_sub '//@(+(e))/[\1]'     'A r[e]gular [e]xpr[e]ssions t[e]st'
336test_sub '//@(+-(e))/[\1]'    'A r[e]gular [e]xpr[e]ssions t[e]st'
337test_sub '//-(e)/#'           'A regular expressions test'
338test_sub '//--(e)/#'          'A regular expressions test'
339test_sub '//?(e)/[\1]'        '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
340test_sub '//{0,1}(e)/[\1]'    '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
341test_sub '//*(e)/[\1]'        '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
342test_sub '//{0,}(e)/[\1]'     '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
343test_sub '//@(?(e))/[\1]'     '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
344test_sub '//@({0,1}(e))/[\1]' '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
345test_sub '//@(*(e))/[\1]'     '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
346test_sub '//@({0,}(e))/[\1]'  '[]A[] []r[e]g[]u[]l[]a[]r[] [e]x[]p[]r[e]s[]s[]i[]o[]n[]s[] []t[e]s[]t[]'
347test_sub '/?-(e)/#'           '#A regular expressions test'
348test_sub '/@(?-(e))/[\1]'     '[]A regular expressions test'
349test_sub '/!(e)/#'            '#'
350test_sub '//!(e)/#'           '#'
351test_sub '/@(!(e))/[\1]'      '[A regular expressions test]'
352test_sub '//@(!(e))/[\1]'     '[A regular expressions test]'
353
354subject='e'
355
356test_sub '/!(e)/#'            '#e'
357test_sub '//!(e)/#'           '#e#'
358test_sub '/!(e)/[\1]'         '[]e'
359test_sub '//!(e)/[\1]'        '[]e[]'
360test_sub '/@(!(e))/[\1]'      '[]e'
361test_sub '//@(!(e))/[\1]'     '[]e[]'
362
363subject='a'
364
365test_sub '/@(!(a))/[\1]'      '[]a'
366test_sub '//@(!(a))/[\1]'     '[]a[]'
367
368subject='aha'
369
370test_sub '/@(!(a))/[\1]'      '[aha]'
371test_sub '//@(!(a))/[\1]'     '[aha]'
372test_sub '/@(!(aha))/[\1]'    '[ah]a'
373test_sub '//@(!(aha))/[\1]'   '[ah][a]'
374
375exit $errors
376