xref: /titanic_41/usr/src/lib/libshell/common/tests/substring.sh (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4*3e14f97fSRoger A. Faulkner#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6da2e3ebdSchin#                  Common Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10da2e3ebdSchin#            http://www.opensource.org/licenses/cpl1.0.txt             #
11da2e3ebdSchin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12da2e3ebdSchin#                                                                      #
13da2e3ebdSchin#              Information and Software Systems Research               #
14da2e3ebdSchin#                            AT&T Research                             #
15da2e3ebdSchin#                           Florham Park NJ                            #
16da2e3ebdSchin#                                                                      #
17da2e3ebdSchin#                  David Korn <dgk@research.att.com>                   #
18da2e3ebdSchin#                                                                      #
19da2e3ebdSchin########################################################################
20da2e3ebdSchinfunction err_exit
21da2e3ebdSchin{
22da2e3ebdSchin	print -u2 -n "\t"
23da2e3ebdSchin	print -u2 -r ${Command}[$1]: "${@:2}"
24da2e3ebdSchin	let Errors+=1
25da2e3ebdSchin}
26da2e3ebdSchinalias err_exit='err_exit $LINENO'
27da2e3ebdSchin
28da2e3ebdSchinCommand=${0##*/}
29da2e3ebdSchininteger Errors=0 j=4
30da2e3ebdSchinbase=/home/dgk/foo//bar
31da2e3ebdSchinstring1=$base/abcabcabc
32da2e3ebdSchinif	[[ ${string1:0} != "$string1" ]]
33da2e3ebdSchinthen	err_exit "string1:0"
34da2e3ebdSchinfi
35da2e3ebdSchinif	[[ ${string1: -1} != "c" ]]
36da2e3ebdSchinthen	err_exit "string1: -1"
37da2e3ebdSchinfi
38da2e3ebdSchinif	[[ ${string1:0:1000} != "$string1" ]]
39da2e3ebdSchinthen	err_exit "string1:0"
40da2e3ebdSchinfi
41da2e3ebdSchinif	[[ ${string1:1} != "${string1#?}" ]]
42da2e3ebdSchinthen	err_exit "string1:1"
43da2e3ebdSchinfi
44da2e3ebdSchinif	[[ ${string1:1:4} != home ]]
45da2e3ebdSchinthen	err_exit "string1:1:4"
46da2e3ebdSchinfi
47da2e3ebdSchinif	[[ ${string1: -5:4} != bcab ]]
48da2e3ebdSchinthen	err_exit "string1: -5:4"
49da2e3ebdSchinfi
50da2e3ebdSchinif	[[ ${string1:1:j} != home ]]
51da2e3ebdSchinthen	err_exit "string1:1:j"
52da2e3ebdSchinfi
53da2e3ebdSchinif	[[ ${string1:(j?1:0):j} != home ]]
54da2e3ebdSchinthen	err_exit "string1:(j?1:0):j"
55da2e3ebdSchinfi
56da2e3ebdSchinif	[[ ${string1%*zzz*} != "$string1" ]]
57da2e3ebdSchinthen	err_exit "string1%*zzz*"
58da2e3ebdSchinfi
59da2e3ebdSchinif	[[ ${string1%%*zzz*} != "$string1" ]]
60da2e3ebdSchinthen	err_exit "string1%%*zzz*"
61da2e3ebdSchinfi
62da2e3ebdSchinif	[[ ${string1#*zzz*} != "$string1" ]]
63da2e3ebdSchinthen	err_exit "string1#*zzz*"
64da2e3ebdSchinfi
65da2e3ebdSchinif	[[ ${string1##*zzz*} != "$string1" ]]
66da2e3ebdSchinthen	err_exit "string1##*zzz*"
67da2e3ebdSchinfi
68da2e3ebdSchinif	[[ ${string1%+(abc)} != "$base/abcabc" ]]
69da2e3ebdSchinthen	err_exit "string1%+(abc)"
70da2e3ebdSchinfi
71da2e3ebdSchinif	[[ ${string1%%+(abc)} != "$base/" ]]
72da2e3ebdSchinthen	err_exit "string1%%+(abc)"
73da2e3ebdSchinfi
74da2e3ebdSchinif	[[ ${string1%/*} != "$base" ]]
75da2e3ebdSchinthen	err_exit "string1%/*"
76da2e3ebdSchinfi
77da2e3ebdSchinif	[[ "${string1%/*}" != "$base" ]]
78da2e3ebdSchinthen	err_exit '"string1%/*"'
79da2e3ebdSchinfi
80da2e3ebdSchinif	[[ ${string1%"/*"} != "$string1" ]]
81da2e3ebdSchinthen	err_exit 'string1%"/*"'
82da2e3ebdSchinfi
83da2e3ebdSchinif	[[ ${string1%%/*} != "" ]]
84da2e3ebdSchinthen	err_exit "string1%%/*"
85da2e3ebdSchinfi
86da2e3ebdSchinif	[[ ${string1#*/bar} != /abcabcabc ]]
87da2e3ebdSchinthen	err_exit "string1#*bar"
88da2e3ebdSchinfi
89da2e3ebdSchinif	[[ ${string1##*/bar} != /abcabcabc ]]
90da2e3ebdSchinthen	err_exit "string1#*bar"
91da2e3ebdSchinfi
92da2e3ebdSchinif	[[ "${string1#@(*/bar|*/foo)}" != //bar/abcabcabc ]]
93da2e3ebdSchinthen	err_exit "string1#@(*/bar|*/foo)"
94da2e3ebdSchinfi
95da2e3ebdSchinif	[[ ${string1##@(*/bar|*/foo)} != /abcabcabc ]]
96da2e3ebdSchinthen	err_exit "string1##@(*/bar|*/foo)"
97da2e3ebdSchinfi
98da2e3ebdSchinif	[[ ${string1##*/@(bar|foo)} != /abcabcabc ]]
99da2e3ebdSchinthen	err_exit "string1##*/@(bar|foo)"
100da2e3ebdSchinfi
101da2e3ebdSchinfoo=abc
102da2e3ebdSchinif	[[ ${foo#a[b*} != abc ]]
103da2e3ebdSchinthen	err_exit "abc#a[b*} != abc"
104da2e3ebdSchinfi
105da2e3ebdSchinif	[[ ${foo//[0-9]/bar} != abc ]]
106da2e3ebdSchinthen	err_exit '${foo//[0-9]/bar} not expanding correctly'
107da2e3ebdSchinfi
108da2e3ebdSchinfoo='(abc)'
109da2e3ebdSchinif	[[ ${foo#'('} != 'abc)' ]]
110da2e3ebdSchinthen	err_exit "(abc)#( != abc)"
111da2e3ebdSchinfi
112da2e3ebdSchinif	[[ ${foo%')'} != '(abc' ]]
113da2e3ebdSchinthen	err_exit "(abc)%) != (abc"
114da2e3ebdSchinfi
115da2e3ebdSchinfoo=a123b456c
116da2e3ebdSchinif	[[ ${foo/[0-9]?/""} != a3b456c ]]
117da2e3ebdSchinthen	err_exit '${foo/[0-9]?/""} not expanding correctly'
118da2e3ebdSchinfi
119da2e3ebdSchinif	[[ ${foo//[0-9]/""} != abc ]]
120da2e3ebdSchinthen	err_exit '${foo//[0-9]/""} not expanding correctly'
121da2e3ebdSchinfi
122da2e3ebdSchinif	[[ ${foo/#a/b} != b123b456c ]]
123da2e3ebdSchinthen	err_exit '${foo/#a/b} not expanding correctly'
124da2e3ebdSchinfi
125da2e3ebdSchinif	[[ ${foo/#?/b} != b123b456c ]]
126da2e3ebdSchinthen	err_exit '${foo/#?/b} not expanding correctly'
127da2e3ebdSchinfi
128da2e3ebdSchinif	[[ ${foo/%c/b} != a123b456b ]]
129da2e3ebdSchinthen	err_exit '${foo/%c/b} not expanding correctly'
130da2e3ebdSchinfi
131da2e3ebdSchinif	[[ ${foo/%?/b} != a123b456b ]]
132da2e3ebdSchinthen	err_exit '${foo/%?/b} not expanding correctly'
133da2e3ebdSchinfi
134da2e3ebdSchinwhile read -r pattern string expected
135da2e3ebdSchindo	if	(( expected ))
136da2e3ebdSchin	then	if	[[ $string != $pattern ]]
137da2e3ebdSchin		then	err_exit "$pattern does not match $string"
138da2e3ebdSchin		fi
139da2e3ebdSchin		if	[[ ${string##$pattern} != "" ]]
140da2e3ebdSchin		then	err_exit "\${$string##$pattern} not null"
141da2e3ebdSchin		fi
142da2e3ebdSchin		if	[ "${string##$pattern}" != '' ]
143da2e3ebdSchin		then	err_exit "\"\${$string##$pattern}\" not null"
144da2e3ebdSchin		fi
145da2e3ebdSchin		if	[[ ${string/$pattern} != "" ]]
146da2e3ebdSchin		then	err_exit "\${$string/$pattern} not null"
147da2e3ebdSchin		fi
148da2e3ebdSchin	else	if	[[ $string == $pattern ]]
149da2e3ebdSchin		then	err_exit "$pattern matches $string"
150da2e3ebdSchin		fi
151da2e3ebdSchin	fi
152da2e3ebdSchindone <<- \EOF
153da2e3ebdSchin	+(a)*+(a)	aabca	1
154da2e3ebdSchin	!(*.o)		foo.o	0
155da2e3ebdSchin	!(*.o)		foo.c	1
156da2e3ebdSchinEOF
157da2e3ebdSchinxx=a/b/c/d/e
158da2e3ebdSchinyy=${xx#*/}
159da2e3ebdSchinif	[[ $yy != b/c/d/e ]]
160da2e3ebdSchinthen	err_exit '${xx#*/} != a/b/c/d/e when xx=a/b/c/d/e'
161da2e3ebdSchinfi
162da2e3ebdSchinif	[[ ${xx//\//\\} != 'a\b\c\d\e' ]]
163da2e3ebdSchinthen	err_exit '${xx//\//\\} not working'
164da2e3ebdSchinfi
165da2e3ebdSchinx=[123]def
166da2e3ebdSchinif	[[ "${x//\[(*)\]/\{\1\}}" != {123}def ]]
167da2e3ebdSchinthen	err_exit 'closing brace escape not working'
168da2e3ebdSchinfi
1697c2fbfb3SApril Chinxx=%28text%29
1707c2fbfb3SApril Chinif	[[ ${xx//%28/abc\)} != 'abc)text%29' ]]
1717c2fbfb3SApril Chinthen	 err_exit '${xx//%28/abc\)} not working'
1727c2fbfb3SApril Chinfi
1737c2fbfb3SApril Chinxx='a:b'
1747c2fbfb3SApril Chinstr='(){}[]*?|&^%$#@l'
1757c2fbfb3SApril Chinfor ((i=0 ; i < ${#str}; i++))
1767c2fbfb3SApril Chindo      [[ $(eval print -r -- \"\${xx//:/\\${str:i:1}}\") == "a${str:i:1}b" ]] || err_exit "substitution of \\${str:i:1}} failed"
1777c2fbfb3SApril Chin        [[ $(eval print -rn -- \"\${xx//:/\'${str:i:1}\'}\") == "a${str:i:1}b" ]] || err_exit "substitution of '${str:i:1}' failed"
1787c2fbfb3SApril Chin        [[ $(eval print -r -- \"\${xx//:/\"${str:i:1}\"}\") == "a${str:i:1}b" ]] || err_exit "substitution of \"${str:i:1}\" failed"
1797c2fbfb3SApril Chindone
1807c2fbfb3SApril Chin[[ ${xx//:/\\n} == 'a\nb' ]]  || err_exit "substituion of \\\\n failed"
1817c2fbfb3SApril Chin[[ ${xx//:/'\n'} == 'a\nb' ]] || err_exit "substituion of '\\n' failed"
1827c2fbfb3SApril Chin[[ ${xx//:/"\n"} ==  'a\nb' ]] || err_exit "substituion of \"\\n\" failed"
1837c2fbfb3SApril Chin[[ ${xx//:/$'\n'} ==  $'a\nb' ]] || err_exit "substituion of \$'\\n' failed"
184da2e3ebdSchinunset foo
185da2e3ebdSchinfoo=one/two/three
186da2e3ebdSchinif	[[ ${foo//'/'/_} != one_two_three ]]
187da2e3ebdSchinthen	err_exit 'single quoting / in replacements failed'
188da2e3ebdSchinfi
189da2e3ebdSchinif	[[ ${foo//"/"/_} != one_two_three ]]
190da2e3ebdSchinthen	err_exit 'double quoting / in replacements failed'
191da2e3ebdSchinfi
192da2e3ebdSchinif	[[ ${foo//\//_} != one_two_three ]]
193da2e3ebdSchinthen	err_exit 'escaping / in replacements failed'
194da2e3ebdSchinfi
195da2e3ebdSchinfunction myexport
196da2e3ebdSchin{
197da2e3ebdSchin	nameref var=$1
198da2e3ebdSchin	if	(( $# > 1 ))
199da2e3ebdSchin	then	export	$1=$2
200da2e3ebdSchin	fi
201da2e3ebdSchin	if	(( $# > 2 ))
202da2e3ebdSchin	then	print $(myexport "$1" "$3" )
203da2e3ebdSchin		return
204da2e3ebdSchin	fi
205da2e3ebdSchin	typeset val
206da2e3ebdSchin	val=$(export | grep "^$1=")
207da2e3ebdSchin	print ${val#"$1="}
208da2e3ebdSchin
209da2e3ebdSchin}
210da2e3ebdSchinexport dgk=base
211da2e3ebdSchinif	[[ $(myexport dgk fun) != fun ]]
212da2e3ebdSchinthen	err_exit 'export inside function not working'
213da2e3ebdSchinfi
214da2e3ebdSchinval=$(export | grep "^dgk=")
215da2e3ebdSchinif	[[ ${val#dgk=} != base ]]
216da2e3ebdSchinthen	err_exit 'export not restored after function call'
217da2e3ebdSchinfi
218da2e3ebdSchinif	[[ $(myexport dgk fun fun2) != fun2 ]]
219da2e3ebdSchinthen	err_exit 'export inside function not working with recursive function'
220da2e3ebdSchinfi
221da2e3ebdSchinval=$(export | grep "^dgk=")
222da2e3ebdSchinif	[[ ${val#dgk=} != base ]]
223da2e3ebdSchinthen	err_exit 'export not restored after recursive function call'
224da2e3ebdSchinfi
225da2e3ebdSchinif	[[ $(dgk=try3 myexport dgk) != try3 ]]
226da2e3ebdSchinthen	err_exit 'name=value not added to export list with function call'
227da2e3ebdSchinfi
228da2e3ebdSchinval=$(export | grep "^dgk=")
229da2e3ebdSchinif	[[ ${val#dgk=} != base ]]
230da2e3ebdSchinthen	err_exit 'export not restored name=value function call'
231da2e3ebdSchinfi
232da2e3ebdSchinunset zzz
233da2e3ebdSchinif	[[ $(myexport zzz fun) != fun ]]
234da2e3ebdSchinthen	err_exit 'export inside function not working for zzz'
235da2e3ebdSchinfi
236da2e3ebdSchinif	[[ $(export | grep "zzz=") ]]
237da2e3ebdSchinthen	err_exit 'zzz exported after function call'
238da2e3ebdSchinfi
239da2e3ebdSchinset -- foo/bar bam/yes last/file/done
240da2e3ebdSchinif	[[ ${@/*\/@(*)/${.sh.match[1]}} != 'bar yes done' ]]
241da2e3ebdSchinthen	err_exit '.sh.match not working with $@'
242da2e3ebdSchinfi
243da2e3ebdSchinif	[[ ${@/*\/@(*)/\1} != 'bar yes done' ]]
244da2e3ebdSchinthen	err_exit '\1 not working with $@'
245da2e3ebdSchinfi
246da2e3ebdSchinvar=(foo/bar bam/yes last/file/done)
247da2e3ebdSchinif	[[ ${var[@]/*\/@(*)/${.sh.match[1]}} != 'bar yes done' ]]
248da2e3ebdSchinthen	err_exit '.sh.match not working with ${var[@]}'
249da2e3ebdSchinfi
250da2e3ebdSchinif	[[ ${var[@]/*\/@(*)/\1} != 'bar yes done' ]]
251da2e3ebdSchinthen	err_exit '\1 not working with ${var[@]}'
252da2e3ebdSchinfi
253da2e3ebdSchinvar='abc_d2ef.462abc %%'
254da2e3ebdSchinif	[[ ${var/+(\w)/Q} != 'Q.462abc %%' ]]
255da2e3ebdSchinthen	err_exit '${var/+(\w)/Q} not workding'
256da2e3ebdSchinfi
257da2e3ebdSchinif	[[ ${var//+(\w)/Q} != 'Q.Q %%' ]]
258da2e3ebdSchinthen	err_exit '${var//+(\w)/Q} not workding'
259da2e3ebdSchinfi
260da2e3ebdSchinif	[[ ${var//+(\S)/Q} != 'Q Q' ]]
261da2e3ebdSchinthen	err_exit '${var//+(\S)/Q} not workding'
262da2e3ebdSchinfi
263da2e3ebdSchinfoo='foo+bar+'
264da2e3ebdSchin[[ $(print -r -- ${foo//+/'|'}) != 'foo|bar|' ]] && err_exit "\${foobar//+/'|'}"
265da2e3ebdSchin[[ $(print -r -- ${foo//+/"|"}) != 'foo|bar|' ]] && err_exit '${foobar//+/"|"}'
266da2e3ebdSchin[[ $(print -r -- "${foo//+/'|'}") != 'foo|bar|' ]] && err_exit '"${foobar//+/'"'|'"'}"'
267da2e3ebdSchin[[ $(print -r -- "${foo//+/"|"}") != 'foo|bar|' ]] && err_exit '"${foobar//+/"|"}"'
268da2e3ebdSchinunset x
269da2e3ebdSchinx=abcedfg
270da2e3ebdSchin: ${x%@(d)f@(g)}
271da2e3ebdSchin[[ ${.sh.match[0]} == dfg ]] || err_exit '.sh.match[0] not dfg'
272da2e3ebdSchin[[ ${.sh.match[1]} == d ]] || err_exit '.sh.match[1] not d'
273da2e3ebdSchin[[ ${.sh.match[2]} == g ]] || err_exit '.sh.match[2] not g'
274da2e3ebdSchinx=abcedddfg
275da2e3ebdSchin: ${x%%+(d)f@(g)}
276da2e3ebdSchin[[ ${.sh.match[1]} == ddd ]] || err_exit '.sh.match[1] not ddd'
277da2e3ebdSchinunset a b
278da2e3ebdSchina='\[abc @(*) def\]'
279da2e3ebdSchinb='[abc 123 def]'
280da2e3ebdSchin[[ ${b//$a/\1} == 123 ]] || err_exit "\${var/pattern} not working with \[ in pattern"
2817c2fbfb3SApril Chinunset foo
2827c2fbfb3SApril Chinfoo='(win32.i386) '
2837c2fbfb3SApril Chin[[ ${foo/'('/'(x11-'} == '(x11-win32.i386) ' ]] || err_exit "\${var/pattern} not working with ' in pattern"
2847c2fbfb3SApril Chin$SHELL -c $'v=\'$(hello)\'; [[ ${v//\'$(\'/-I\'$(\'} == -I"$v" ]]' 2> /dev/null || err_exit "\${var/pattern} not working with \$( as pattern"
285da2e3ebdSchinunset X
286da2e3ebdSchin$SHELL -c '[[ ! ${X[@]:0:300} ]]' 2> /dev/null || err_exit '${X[@]:0:300} with X undefined fails'
287da2e3ebdSchin$SHELL -c '[[ ${@:0:300} == "$0" ]]' 2> /dev/null || err_exit '${@:0:300} with no arguments fails'
288da2e3ebdSchini=20030704
289da2e3ebdSchin[[ ${i#{6}(?)} == 04 ]] ||  err_exit '${i#{6}(?)} not working'
290da2e3ebdSchin[[ ${i#{6,6}(?)} == 04 ]] ||  err_exit '${i#{6,6}(?)} not working'
291da2e3ebdSchinLC_ALL=posix
292da2e3ebdSchini="   ."
293da2e3ebdSchin[[ $(printf "<%s>\n" ${i#' '}) == '<.>' ]] || err_exit 'printf "<%s>\n" ${i#' '} failed'
294da2e3ebdSchinunset x
295da2e3ebdSchinx=foo
296da2e3ebdSchin[[ "${x%o}(1)" == "fo(1)" ]] ||  err_exit 'print ${}() treated as pattern'
297da2e3ebdSchinunset i pattern string
298da2e3ebdSchinstring=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz
299da2e3ebdSchininteger i
300da2e3ebdSchinfor((i=0; i < ${#string}; i++))
301da2e3ebdSchindo	pattern+='@(?)'
302da2e3ebdSchindone
303da2e3ebdSchin[[ $(string=$string $SHELL -c  ": \${string/$pattern/}; print \${.sh.match[26]}") == Z ]] || err_exit -u2 'sh.match[26] not Z'
304da2e3ebdSchin: ${string/$pattern/}
305da2e3ebdSchin(( ${#.sh.match[@]} == 53 )) || err_exit '.sh.match has wrong number of elements'
306da2e3ebdSchin[[ ${.sh.match[@]:2:4} == 'B C D E'  ]] || err_exit '${.sh.match[@]:2:4} incorrect'
307da2e3ebdSchin
308da2e3ebdSchinD=$';' E=$'\\\\' Q=$'"' S=$'\'' M='nested pattern substitution failed'
309da2e3ebdSchin
310da2e3ebdSchinx='-(-)-'
311da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
312da2e3ebdSchinx='-(-)-)-'
313da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
314da2e3ebdSchinx='-(-()-)-'
315da2e3ebdSchin[[ ${x/*%(())*/\1} == '()' ]] || err_exit $M
316da2e3ebdSchinx='-(-\)-)-'
317da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-\)' ]] || err_exit $M
318da2e3ebdSchinx='-(-\\)-)-'
319da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-\\)' ]] || err_exit $M
320da2e3ebdSchinx='-(-(-)-'
321da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
322da2e3ebdSchinx='-(-(-)-)-'
323da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
324da2e3ebdSchinx='-(-[-]-)-'
325da2e3ebdSchin[[ ${x/*%(()[])*/\1} == '(-[-]-)' ]] || err_exit $M
326da2e3ebdSchinx='-[-(-)-]-'
327da2e3ebdSchin[[ ${x/*%(()[])*/\1} == '(-)' ]] || err_exit $M
328da2e3ebdSchinx='-(-[-)-]-'
329da2e3ebdSchin[[ ${x/*%(()[])*/\1} == '-(-[-)-]-' ]] || err_exit $M
330da2e3ebdSchinx='-(-[-]-)-'
331da2e3ebdSchin[[ ${x/*%([]())*/\1} == '[-]' ]] || err_exit $M
332da2e3ebdSchinx='-[-(-)-]-'
333da2e3ebdSchin[[ ${x/*%([]())*/\1} == '[-(-)-]' ]] || err_exit $M
334da2e3ebdSchinx='-(-[-)-]-'
335da2e3ebdSchin[[ ${x/*%([]())*/\1} == '-(-[-)-]-' ]] || err_exit $M
336da2e3ebdSchin
337da2e3ebdSchinx='-((-))-'
338da2e3ebdSchin[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
339da2e3ebdSchinx='-((-))-'
340da2e3ebdSchin[[ ${x/~(-g)*%(())*/\1} == '((-))-' ]] || err_exit $M
341da2e3ebdSchinx='-((-))-'
342da2e3ebdSchin[[ ${x/~(-g:*)*%(())*/\1} == '(-)' ]] || err_exit $M
343da2e3ebdSchinx='-((-))-'
344da2e3ebdSchin[[ ${x/~(+g)*%(())*/\1} == '(-)' ]] || err_exit $M
345da2e3ebdSchinx='-((-))-'
346da2e3ebdSchin[[ ${x/~(+g:*)*%(())*/\1} == '(-)' ]] || err_exit $M
347da2e3ebdSchinx='-((-))-'
348da2e3ebdSchin[[ ${x/*(?)*%(())*(?)*/:\1:\2:\3:} == ':-(:(-):)-:' ]] || err_exit $M
349da2e3ebdSchinx='-((-))-'
350da2e3ebdSchin[[ ${x/~(-g)*(?)*%(())*(?)*/:\1:\2:\3:} == '::((-))::-' ]] || err_exit $M
351da2e3ebdSchinx='-((-))-'
352da2e3ebdSchin[[ ${x/~(-g:*(?))*%(())*(?)*/:\1:\2:\3:} == '::(-):)-:' ]] || err_exit $M
353da2e3ebdSchinx='-((-))-'
354da2e3ebdSchin[[ ${x/~(+g)*(?)*%(())*(?)*/:\1:\2:\3:} == ':-(:(-):)-:' ]] || err_exit $M
355da2e3ebdSchinx='-((-))-'
356da2e3ebdSchin[[ ${x/~(+g:*(?))*%(())*(?)*/:\1:\2:\3:} == ':-(:(-):)-:' ]] || err_exit $M
357da2e3ebdSchinx='call(a+b,x/(c/d),(0));'
358da2e3ebdSchin[[ ${x/+([[:alnum:]])*([[:space:]])(*%(()))*/:\1:\2:\3:} == ':call::(a+b,x/(c/d),(0)):' ]] || err_exit $M
359da2e3ebdSchin
360da2e3ebdSchinx='-(-;-)-'
361da2e3ebdSchin[[ ${x/*%(()D${D})*/\1} == '-(-;-)-' ]] || err_exit $M
362da2e3ebdSchinx='-(-);-'
363da2e3ebdSchin[[ ${x/*%(()D${D})*/\1} == '(-)' ]] || err_exit $M
364da2e3ebdSchinx='-(-)\;-'
365da2e3ebdSchin[[ ${x/*%(()D${D})*/\1} == '(-)' ]] || err_exit $M
366da2e3ebdSchinx='-(-\;-)-'
367da2e3ebdSchin[[ ${x/*%(()D${D}E${E})*/\1} == '(-\;-)' ]] || err_exit $M
368da2e3ebdSchinx='-(-)\;-'
369da2e3ebdSchin[[ ${x/*%(()D${D}E${E})*/\1} == '(-)' ]] || err_exit $M
370da2e3ebdSchinx='-(-(-)\;-)-'
371da2e3ebdSchin[[ ${x/*%(()D${D}E${E})*/\1} == '(-)' ]] || err_exit $M
372da2e3ebdSchin
373da2e3ebdSchinx='-(-")"-)-'
374da2e3ebdSchin[[ ${x/*%(()Q${Q})*/\1} == '(-")"-)' ]] || err_exit $M
375da2e3ebdSchinx='-(-\")"-)-'
376da2e3ebdSchin[[ ${x/*%(()Q${Q})*/\1} == '(-\")"-)' ]] || err_exit $M
377da2e3ebdSchinx='-(-\")\"-)-'
378da2e3ebdSchin[[ ${x/*%(()Q${Q})*/\1} == '(-\")\"-)' ]] || err_exit $M
379da2e3ebdSchinx=$'-(-\\\'")\\\'-)-'
380da2e3ebdSchin[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'(-\\\'")\\\'-)' ]] || err_exit $M
381da2e3ebdSchinx=$'-(-\\\'")"-)-'
382da2e3ebdSchin[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
383da2e3ebdSchinx=$'-(-\\\'")"\'-)-'
384da2e3ebdSchin[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
385da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
386da2e3ebdSchin[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
387da2e3ebdSchinx=$'-(-\')\\\'\'-)-'
388da2e3ebdSchin[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
389da2e3ebdSchinx=$'-(-\'")\'-)-'
390da2e3ebdSchin[[ ${x/*%(()L${S}Q${Q})*/\1} == $'(-\'")\'-)' ]] || err_exit $M
391da2e3ebdSchinx=$'-(-\\\'")"-)-'
392da2e3ebdSchin[[ ${x/*%(()L${S}Q${Q})*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
393da2e3ebdSchinx=$'-(-\\\'")"\'-)-'
394da2e3ebdSchin[[ ${x/*%(()L${S}Q${Q})*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
395da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
396da2e3ebdSchin[[ ${x/*%(()L${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
397da2e3ebdSchinx=$'-(-\')\\\'\'-)-'
398da2e3ebdSchin[[ ${x/*%(()L${S}Q${Q})*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
399da2e3ebdSchinx='-(-")"-)-'
400da2e3ebdSchin[[ ${x/*%(()Q${Q})*/\1} == '(-")"-)' ]] || err_exit $M
401da2e3ebdSchinx='-(-\")"-)-'
402da2e3ebdSchin[[ ${x/*%(()Q${Q})*/\1} == '(-\")"-)' ]] || err_exit $M
403da2e3ebdSchinx='-(-\")\"-)-'
404da2e3ebdSchin[[ ${x/*%(()Q${Q})*/\1} == '(-\")\"-)' ]] || err_exit $M
405da2e3ebdSchin
406da2e3ebdSchinx='-(-\)-)-'
407da2e3ebdSchin[[ ${x/*%(()E${E})*/\1} == '(-\)-)' ]] || err_exit $M
408da2e3ebdSchinx='-(-\\)-)-'
409da2e3ebdSchin[[ ${x/*%(()E${E})*/\1} == '(-\\)' ]] || err_exit $M
410da2e3ebdSchinx='-(-\")"-)-'
411da2e3ebdSchin[[ ${x/*%(()E${E}Q${Q})*/\1} == '(-\")' ]] || err_exit $M
412da2e3ebdSchinx='-(-\")\"-)-'
413da2e3ebdSchin[[ ${x/*%(()E${E}Q${Q})*/\1} == '(-\")' ]] || err_exit $M
414da2e3ebdSchinx=$'-(-\'")"-)-'
415da2e3ebdSchin[[ ${x/*%(()E${E}Q${S}Q${Q})*/\1} == $'-(-\'")"-)-' ]] || err_exit $M
416da2e3ebdSchinx=$'-(-\\\'")"-)-'
417da2e3ebdSchin[[ ${x/*%(()E${E}Q${S}Q${Q})*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
418da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
419da2e3ebdSchin[[ ${x/*%(()E${E}Q${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
420da2e3ebdSchinx=$'-(-\\\'")"-)-'
421da2e3ebdSchin[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
422da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
423da2e3ebdSchin[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
424da2e3ebdSchinx=$'-(-\\"\')\\\'\\"-)-'
425da2e3ebdSchin[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'(-\\"\')\\\'\\"-)' ]] || err_exit $M
426da2e3ebdSchinx=$'-(-\\"\')\\\'\\"\'-)-'
427da2e3ebdSchin[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'-(-\\"\')\\\'\\"\'-)-' ]] || err_exit $M
428da2e3ebdSchin
429da2e3ebdSchinx='-(-;-)-'
430da2e3ebdSchin[[ ${x/*%(()D\;)*/\1} == '-(-;-)-' ]] || err_exit $M
431da2e3ebdSchinx='-(-);-'
432da2e3ebdSchin[[ ${x/*%(()D\;)*/\1} == '(-)' ]] || err_exit $M
433da2e3ebdSchinx='-(-)\;-'
434da2e3ebdSchin[[ ${x/*%(()D\;)*/\1} == '(-)' ]] || err_exit $M
435da2e3ebdSchinx='-(-\;-)-'
436da2e3ebdSchin[[ ${x/*%(()D\;E\\)*/\1} == '(-\;-)' ]] || err_exit $M
437da2e3ebdSchinx='-(-);-'
438da2e3ebdSchin[[ ${x/*%(()D\;E\\)*/\1} == '(-)' ]] || err_exit $M
439da2e3ebdSchinx='-(-)\;-'
440da2e3ebdSchin[[ ${x/*%(()D\;E\\)*/\1} == '(-)' ]] || err_exit $M
441da2e3ebdSchinx='-(-(-)\;-)-'
442da2e3ebdSchin[[ ${x/*%(()D\;E\\)*/\1} == '(-)' ]] || err_exit $M
443da2e3ebdSchin
444da2e3ebdSchinx='-(-")"-)-'
445da2e3ebdSchin[[ ${x/*%(()Q\")*/\1} == '(-")"-)' ]] || err_exit $M
446da2e3ebdSchinx='-(-\")"-)-'
447da2e3ebdSchin[[ ${x/*%(()Q\")*/\1} == '(-\")"-)' ]] || err_exit $M
448da2e3ebdSchinx='-(-\")\"-)-'
449da2e3ebdSchin[[ ${x/*%(()Q\")*/\1} == '(-\")\"-)' ]] || err_exit $M
450da2e3ebdSchinx=$'-(-\\\'")\\\'-)-'
451da2e3ebdSchin[[ ${x/*%(()Q\'Q\")*/\1} == $'(-\\\'")\\\'-)' ]] || err_exit $M
452da2e3ebdSchinx=$'-(-\\\'")"-)-'
453da2e3ebdSchin[[ ${x/*%(()Q\'Q\")*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
454da2e3ebdSchinx=$'-(-\\\'")"\'-)-'
455da2e3ebdSchin[[ ${x/*%(()Q\'Q\")*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
456da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
457da2e3ebdSchin[[ ${x/*%(()Q\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
458da2e3ebdSchinx=$'-(-\')\\\'\'-)-'
459da2e3ebdSchin[[ ${x/*%(()Q\'Q\")*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
460da2e3ebdSchinx=$'-(-\'")\'-)-'
461da2e3ebdSchin[[ ${x/*%(()L\'Q\")*/\1} == $'(-\'")\'-)' ]] || err_exit $M
462da2e3ebdSchinx=$'-(-\\\'")"-)-'
463da2e3ebdSchin[[ ${x/*%(()L\'Q\")*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
464da2e3ebdSchinx=$'-(-\\\'")"\'-)-'
465da2e3ebdSchin[[ ${x/*%(()L\'Q\")*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
466da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
467da2e3ebdSchin[[ ${x/*%(()L\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
468da2e3ebdSchinx=$'-(-\')\\\'\'-)-'
469da2e3ebdSchin[[ ${x/*%(()L\'Q\")*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
470da2e3ebdSchinx='-(-")"-)-'
471da2e3ebdSchin[[ ${x/*%(()Q\")*/\1} == '(-")"-)' ]] || err_exit $M
472da2e3ebdSchinx='-(-\")"-)-'
473da2e3ebdSchin[[ ${x/*%(()Q\")*/\1} == '(-\")"-)' ]] || err_exit $M
474da2e3ebdSchinx='-(-\")\"-)-'
475da2e3ebdSchin[[ ${x/*%(()Q\")*/\1} == '(-\")\"-)' ]] || err_exit $M
476da2e3ebdSchin
477da2e3ebdSchinx='-(-\)-)-'
478da2e3ebdSchin[[ ${x/*%(()E\\)*/\1} == '(-\)-)' ]] || err_exit $M
479da2e3ebdSchinx='-(-\\)-)-'
480da2e3ebdSchin[[ ${x/*%(()E\\)*/\1} == '(-\\)' ]] || err_exit $M
481da2e3ebdSchinx='-(-\")"-)-'
482da2e3ebdSchin[[ ${x/*%(()E\\Q\")*/\1} == '(-\")' ]] || err_exit $M
483da2e3ebdSchinx='-(-\")\"-)-'
484da2e3ebdSchin[[ ${x/*%(()E\\Q\")*/\1} == '(-\")' ]] || err_exit $M
485da2e3ebdSchinx=$'-(-\'")"-)-'
486da2e3ebdSchin[[ ${x/*%(()E\\Q\'Q\")*/\1} == $'-(-\'")"-)-' ]] || err_exit $M
487da2e3ebdSchinx=$'-(-\\\'")"-)-'
488da2e3ebdSchin[[ ${x/*%(()E\\Q\'Q\")*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
489da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
490da2e3ebdSchin[[ ${x/*%(()E\\Q\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
491da2e3ebdSchinx=$'-(-\\\'")"-)-'
492da2e3ebdSchin[[ ${x/*%(()E\\L\'Q\")*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
493da2e3ebdSchinx=$'-(-\\"\')\'\\"-)-'
494da2e3ebdSchin[[ ${x/*%(()E\\L\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
495da2e3ebdSchinx=$'-(-\\"\')\\\'\\"-)-'
496da2e3ebdSchin[[ ${x/*%(()E\\L\'Q\")*/\1} == $'(-\\"\')\\\'\\"-)' ]] || err_exit $M
497da2e3ebdSchinx=$'-(-\\"\')\\\'\\"\'-)-'
498da2e3ebdSchin[[ ${x/*%(()E\\L\'Q\")*/\1} == $'-(-\\"\')\\\'\\"\'-)-' ]] || err_exit $M
499da2e3ebdSchin
500da2e3ebdSchinpattern=00
501da2e3ebdSchinvar=100
502da2e3ebdSchin[[ $( print $(( ${var%%00} )) ) == 1 ]] || err_exit "arithmetic with embeddded patterns fails"
503da2e3ebdSchin[[ $( print $(( ${var%%$pattern} )) ) == 1 ]] || err_exit "arithmetic with embeddded pattern variables fails"
504da2e3ebdSchinif	[[ ax == @(a)* ]] && [[ ${.sh.match[1]:0:${#.sh.match[1]}}  != a ]]
505da2e3ebdSchinthen	err_exit '${.sh.match[1]:1:${#.sh.match[1]}} not expanding correctly'
506da2e3ebdSchinfi
507da2e3ebdSchin
508da2e3ebdSchinstring='foo(d:\nt\box\something)bar'
509da2e3ebdSchinexpected='d:\nt\box\something'
510da2e3ebdSchin[[ ${string/*\(+([!\)])\)*/\1} == "$expected" ]] || err_exit "substring expansion failed '${string/*\(+([!\)])\)*/\1}' returned -- '$expected' expected"
511da2e3ebdSchinif	[[ $($SHELL -c $'export LC_ALL=en_US.UTF-8; print -r "\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254" | wc -m' 2>/dev/null) == 10 ]]
51234f9b3eeSRoland Mainzthen	LC_ALL=en_US.UTF-8 $SHELL -c b1=$'"\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254"; [[ ${b1:4:1} == w ]]' || err_exit 'multibyte ${var:offset:len} not working correctly'
513da2e3ebdSchinfi
514da2e3ebdSchin{ $SHELL -c 'unset x;[[ ${SHELL:$x} == $SHELL ]]';} 2> /dev/null || err_exit '${var:$x} fails when x is not set'
515da2e3ebdSchin{ $SHELL -c 'x=;[[ ${SHELL:$x} == $SHELL ]]';} 2> /dev/null || err_exit '${var:$x} fails when x is null'
5167c2fbfb3SApril Chin
5177c2fbfb3SApril Chin#	subject		mode	pattern			result	#
5187c2fbfb3SApril Chinset --							\
5197c2fbfb3SApril Chin	'a$z'		'E'	'[$]|#'		'a($)z'	\
5207c2fbfb3SApril Chin	'a#z'		'E'	'[$]|#'		'a(#)z'	\
5217c2fbfb3SApril Chin	'a$z'		'Elr'	'[$]|#'		'a$z'	\
5227c2fbfb3SApril Chin	'a#z'		'Elr'	'[$]|#'		'a#z'	\
5237c2fbfb3SApril Chin	'a$'		'E'	'[$]|#'		'a($)'	\
5247c2fbfb3SApril Chin	'a#'		'E'	'[$]|#'		'a(#)'	\
5257c2fbfb3SApril Chin	'a$'		'Elr'	'[$]|#'		'a$'	\
5267c2fbfb3SApril Chin	'a#'		'Elr'	'[$]|#'		'a#'	\
5277c2fbfb3SApril Chin	'$z'		'E'	'[$]|#'		'($)z'	\
5287c2fbfb3SApril Chin	'#z'		'E'	'[$]|#'		'(#)z'	\
5297c2fbfb3SApril Chin	'$z'		'Elr'	'[$]|#'		'$z'	\
5307c2fbfb3SApril Chin	'#z'		'Elr'	'[$]|#'		'#z'	\
5317c2fbfb3SApril Chin	'$'		'E'	'[$]|#'		'($)'	\
5327c2fbfb3SApril Chin	'#'		'E'	'[$]|#'		'(#)'	\
5337c2fbfb3SApril Chin	'$'		'Elr'	'[$]|#'		'($)'	\
5347c2fbfb3SApril Chin	'#'		'Elr'	'[$]|#'		'(#)'	\
5357c2fbfb3SApril Chin	'a$z'		'E'	'\$|#'		'a$z()'	\
5367c2fbfb3SApril Chin	'a$z'		'E'	'\\$|#'		'a$z'	\
5377c2fbfb3SApril Chin	'a$z'		'E'	'\\\$|#'	'a($)z'	\
5387c2fbfb3SApril Chin	'a#z'		'E'	'\\\$|#'	'a(#)z'	\
5397c2fbfb3SApril Chin	'a$z'		'Elr'	'\\\$|#'	'a$z'	\
5407c2fbfb3SApril Chin	'a#z'		'Elr'	'\\\$|#'	'a#z'	\
5417c2fbfb3SApril Chin	'a$'		'E'	'\\\$|#'	'a($)'	\
5427c2fbfb3SApril Chin	'a#'		'E'	'\\\$|#'	'a(#)'	\
5437c2fbfb3SApril Chin	'a$'		'Elr'	'\\\$|#'	'a$'	\
5447c2fbfb3SApril Chin	'a#'		'Elr'	'\\\$|#'	'a#'	\
5457c2fbfb3SApril Chin	'$z'		'E'	'\\\$|#'	'($)z'	\
5467c2fbfb3SApril Chin	'#z'		'E'	'\\\$|#'	'(#)z'	\
5477c2fbfb3SApril Chin	'$z'		'Elr'	'\\\$|#'	'$z'	\
5487c2fbfb3SApril Chin	'#z'		'Elr'	'\\\$|#'	'#z'	\
5497c2fbfb3SApril Chin	'$'		'E'	'\\\$|#'	'($)'	\
5507c2fbfb3SApril Chin	'#'		'E'	'\\\$|#'	'(#)'	\
5517c2fbfb3SApril Chin	'$'		'Elr'	'\\\$|#'	'($)'	\
5527c2fbfb3SApril Chin	'#'		'Elr'	'\\\$|#'	'(#)'	\
5537c2fbfb3SApril Chin#	do not delete this line			#
5547c2fbfb3SApril Chinunset i o
5557c2fbfb3SApril Chinwhile	(( $# >= 4 ))
5567c2fbfb3SApril Chindo	i=$1
5577c2fbfb3SApril Chin	eval o="\${i/~($2)$3/\\(\\0\\)}"
5587c2fbfb3SApril Chin	if	[[ "$o" != "$4" ]]
5597c2fbfb3SApril Chin	then	err_exit "i='$1'; \${i/~($2)$3/\\(\\0\\)} failed -- expected '$4', got '$o'"
5607c2fbfb3SApril Chin	fi
5617c2fbfb3SApril Chin	eval o="\${i/~($2)($3)/\\(\\1\\)}"
5627c2fbfb3SApril Chin	if	[[ "$o" != "$4" ]]
5637c2fbfb3SApril Chin	then	err_exit "i='$1'; \${i/~($2)($3)/\\(\\1\\)} failed -- expected '$4', got '$o'"
5647c2fbfb3SApril Chin	fi
5657c2fbfb3SApril Chin	shift 4
5667c2fbfb3SApril Chindone
5677c2fbfb3SApril Chin
568da2e3ebdSchinexit $((Errors))
569