1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                 Eclipse Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#          http://www.eclipse.org/org/documents/epl-v10.html           #
11#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
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 -n "\t"
23	print -u2 -r ${Command}[$1]: "${@:2}"
24	let Errors+=1
25}
26alias err_exit='err_exit $LINENO'
27
28Command=${0##*/}
29integer Errors=0 j=4
30base=/home/dgk/foo//bar
31string1=$base/abcabcabc
32if	[[ ${string1:0} != "$string1" ]]
33then	err_exit "string1:0"
34fi
35if	[[ ${string1: -1} != "c" ]]
36then	err_exit "string1: -1"
37fi
38if	[[ ${string1:0:1000} != "$string1" ]]
39then	err_exit "string1:0"
40fi
41if	[[ ${string1:1} != "${string1#?}" ]]
42then	err_exit "string1:1"
43fi
44if	[[ ${string1:1:4} != home ]]
45then	err_exit "string1:1:4"
46fi
47if	[[ ${string1: -5:4} != bcab ]]
48then	err_exit "string1: -5:4"
49fi
50if	[[ ${string1:1:j} != home ]]
51then	err_exit "string1:1:j"
52fi
53if	[[ ${string1:(j?1:0):j} != home ]]
54then	err_exit "string1:(j?1:0):j"
55fi
56if	[[ ${string1%*zzz*} != "$string1" ]]
57then	err_exit "string1%*zzz*"
58fi
59if	[[ ${string1%%*zzz*} != "$string1" ]]
60then	err_exit "string1%%*zzz*"
61fi
62if	[[ ${string1#*zzz*} != "$string1" ]]
63then	err_exit "string1#*zzz*"
64fi
65if	[[ ${string1##*zzz*} != "$string1" ]]
66then	err_exit "string1##*zzz*"
67fi
68if	[[ ${string1%+(abc)} != "$base/abcabc" ]]
69then	err_exit "string1%+(abc)"
70fi
71if	[[ ${string1%%+(abc)} != "$base/" ]]
72then	err_exit "string1%%+(abc)"
73fi
74if	[[ ${string1%/*} != "$base" ]]
75then	err_exit "string1%/*"
76fi
77if	[[ "${string1%/*}" != "$base" ]]
78then	err_exit '"string1%/*"'
79fi
80if	[[ ${string1%"/*"} != "$string1" ]]
81then	err_exit 'string1%"/*"'
82fi
83if	[[ ${string1%%/*} != "" ]]
84then	err_exit "string1%%/*"
85fi
86if	[[ ${string1#*/bar} != /abcabcabc ]]
87then	err_exit "string1#*bar"
88fi
89if	[[ ${string1##*/bar} != /abcabcabc ]]
90then	err_exit "string1#*bar"
91fi
92if	[[ "${string1#@(*/bar|*/foo)}" != //bar/abcabcabc ]]
93then	err_exit "string1#@(*/bar|*/foo)"
94fi
95if	[[ ${string1##@(*/bar|*/foo)} != /abcabcabc ]]
96then	err_exit "string1##@(*/bar|*/foo)"
97fi
98if	[[ ${string1##*/@(bar|foo)} != /abcabcabc ]]
99then	err_exit "string1##*/@(bar|foo)"
100fi
101foo=abc
102if	[[ ${foo#a[b*} != abc ]]
103then	err_exit "abc#a[b*} != abc"
104fi
105if	[[ ${foo//[0-9]/bar} != abc ]]
106then	err_exit '${foo//[0-9]/bar} not expanding correctly'
107fi
108foo='(abc)'
109if	[[ ${foo#'('} != 'abc)' ]]
110then	err_exit "(abc)#( != abc)"
111fi
112if	[[ ${foo%')'} != '(abc' ]]
113then	err_exit "(abc)%) != (abc"
114fi
115foo=a123b456c
116if	[[ ${foo/[0-9]?/""} != a3b456c ]]
117then	err_exit '${foo/[0-9]?/""} not expanding correctly'
118fi
119if	[[ ${foo//[0-9]/""} != abc ]]
120then	err_exit '${foo//[0-9]/""} not expanding correctly'
121fi
122if	[[ ${foo/#a/b} != b123b456c ]]
123then	err_exit '${foo/#a/b} not expanding correctly'
124fi
125if	[[ ${foo/#?/b} != b123b456c ]]
126then	err_exit '${foo/#?/b} not expanding correctly'
127fi
128if	[[ ${foo/%c/b} != a123b456b ]]
129then	err_exit '${foo/%c/b} not expanding correctly'
130fi
131if	[[ ${foo/%?/b} != a123b456b ]]
132then	err_exit '${foo/%?/b} not expanding correctly'
133fi
134while read -r pattern string expected
135do	if	(( expected ))
136	then	if	[[ $string != $pattern ]]
137		then	err_exit "$pattern does not match $string"
138		fi
139		if	[[ ${string##$pattern} != "" ]]
140		then	err_exit "\${$string##$pattern} not null"
141		fi
142		if	[ "${string##$pattern}" != '' ]
143		then	err_exit "\"\${$string##$pattern}\" not null"
144		fi
145		if	[[ ${string/$pattern} != "" ]]
146		then	err_exit "\${$string/$pattern} not null"
147		fi
148	else	if	[[ $string == $pattern ]]
149		then	err_exit "$pattern matches $string"
150		fi
151	fi
152done <<- \EOF
153	+(a)*+(a)	aabca	1
154	!(*.o)		foo.o	0
155	!(*.o)		foo.c	1
156EOF
157xx=a/b/c/d/e
158yy=${xx#*/}
159if	[[ $yy != b/c/d/e ]]
160then	err_exit '${xx#*/} != a/b/c/d/e when xx=a/b/c/d/e'
161fi
162if	[[ ${xx//\//\\} != 'a\b\c\d\e' ]]
163then	err_exit '${xx//\//\\} not working'
164fi
165x=[123]def
166if	[[ "${x//\[@(*)\]/\{\1\}}" != {123}def ]]
167then	err_exit 'closing brace escape not working'
168fi
169xx=%28text%29
170if	[[ ${xx//%28/abc\)} != 'abc)text%29' ]]
171then	 err_exit '${xx//%28/abc\)} not working'
172fi
173xx='a:b'
174str='(){}[]*?|&^%$#@l'
175for ((i=0 ; i < ${#str}; i++))
176do      [[ $(eval print -r -- \"\${xx//:/\\${str:i:1}}\") == "a${str:i:1}b" ]] || err_exit "substitution of \\${str:i:1}} failed"
177        [[ $(eval print -rn -- \"\${xx//:/\'${str:i:1}\'}\") == "a${str:i:1}b" ]] || err_exit "substitution of '${str:i:1}' failed"
178        [[ $(eval print -r -- \"\${xx//:/\"${str:i:1}\"}\") == "a${str:i:1}b" ]] || err_exit "substitution of \"${str:i:1}\" failed"
179done
180[[ ${xx//:/\\n} == 'a\nb' ]]  || err_exit "substituion of \\\\n failed"
181[[ ${xx//:/'\n'} == 'a\nb' ]] || err_exit "substituion of '\\n' failed"
182[[ ${xx//:/"\n"} ==  'a\nb' ]] || err_exit "substituion of \"\\n\" failed"
183[[ ${xx//:/$'\n'} ==  $'a\nb' ]] || err_exit "substituion of \$'\\n' failed"
184unset foo
185foo=one/two/three
186if	[[ ${foo//'/'/_} != one_two_three ]]
187then	err_exit 'single quoting / in replacements failed'
188fi
189if	[[ ${foo//"/"/_} != one_two_three ]]
190then	err_exit 'double quoting / in replacements failed'
191fi
192if	[[ ${foo//\//_} != one_two_three ]]
193then	err_exit 'escaping / in replacements failed'
194fi
195function myexport
196{
197	nameref var=$1
198	if	(( $# > 1 ))
199	then	export	$1=$2
200	fi
201	if	(( $# > 2 ))
202	then	print $(myexport "$1" "$3" )
203		return
204	fi
205	typeset val
206	val=$(export | grep "^$1=")
207	print ${val#"$1="}
208
209}
210export dgk=base
211if	[[ $(myexport dgk fun) != fun ]]
212then	err_exit 'export inside function not working'
213fi
214val=$(export | grep "^dgk=")
215if	[[ ${val#dgk=} != base ]]
216then	err_exit 'export not restored after function call'
217fi
218if	[[ $(myexport dgk fun fun2) != fun2 ]]
219then	err_exit 'export inside function not working with recursive function'
220fi
221val=$(export | grep "^dgk=")
222if	[[ ${val#dgk=} != base ]]
223then	err_exit 'export not restored after recursive function call'
224fi
225if	[[ $(dgk=try3 myexport dgk) != try3 ]]
226then	err_exit 'name=value not added to export list with function call'
227fi
228val=$(export | grep "^dgk=")
229if	[[ ${val#dgk=} != base ]]
230then	err_exit 'export not restored name=value function call'
231fi
232unset zzz
233if	[[ $(myexport zzz fun) != fun ]]
234then	err_exit 'export inside function not working for zzz'
235fi
236if	[[ $(export | grep "zzz=") ]]
237then	err_exit 'zzz exported after function call'
238fi
239set -- foo/bar bam/yes last/file/done
240if	[[ ${@/*\/@(*)/\1} != 'bar yes done' ]]
241then	err_exit '\1 not working with $@'
242fi
243var=(foo/bar bam/yes last/file/done)
244if	[[ ${var[@]/*\/@(*)/\1} != 'bar yes done' ]]
245then	err_exit '\1 not working with ${var[@]}'
246fi
247var='abc_d2ef.462abc %%'
248if	[[ ${var/+(\w)/Q} != 'Q.462abc %%' ]]
249then	err_exit '${var/+(\w)/Q} not workding'
250fi
251if	[[ ${var//+(\w)/Q} != 'Q.Q %%' ]]
252then	err_exit '${var//+(\w)/Q} not workding'
253fi
254if	[[ ${var//+(\S)/Q} != 'Q Q' ]]
255then	err_exit '${var//+(\S)/Q} not workding'
256fi
257var=$($SHELL -c 'v=/vin:/usr/vin r=vin; : ${v//vin/${r//v/b}};typeset -p .sh.match') 2> /dev/null
258[[ $var == 'typeset -a .sh.match=((vin vin) )' ]] || err_exit '.sh.match not correct when replacement pattern contains a substring match'
259foo='foo+bar+'
260[[ $(print -r -- ${foo//+/'|'}) != 'foo|bar|' ]] && err_exit "\${foobar//+/'|'}"
261[[ $(print -r -- ${foo//+/"|"}) != 'foo|bar|' ]] && err_exit '${foobar//+/"|"}'
262[[ $(print -r -- "${foo//+/'|'}") != 'foo|bar|' ]] && err_exit '"${foobar//+/'"'|'"'}"'
263[[ $(print -r -- "${foo//+/"|"}") != 'foo|bar|' ]] && err_exit '"${foobar//+/"|"}"'
264unset x
265x=abcedfg
266: ${x%@(d)f@(g)}
267[[ ${.sh.match[0]} == dfg ]] || err_exit '.sh.match[0] not dfg'
268[[ ${.sh.match[1]} == d ]] || err_exit '.sh.match[1] not d'
269[[ ${.sh.match[2]} == g ]] || err_exit '.sh.match[2] not g'
270x=abcedddfg
271: ${x%%+(d)f@(g)}
272[[ ${.sh.match[1]} == ddd ]] || err_exit '.sh.match[1] not ddd'
273unset a b
274a='\[abc @(*) def\]'
275b='[abc 123 def]'
276[[ ${b//$a/\1} == 123 ]] || err_exit "\${var/pattern} not working with \[ in pattern"
277unset foo
278foo='(win32.i386) '
279[[ ${foo/'('/'(x11-'} == '(x11-win32.i386) ' ]] || err_exit "\${var/pattern} not working with ' in pattern"
280$SHELL -c $'v=\'$(hello)\'; [[ ${v//\'$(\'/-I\'$(\'} == -I"$v" ]]' 2> /dev/null || err_exit "\${var/pattern} not working with \$( as pattern"
281unset X
282$SHELL -c '[[ ! ${X[@]:0:300} ]]' 2> /dev/null || err_exit '${X[@]:0:300} with X undefined fails'
283$SHELL -c '[[ ${@:0:300} == "$0" ]]' 2> /dev/null || err_exit '${@:0:300} with no arguments fails'
284i=20030704
285[[ ${i#{6}(?)} == 04 ]] ||  err_exit '${i#{6}(?)} not working'
286[[ ${i#{6,6}(?)} == 04 ]] ||  err_exit '${i#{6,6}(?)} not working'
287LC_ALL=posix
288i="   ."
289[[ $(printf "<%s>\n" ${i#' '}) == '<.>' ]] || err_exit 'printf "<%s>\n" ${i#' '} failed'
290unset x
291x=foo
292[[ "${x%o}(1)" == "fo(1)" ]] ||  err_exit 'print ${}() treated as pattern'
293unset i pattern string
294string=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz
295integer i
296for((i=0; i < ${#string}; i++))
297do	pattern+='@(?)'
298done
299[[ $(string=$string $SHELL -c  ": \${string/$pattern/}; print \${.sh.match[26]}") == Z ]] || err_exit -u2 'sh.match[26] not Z'
300: ${string/$pattern/}
301(( ${#.sh.match[@]} == 53 )) || err_exit '.sh.match has wrong number of elements'
302[[ ${.sh.match[@]:2:4} == 'B C D E'  ]] || err_exit '${.sh.match[@]:2:4} incorrect'
303
304D=$';' E=$'\\\\' Q=$'"' S=$'\'' M='nested pattern substitution failed'
305
306x='-(-)-'
307[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
308x='-(-)-)-'
309[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
310x='-(-()-)-'
311[[ ${x/*%(())*/\1} == '()' ]] || err_exit $M
312x='-(-\)-)-'
313[[ ${x/*%(())*/\1} == '(-\)' ]] || err_exit $M
314x='-(-\\)-)-'
315[[ ${x/*%(())*/\1} == '(-\\)' ]] || err_exit $M
316x='-(-(-)-'
317[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
318x='-(-(-)-)-'
319[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
320x='-(-[-]-)-'
321[[ ${x/*%(()[])*/\1} == '(-[-]-)' ]] || err_exit $M
322x='-[-(-)-]-'
323[[ ${x/*%(()[])*/\1} == '(-)' ]] || err_exit $M
324x='-(-[-)-]-'
325[[ ${x/*%(()[])*/\1} == '-(-[-)-]-' ]] || err_exit $M
326x='-(-[-]-)-'
327[[ ${x/*%([]())*/\1} == '[-]' ]] || err_exit $M
328x='-[-(-)-]-'
329[[ ${x/*%([]())*/\1} == '[-(-)-]' ]] || err_exit $M
330x='-(-[-)-]-'
331[[ ${x/*%([]())*/\1} == '-(-[-)-]-' ]] || err_exit $M
332
333x='-((-))-'
334[[ ${x/*%(())*/\1} == '(-)' ]] || err_exit $M
335x='-((-))-'
336[[ ${x/~(-g)*%(())*/\1} == '((-))-' ]] || err_exit $M
337x='-((-))-'
338[[ ${x/~(-g:*)*%(())*/\1} == '(-)' ]] || err_exit $M
339x='-((-))-'
340[[ ${x/~(+g)*%(())*/\1} == '(-)' ]] || err_exit $M
341x='-((-))-'
342[[ ${x/~(+g:*)*%(())*/\1} == '(-)' ]] || err_exit $M
343x='-((-))-'
344[[ ${x/*(?)*%(())*(?)*/:\1:\2:\3:} == ':-(:(-):)-:' ]] || err_exit $M
345x='-((-))-'
346[[ ${x/~(-g)*(?)*%(())*(?)*/:\1:\2:\3:} == '::((-))::-' ]] || err_exit $M
347x='-((-))-'
348[[ ${x/~(-g:*(?))*%(())*(?)*/:\1:\2:\3:} == '::(-):)-:' ]] || err_exit $M
349x='-((-))-'
350[[ ${x/~(+g)*(?)*%(())*(?)*/:\1:\2:\3:} == ':-(:(-):)-:' ]] || err_exit $M
351x='-((-))-'
352[[ ${x/~(+g:*(?))*%(())*(?)*/:\1:\2:\3:} == ':-(:(-):)-:' ]] || err_exit $M
353x='call(a+b,x/(c/d),(0));'
354[[ ${x/+([[:alnum:]])*([[:space:]])@(*%(()))*/:\1:\2:\3:} == ':call::(a+b,x/(c/d),(0)):' ]] || err_exit $M
355
356x='-(-;-)-'
357[[ ${x/*%(()D${D})*/\1} == '-(-;-)-' ]] || err_exit $M
358x='-(-);-'
359[[ ${x/*%(()D${D})*/\1} == '(-)' ]] || err_exit $M
360x='-(-)\;-'
361[[ ${x/*%(()D${D})*/\1} == '(-)' ]] || err_exit $M
362x='-(-\;-)-'
363[[ ${x/*%(()D${D}E${E})*/\1} == '(-\;-)' ]] || err_exit $M
364x='-(-)\;-'
365[[ ${x/*%(()D${D}E${E})*/\1} == '(-)' ]] || err_exit $M
366x='-(-(-)\;-)-'
367[[ ${x/*%(()D${D}E${E})*/\1} == '(-)' ]] || err_exit $M
368
369x='-(-")"-)-'
370[[ ${x/*%(()Q${Q})*/\1} == '(-")"-)' ]] || err_exit $M
371x='-(-\")"-)-'
372[[ ${x/*%(()Q${Q})*/\1} == '(-\")"-)' ]] || err_exit $M
373x='-(-\")\"-)-'
374[[ ${x/*%(()Q${Q})*/\1} == '(-\")\"-)' ]] || err_exit $M
375x=$'-(-\\\'")\\\'-)-'
376[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'(-\\\'")\\\'-)' ]] || err_exit $M
377x=$'-(-\\\'")"-)-'
378[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
379x=$'-(-\\\'")"\'-)-'
380[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
381x=$'-(-\\"\')\'\\"-)-'
382[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
383x=$'-(-\')\\\'\'-)-'
384[[ ${x/*%(()Q${S}Q${Q})*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
385x=$'-(-\'")\'-)-'
386[[ ${x/*%(()L${S}Q${Q})*/\1} == $'(-\'")\'-)' ]] || err_exit $M
387x=$'-(-\\\'")"-)-'
388[[ ${x/*%(()L${S}Q${Q})*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
389x=$'-(-\\\'")"\'-)-'
390[[ ${x/*%(()L${S}Q${Q})*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
391x=$'-(-\\"\')\'\\"-)-'
392[[ ${x/*%(()L${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
393x=$'-(-\')\\\'\'-)-'
394[[ ${x/*%(()L${S}Q${Q})*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
395x='-(-")"-)-'
396[[ ${x/*%(()Q${Q})*/\1} == '(-")"-)' ]] || err_exit $M
397x='-(-\")"-)-'
398[[ ${x/*%(()Q${Q})*/\1} == '(-\")"-)' ]] || err_exit $M
399x='-(-\")\"-)-'
400[[ ${x/*%(()Q${Q})*/\1} == '(-\")\"-)' ]] || err_exit $M
401
402x='-(-\)-)-'
403[[ ${x/*%(()E${E})*/\1} == '(-\)-)' ]] || err_exit $M
404x='-(-\\)-)-'
405[[ ${x/*%(()E${E})*/\1} == '(-\\)' ]] || err_exit $M
406x='-(-\")"-)-'
407[[ ${x/*%(()E${E}Q${Q})*/\1} == '(-\")' ]] || err_exit $M
408x='-(-\")\"-)-'
409[[ ${x/*%(()E${E}Q${Q})*/\1} == '(-\")' ]] || err_exit $M
410x=$'-(-\'")"-)-'
411[[ ${x/*%(()E${E}Q${S}Q${Q})*/\1} == $'-(-\'")"-)-' ]] || err_exit $M
412x=$'-(-\\\'")"-)-'
413[[ ${x/*%(()E${E}Q${S}Q${Q})*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
414x=$'-(-\\"\')\'\\"-)-'
415[[ ${x/*%(()E${E}Q${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
416x=$'-(-\\\'")"-)-'
417[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
418x=$'-(-\\"\')\'\\"-)-'
419[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
420x=$'-(-\\"\')\\\'\\"-)-'
421[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'(-\\"\')\\\'\\"-)' ]] || err_exit $M
422x=$'-(-\\"\')\\\'\\"\'-)-'
423[[ ${x/*%(()E${E}L${S}Q${Q})*/\1} == $'-(-\\"\')\\\'\\"\'-)-' ]] || err_exit $M
424
425x='-(-;-)-'
426[[ ${x/*%(()D\;)*/\1} == '-(-;-)-' ]] || err_exit $M
427x='-(-);-'
428[[ ${x/*%(()D\;)*/\1} == '(-)' ]] || err_exit $M
429x='-(-)\;-'
430[[ ${x/*%(()D\;)*/\1} == '(-)' ]] || err_exit $M
431x='-(-\;-)-'
432[[ ${x/*%(()D\;E\\)*/\1} == '(-\;-)' ]] || err_exit $M
433x='-(-);-'
434[[ ${x/*%(()D\;E\\)*/\1} == '(-)' ]] || err_exit $M
435x='-(-)\;-'
436[[ ${x/*%(()D\;E\\)*/\1} == '(-)' ]] || err_exit $M
437x='-(-(-)\;-)-'
438[[ ${x/*%(()D\;E\\)*/\1} == '(-)' ]] || err_exit $M
439
440x='-(-")"-)-'
441[[ ${x/*%(()Q\")*/\1} == '(-")"-)' ]] || err_exit $M
442x='-(-\")"-)-'
443[[ ${x/*%(()Q\")*/\1} == '(-\")"-)' ]] || err_exit $M
444x='-(-\")\"-)-'
445[[ ${x/*%(()Q\")*/\1} == '(-\")\"-)' ]] || err_exit $M
446x=$'-(-\\\'")\\\'-)-'
447[[ ${x/*%(()Q\'Q\")*/\1} == $'(-\\\'")\\\'-)' ]] || err_exit $M
448x=$'-(-\\\'")"-)-'
449[[ ${x/*%(()Q\'Q\")*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
450x=$'-(-\\\'")"\'-)-'
451[[ ${x/*%(()Q\'Q\")*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
452x=$'-(-\\"\')\'\\"-)-'
453[[ ${x/*%(()Q\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
454x=$'-(-\')\\\'\'-)-'
455[[ ${x/*%(()Q\'Q\")*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
456x=$'-(-\'")\'-)-'
457[[ ${x/*%(()L\'Q\")*/\1} == $'(-\'")\'-)' ]] || err_exit $M
458x=$'-(-\\\'")"-)-'
459[[ ${x/*%(()L\'Q\")*/\1} == $'-(-\\\'")"-)-' ]] || err_exit $M
460x=$'-(-\\\'")"\'-)-'
461[[ ${x/*%(()L\'Q\")*/\1} == $'(-\\\'")"\'-)' ]] || err_exit $M
462x=$'-(-\\"\')\'\\"-)-'
463[[ ${x/*%(()L\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
464x=$'-(-\')\\\'\'-)-'
465[[ ${x/*%(()L\'Q\")*/\1} == $'-(-\')\\\'\'-)-' ]] || err_exit $M
466x='-(-")"-)-'
467[[ ${x/*%(()Q\")*/\1} == '(-")"-)' ]] || err_exit $M
468x='-(-\")"-)-'
469[[ ${x/*%(()Q\")*/\1} == '(-\")"-)' ]] || err_exit $M
470x='-(-\")\"-)-'
471[[ ${x/*%(()Q\")*/\1} == '(-\")\"-)' ]] || err_exit $M
472
473x='-(-\)-)-'
474[[ ${x/*%(()E\\)*/\1} == '(-\)-)' ]] || err_exit $M
475x='-(-\\)-)-'
476[[ ${x/*%(()E\\)*/\1} == '(-\\)' ]] || err_exit $M
477x='-(-\")"-)-'
478[[ ${x/*%(()E\\Q\")*/\1} == '(-\")' ]] || err_exit $M
479x='-(-\")\"-)-'
480[[ ${x/*%(()E\\Q\")*/\1} == '(-\")' ]] || err_exit $M
481x=$'-(-\'")"-)-'
482[[ ${x/*%(()E\\Q\'Q\")*/\1} == $'-(-\'")"-)-' ]] || err_exit $M
483x=$'-(-\\\'")"-)-'
484[[ ${x/*%(()E\\Q\'Q\")*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
485x=$'-(-\\"\')\'\\"-)-'
486[[ ${x/*%(()E\\Q\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
487x=$'-(-\\\'")"-)-'
488[[ ${x/*%(()E\\L\'Q\")*/\1} == $'(-\\\'")"-)' ]] || err_exit $M
489x=$'-(-\\"\')\'\\"-)-'
490[[ ${x/*%(()E\\L\'Q\")*/\1} == $'(-\\"\')\'\\"-)' ]] || err_exit $M
491x=$'-(-\\"\')\\\'\\"-)-'
492[[ ${x/*%(()E\\L\'Q\")*/\1} == $'(-\\"\')\\\'\\"-)' ]] || err_exit $M
493x=$'-(-\\"\')\\\'\\"\'-)-'
494[[ ${x/*%(()E\\L\'Q\")*/\1} == $'-(-\\"\')\\\'\\"\'-)-' ]] || err_exit $M
495
496pattern=00
497var=100
498[[ $( print $(( ${var%%00} )) ) == 1 ]] || err_exit "arithmetic with embeddded patterns fails"
499[[ $( print $(( ${var%%$pattern} )) ) == 1 ]] || err_exit "arithmetic with embeddded pattern variables fails"
500if	[[ ax == @(a)* ]] && [[ ${.sh.match[1]:0:${#.sh.match[1]}}  != a ]]
501then	err_exit '${.sh.match[1]:1:${#.sh.match[1]}} not expanding correctly'
502fi
503
504string='foo(d:\nt\box\something)bar'
505expected='d:\nt\box\something'
506[[ ${string/*\(+([!\)])\)*/\1} == "$expected" ]] || err_exit "substring expansion failed '${string/*\(+([!\)])\)*/\1}' returned -- '$expected' expected"
507if	[[ $($SHELL -c $'export LC_ALL=C.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 ]]
508then	LC_ALL=C.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'
509fi
510{ $SHELL -c 'unset x;[[ ${SHELL:$x} == $SHELL ]]';} 2> /dev/null || err_exit '${var:$x} fails when x is not set'
511{ $SHELL -c 'x=;[[ ${SHELL:$x} == $SHELL ]]';} 2> /dev/null || err_exit '${var:$x} fails when x is null'
512
513#	subject		mode	pattern			result	#
514set --							\
515	'a$z'		'E'	'[$]|#'		'a($)z'	\
516	'a#z'		'E'	'[$]|#'		'a(#)z'	\
517	'a$z'		'Elr'	'[$]|#'		'a$z'	\
518	'a#z'		'Elr'	'[$]|#'		'a#z'	\
519	'a$'		'E'	'[$]|#'		'a($)'	\
520	'a#'		'E'	'[$]|#'		'a(#)'	\
521	'a$'		'Elr'	'[$]|#'		'a$'	\
522	'a#'		'Elr'	'[$]|#'		'a#'	\
523	'$z'		'E'	'[$]|#'		'($)z'	\
524	'#z'		'E'	'[$]|#'		'(#)z'	\
525	'$z'		'Elr'	'[$]|#'		'$z'	\
526	'#z'		'Elr'	'[$]|#'		'#z'	\
527	'$'		'E'	'[$]|#'		'($)'	\
528	'#'		'E'	'[$]|#'		'(#)'	\
529	'$'		'Elr'	'[$]|#'		'($)'	\
530	'#'		'Elr'	'[$]|#'		'(#)'	\
531	'a$z'		'E'	'\$|#'		'a$z()'	\
532	'a$z'		'E'	'\\$|#'		'a$z'	\
533	'a$z'		'E'	'\\\$|#'	'a($)z'	\
534	'a#z'		'E'	'\\\$|#'	'a(#)z'	\
535	'a$z'		'Elr'	'\\\$|#'	'a$z'	\
536	'a#z'		'Elr'	'\\\$|#'	'a#z'	\
537	'a$'		'E'	'\\\$|#'	'a($)'	\
538	'a#'		'E'	'\\\$|#'	'a(#)'	\
539	'a$'		'Elr'	'\\\$|#'	'a$'	\
540	'a#'		'Elr'	'\\\$|#'	'a#'	\
541	'$z'		'E'	'\\\$|#'	'($)z'	\
542	'#z'		'E'	'\\\$|#'	'(#)z'	\
543	'$z'		'Elr'	'\\\$|#'	'$z'	\
544	'#z'		'Elr'	'\\\$|#'	'#z'	\
545	'$'		'E'	'\\\$|#'	'($)'	\
546	'#'		'E'	'\\\$|#'	'(#)'	\
547	'$'		'Elr'	'\\\$|#'	'($)'	\
548	'#'		'Elr'	'\\\$|#'	'(#)'	\
549#	do not delete this line			#
550unset i o
551while	(( $# >= 4 ))
552do	i=$1
553	eval o="\${i/~($2)$3/\\(\\0\\)}"
554	if	[[ "$o" != "$4" ]]
555	then	err_exit "i='$1'; \${i/~($2)$3/\\(\\0\\)} failed -- expected '$4', got '$o'"
556	fi
557	eval o="\${i/~($2)($3)/\\(\\1\\)}"
558	if	[[ "$o" != "$4" ]]
559	then	err_exit "i='$1'; \${i/~($2)($3)/\\(\\1\\)} failed -- expected '$4', got '$o'"
560	fi
561	shift 4
562done
563
564#multibyte locale tests
565x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:0:1}" == a || err_exit ${x:0:1} should be a'
566x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1:1}" == "<2b|>" || err_exit ${x:1:1} should be <2b|>'
567x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:3:1}" == "<3d|\\>" || err_exit ${x:3:1} should be <3d|\>'
568x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:4:1}" == e || err_exit ${x:4:1} should bee'
569x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1}" == "<2b|>c<3d|\\>e" || print -u2   ${x:1}" should be <2b|>c<3d|\>e'
570x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x: -1:1}" == e || err_exit ${x: -1:1} should be e'
571x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x: -2:1}" == "<3d|\\>" || err_exit ${x: -2:1} == <3d|\>'
572x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1:3}" == "<2b|>c<3d|\\>" || err_exit ${x:1:3} should be <2b|>c<3d|\>'
573x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x:1:20}" == "<2b|>c<3d|\\>e" || err_exit ${x:1:20} should be <2b|>c<3d|\>e'
574x='a<2b|>c<3d|\>e' LC_ALL=debug $SHELL -c 'test "${x#??}" == "c<3d|\\>e" || err_exit "${x#??} should be c<3d|\>e'
575
576x='a one and a two'
577[[ "${x//~(E)\<.\>/}" == ' one and  two' ]]  || err_exit "\< and \> not working in with ere's"
578
579{
580$SHELL -c 'typeset x="123" ; integer i=100 ; print -n "${x:i:5}"'
581} 2> /dev/null || err_exit '${x:i:j} fails when i > strlen(x)'
582
583got=$($SHELL -c 'A=""; B="B"; for I in ${A[@]} ${B[@]}; do echo "\"$I\""; done')
584[[ $got == $'"B"' ]] || err_exit '"\"$I\"" fails when $I is empty string'
585
586A='|'
587[[ $A == $A ]] || err_exit 'With A="|",  [[ $A == $A ]] does not match'
588
589x="111 222 333 444 555 666"
590[[ $x == ~(E)(...).(...).(...) ]]
591[[ -v .sh.match[0] ]] ||   err_exit '[[ -v .sh.match[0] ]] should be true'
592[[ -v .sh.match[3] ]] ||   err_exit '[[ -v .sh.match[3] ]] should be true'
593[[ -v .sh.match[4] ]] &&   err_exit '[[ -v .sh.match[4] ]] should be false'
594[[ ${#.sh.match[@]} == 4 ]] || err_exit "\${#.sh.match[@]} should be 4, not ${#.sh.match[@]}"
595
596x="foo bar"
597dummy=${x/~(E)(*)/}
598[[ ${ print -v .sh.match;} ]] && err_exit 'print -v should show .sh.match empty when there are no matches'
599
600if	$SHELL -c 'set 1 2 3 4 5 6 7 8 9 10 11 12; : ${##[0-9]}' 2>/dev/null
601then	set 1 2 3 4 5 6 7 8 9 10 11 12
602	[[ ${##[0-9]} == 2 ]] || err_exit '${##[0-9]} should be 2 with $#==12'
603	[[ ${###[0-9]} == 2 ]] || err_exit '${###[0-9]} should be 2 with $#==12'
604	[[ ${#%[0-9]} == 1 ]] || err_exit '${#%[0-9]} should be 1 with $#==12'
605	[[ ${#%%[0-9]} == 1 ]] || err_exit '${#%%[0-9]} should be 1 with $#==12'
606else	err_exit '${##[0-9]} give syntax error'
607fi
608
609{
610  $SHELL -c 'x="a123 456 789z"; : ${x//{3}(\d)/ }' &
611  sleep .5; kill $!; wait $!
612} 2> /dev/null || err_exit $'tokenizer can\'t handle ${var op {..} }'
613
614
615function foo
616{
617	typeset x="123 456 789 abc"
618	typeset dummy="${x/~(E-g)([[:digit:]][[:digit:]])((X)|([[:digit:]]))([[:blank:]])/_}"
619	exp=$'(\n\t[0]=\'123 \'\n\t[1]=12\n\t[2]=3\n\t[4]=3\n\t[5]=\' \'\n)'
620	[[ $(print -v .sh.match) == "$exp" ]] || err_exit '.sh.match not correct with alternations'
621}
622foo
623
624x="a 1 b"
625d=${x/~(E)(([[:digit:]])[[:space:]]*|([[:alpha:]]))/X}
626[[ $(print -v .sh.match) == $'(\n\t[0]=a\n\t[1]=a\n\t[3]=a\n)' ]] || err_exit '.sh.match not sparse'
627
628unset v
629typeset -a arr=( 0 1 2 3 4 )
630for v in "${arr[@]:5}"
631do	err_exit "\${arr[@]:5} should not generate $v"
632	break
633done
634for v in "${arr[@]:1:0}"
635do	err_exit "\${arr[@]:1:0} should not generate ${v:-empty_string}"
636	break
637done
638for v in "${arr[@]:0:-1}"
639do	err_exit "\${arr[@]:0:-1} should not generate ${v:-empty_string}"
640	break
641done
642
643set 1 2 3 4
644for v in "${@:5}"
645do	err_exit "\${@:5} should not generate $v"
646	break
647done
648for v in "${@:1:0}"
649do	err_exit "\${@:1:0} should not generate ${v:-empty_string}"
650	break
651done
652for v in "${@:0:-1}"
653do	err_exit "\${@:0:-1} should not generate ${v:-empty_string}"
654	break
655done
656
657unset v d
658v=abbbc
659d="${v/~(E)b{2,4}/dummy}"
660[[ ${.sh.match} == bbb ]] || err_exit '.sh.match wrong after ${s/~(E)b{2,4}/dummy}'
661[[ $d == adummyc ]] || err_exit '${s/~(E)b{2,4}/dummy} not working'
662
663
664exit $((Errors<125?Errors:125))
665