1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4b30d1939SAndy Fiddaman#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11b30d1939SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
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
307c2fbfb3SApril Chin
3134f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3234f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT
3334f9b3eeSRoland Mainz
347c2fbfb3SApril Chin[[ ${.sh.version} == "$KSH_VERSION" ]] || err_exit '.sh.version != KSH_VERSION'
357c2fbfb3SApril Chinunset ss
3634f9b3eeSRoland Mainz[[ ${@ss} ]] && err_exit '${@ss} should be empty string when ss is unset'
3734f9b3eeSRoland Mainz[[ ${!ss} == ss ]] ||  err_exit '${!ss} should be ss when ss is unset'
3834f9b3eeSRoland Mainz[[ ${#ss} == 0 ]] ||  err_exit '${#ss} should be 0 when ss is unset'
39da2e3ebdSchin# RANDOM
40da2e3ebdSchinif	(( RANDOM==RANDOM || $RANDOM==$RANDOM ))
41da2e3ebdSchinthen	err_exit RANDOM variable not working
42da2e3ebdSchinfi
43da2e3ebdSchin# SECONDS
44da2e3ebdSchinsleep 3
45da2e3ebdSchinif	(( SECONDS < 2 ))
46da2e3ebdSchinthen	err_exit SECONDS variable not working
47da2e3ebdSchinfi
48da2e3ebdSchin# _
49da2e3ebdSchinset abc def
50da2e3ebdSchinif	[[ $_ != def ]]
51da2e3ebdSchinthen	err_exit _ variable not working
52da2e3ebdSchinfi
53da2e3ebdSchin# ERRNO
54da2e3ebdSchin#set abc def
55da2e3ebdSchin#rm -f foobar#
56da2e3ebdSchin#ERRNO=
57da2e3ebdSchin#2> /dev/null < foobar#
58da2e3ebdSchin#if	(( ERRNO == 0 ))
59da2e3ebdSchin#then	err_exit ERRNO variable not working
60da2e3ebdSchin#fi
61da2e3ebdSchin# PWD
62da2e3ebdSchinif	[[ !  $PWD -ef . ]]
6334f9b3eeSRoland Mainzthen	err_exit PWD variable failed, not equivalent to .
64da2e3ebdSchinfi
65da2e3ebdSchin# PPID
6634f9b3eeSRoland Mainzexp=$$
6734f9b3eeSRoland Mainzgot=${ $SHELL -c 'print $PPID'; }
6834f9b3eeSRoland Mainzif	[[ ${ $SHELL -c 'print $PPID'; } != $$ ]]
6934f9b3eeSRoland Mainzthen	err_exit "PPID variable failed -- expected '$exp', got '$got'"
70da2e3ebdSchinfi
71da2e3ebdSchin# OLDPWD
72da2e3ebdSchinold=$PWD
73da2e3ebdSchincd /
74da2e3ebdSchinif	[[ $OLDPWD != $old ]]
7534f9b3eeSRoland Mainzthen	err_exit "OLDPWD variable failed -- expected '$old', got '$OLDPWD'"
76da2e3ebdSchinfi
77da2e3ebdSchincd $old || err_exit cd failed
78da2e3ebdSchin# REPLY
79da2e3ebdSchinread <<-!
80da2e3ebdSchin	foobar
81da2e3ebdSchin	!
82da2e3ebdSchinif	[[ $REPLY != foobar ]]
83da2e3ebdSchinthen	err_exit REPLY variable not working
84da2e3ebdSchinfi
85da2e3ebdSchininteger save=$LINENO
86da2e3ebdSchin# LINENO
87da2e3ebdSchinLINENO=10
88da2e3ebdSchin#
89da2e3ebdSchin#  These lines intentionally left blank
90da2e3ebdSchin#
91da2e3ebdSchinif	(( LINENO != 13))
92da2e3ebdSchinthen	err_exit LINENO variable not working
93da2e3ebdSchinfi
94da2e3ebdSchinLINENO=save+10
95da2e3ebdSchinIFS=:
96da2e3ebdSchinx=a::b::c
97da2e3ebdSchinif	[[ $x != a::b::c ]]
9834f9b3eeSRoland Mainzthen	err_exit "word splitting on constants"
99da2e3ebdSchinfi
100da2e3ebdSchinset -- $x
101da2e3ebdSchinif	[[ $# != 5 ]]
102da2e3ebdSchinthen	err_exit ":: doesn't separate null arguments "
103da2e3ebdSchinfi
104da2e3ebdSchinset x
105da2e3ebdSchinif	x$1=0 2> /dev/null
106da2e3ebdSchinthen	err_exit "x\$1=value treated as an assignment"
107da2e3ebdSchinfi
108da2e3ebdSchin# check for attributes across subshells
109da2e3ebdSchintypeset -i x=3
110da2e3ebdSchiny=1/0
111b30d1939SAndy Fiddamanif	( x=y ) 2> /dev/null
1127c2fbfb3SApril Chinthen	err_exit "attributes not passed to subshells"
113da2e3ebdSchinfi
114da2e3ebdSchinunset x
115da2e3ebdSchinfunction x.set
116da2e3ebdSchin{
117da2e3ebdSchin	nameref foo=${.sh.name}.save
118da2e3ebdSchin	foo=${.sh.value}
119da2e3ebdSchin	.sh.value=$0
120da2e3ebdSchin}
121da2e3ebdSchinx=bar
122da2e3ebdSchinif	[[ $x != x.set ]]
123da2e3ebdSchinthen	err_exit 'x.set does not override assignment'
124da2e3ebdSchinfi
125da2e3ebdSchinx.get()
126da2e3ebdSchin{
127da2e3ebdSchin	nameref foo=${.sh.name}.save
128da2e3ebdSchin	.sh.value=$foo
129da2e3ebdSchin}
130da2e3ebdSchin
131da2e3ebdSchinif	[[ $x != bar ]]
132da2e3ebdSchinthen	err_exit 'x.get does not work correctly'
133da2e3ebdSchinfi
134da2e3ebdSchintypeset +n foo
135da2e3ebdSchinunset foo
136da2e3ebdSchinfoo=bar
137da2e3ebdSchin(
138da2e3ebdSchin	unset foo
139da2e3ebdSchin	set +u
140da2e3ebdSchin	if	[[ $foo != '' ]]
141da2e3ebdSchin	then	err_exit '$foo not null after unset in subsehll'
142da2e3ebdSchin	fi
143da2e3ebdSchin)
144da2e3ebdSchinif	[[ $foo != bar ]]
145da2e3ebdSchinthen	err_exit 'unset foo in subshell produces side effect '
146da2e3ebdSchinfi
147da2e3ebdSchinunset foo
148da2e3ebdSchinif	[[ $( { : ${foo?hi there} ; } 2>&1) != *'hi there' ]]
149da2e3ebdSchinthen	err_exit '${foo?hi there} with foo unset does not print hi there on 2'
150da2e3ebdSchinfi
151da2e3ebdSchinx=$0
152da2e3ebdSchinset foobar
153da2e3ebdSchinif	[[ ${@:0} != "$x foobar" ]]
154da2e3ebdSchinthen	err_exit '${@:0} not expanding correctly'
155da2e3ebdSchinfi
156da2e3ebdSchinset --
157da2e3ebdSchinif	[[ ${*:0:1} != "$0" ]]
158da2e3ebdSchinthen	err_exit '${@:0} not expanding correctly'
159da2e3ebdSchinfi
160da2e3ebdSchinACCESS=0
161da2e3ebdSchinfunction COUNT.set
162da2e3ebdSchin{
163da2e3ebdSchin        (( ACCESS++ ))
164da2e3ebdSchin}
165da2e3ebdSchinCOUNT=0
166da2e3ebdSchin(( COUNT++ ))
167da2e3ebdSchinif	(( COUNT != 1 || ACCESS!=2 ))
168da2e3ebdSchinthen	err_exit " set discipline failure COUNT=$COUNT ACCESS=$ACCESS"
169da2e3ebdSchinfi
170da2e3ebdSchinLANG=C > /dev/null 2>&1
171da2e3ebdSchinif	[[ $LANG != C ]]
172da2e3ebdSchinthen	err_exit "C locale not working"
173da2e3ebdSchinfi
174da2e3ebdSchinunset RANDOM
175da2e3ebdSchinunset -n foo
176da2e3ebdSchinfoo=junk
177da2e3ebdSchinfunction foo.get
178da2e3ebdSchin{
17934f9b3eeSRoland Mainz	.sh.value=stuff
180da2e3ebdSchin	unset -f foo.get
181da2e3ebdSchin}
182da2e3ebdSchinif	[[ $foo != stuff ]]
183da2e3ebdSchinthen	err_exit "foo.get discipline not working"
184da2e3ebdSchinfi
185da2e3ebdSchinif	[[ $foo != junk ]]
186da2e3ebdSchinthen	err_exit "foo.get discipline not working after unset"
187da2e3ebdSchinfi
188da2e3ebdSchin# special variables
189da2e3ebdSchinset -- 1 2 3 4 5 6 7 8 9 10
190da2e3ebdSchinsleep 1000 &
191da2e3ebdSchinif	[[ $(print -r -- ${#10}) != 2 ]]
192da2e3ebdSchinthen	err_exit '${#10}, where ${10}=10 not working'
193da2e3ebdSchinfi
194da2e3ebdSchinfor i in @ '*' ! '#' - '?' '$'
195da2e3ebdSchindo	false
196da2e3ebdSchin	eval foo='$'$i bar='$'{$i}
197da2e3ebdSchin	if	[[ ${foo} != "${bar}" ]]
198da2e3ebdSchin	then	err_exit "\$$i not equal to \${$i}"
199da2e3ebdSchin	fi
200da2e3ebdSchin	command eval bar='$'{$i%?} 2> /dev/null || err_exit "\${$i%?} gives syntax error"
201da2e3ebdSchin	if	[[ $i != [@*] && ${foo%?} != "$bar"  ]]
202da2e3ebdSchin	then	err_exit "\${$i%?} not correct"
203da2e3ebdSchin	fi
204da2e3ebdSchin	command eval bar='$'{$i#?} 2> /dev/null || err_exit "\${$i#?} gives syntax error"
205da2e3ebdSchin	if	[[ $i != [@*] && ${foo#?} != "$bar"  ]]
206da2e3ebdSchin	then	err_exit "\${$i#?} not correct"
207da2e3ebdSchin	fi
208da2e3ebdSchin	command eval foo='$'{$i} bar='$'{#$i} || err_exit "\${#$i} gives synta
209da2e3ebdSchinx error"
210da2e3ebdSchin	if	[[ $i != @([@*]) && ${#foo} != "$bar" ]]
211da2e3ebdSchin	then	err_exit "\${#$i} not correct"
212da2e3ebdSchin	fi
213da2e3ebdSchindone
214da2e3ebdSchinkill $!
215da2e3ebdSchinunset x
216da2e3ebdSchinCDPATH=/
21734f9b3eeSRoland Mainzx=$(cd ${tmp#/})
21834f9b3eeSRoland Mainzif	[[ $x != $tmp ]]
219da2e3ebdSchinthen	err_exit 'CDPATH does not display new directory'
220da2e3ebdSchinfi
221da2e3ebdSchinCDPATH=/:
22234f9b3eeSRoland Mainzx=$(cd ${tmp%/*}; cd ${tmp##*/})
223da2e3ebdSchinif	[[ $x ]]
224da2e3ebdSchinthen	err_exit 'CDPATH displays new directory when not used'
225da2e3ebdSchinfi
22634f9b3eeSRoland Mainzx=$(cd ${tmp#/})
22734f9b3eeSRoland Mainzif	[[ $x != $tmp ]]
22834f9b3eeSRoland Mainzthen	err_exit "CDPATH ${tmp#/} does not display new directory"
229da2e3ebdSchinfi
230da2e3ebdSchinTMOUT=100
231da2e3ebdSchin(TMOUT=20)
232da2e3ebdSchinif	(( TMOUT !=100 ))
233da2e3ebdSchinthen	err_exit 'setting TMOUT in subshell affects parent'
234da2e3ebdSchinfi
235da2e3ebdSchinunset y
236da2e3ebdSchinfunction setdisc # var
237da2e3ebdSchin{
238da2e3ebdSchin        eval function $1.get'
239da2e3ebdSchin        {
240da2e3ebdSchin                .sh.value=good
241da2e3ebdSchin        }
242da2e3ebdSchin        '
243da2e3ebdSchin}
244da2e3ebdSchiny=bad
245da2e3ebdSchinsetdisc y
246da2e3ebdSchinif	[[ $y != good ]]
247da2e3ebdSchinthen	err_exit 'setdisc function not working'
248da2e3ebdSchinfi
249da2e3ebdSchininteger x=$LINENO
250da2e3ebdSchin: $'\
251da2e3ebdSchin'
252da2e3ebdSchinif	(( LINENO != x+3  ))
253da2e3ebdSchinthen	err_exit '\<newline> gets linenumber count wrong'
254da2e3ebdSchinfi
255da2e3ebdSchinset --
256da2e3ebdSchinset -- "${@-}"
257da2e3ebdSchinif	(( $# !=1 ))
258da2e3ebdSchinthen	err_exit	'"${@-}" not expanding to null string'
259da2e3ebdSchinfi
2607c2fbfb3SApril Chinfor i in : % + / 3b '**' '***' '@@' '{' '[' '}' !!  '*a' '$foo'
261da2e3ebdSchindo      (eval : \${"$i"} 2> /dev/null) && err_exit "\${$i} not an syntax error"
262da2e3ebdSchindone
263da2e3ebdSchinunset IFS
264da2e3ebdSchin( IFS='  ' ; read -r a b c <<-!
265da2e3ebdSchin	x  y z
266da2e3ebdSchin	!
267da2e3ebdSchin	if	[[ $b ]]
268da2e3ebdSchin	then	err_exit 'IFS="  " not causing adjacent space to be null string'
269da2e3ebdSchin	fi
270da2e3ebdSchin)
271da2e3ebdSchinread -r a b c <<-!
272da2e3ebdSchinx  y z
273da2e3ebdSchin!
274da2e3ebdSchinif	[[ $b != y ]]
275da2e3ebdSchinthen	err_exit 'IFS not restored after subshell'
276da2e3ebdSchinfi
277da2e3ebdSchin
278da2e3ebdSchin# The next part generates 3428 IFS set/read tests.
279da2e3ebdSchin
280da2e3ebdSchinunset IFS x
281da2e3ebdSchinfunction split
282da2e3ebdSchin{
283da2e3ebdSchin	i=$1 s=$2 r=$3
284da2e3ebdSchin	IFS=': '
285da2e3ebdSchin	set -- $i
286da2e3ebdSchin	IFS=' '
287da2e3ebdSchin	g="[$#]"
288da2e3ebdSchin	while	:
289da2e3ebdSchin	do	case $# in
290da2e3ebdSchin		0)	break ;;
291da2e3ebdSchin		esac
292da2e3ebdSchin		g="$g($1)"
293da2e3ebdSchin		shift
294da2e3ebdSchin	done
295da2e3ebdSchin	case "$g" in
296da2e3ebdSchin	"$s")	;;
297da2e3ebdSchin	*)	err_exit "IFS=': '; set -- '$i'; expected '$s' got '$g'" ;;
298da2e3ebdSchin	esac
299da2e3ebdSchin	print "$i" | IFS=": " read arg rem; g="($arg)($rem)"
300da2e3ebdSchin	case "$g" in
301da2e3ebdSchin	"$r")	;;
302da2e3ebdSchin	*)	err_exit "IFS=': '; read '$i'; expected '$r' got '$g'" ;;
303da2e3ebdSchin	esac
304da2e3ebdSchin}
305da2e3ebdSchinfor str in 	\
306da2e3ebdSchin	'-'	\
307da2e3ebdSchin	'a'	\
308da2e3ebdSchin	'- -'	\
309da2e3ebdSchin	'- a'	\
310da2e3ebdSchin	'a -'	\
311da2e3ebdSchin	'a b'	\
312da2e3ebdSchin	'- - -'	\
313da2e3ebdSchin	'- - a'	\
314da2e3ebdSchin	'- a -'	\
315da2e3ebdSchin	'- a b'	\
316da2e3ebdSchin	'a - -'	\
317da2e3ebdSchin	'a - b'	\
318da2e3ebdSchin	'a b -'	\
319da2e3ebdSchin	'a b c'
320da2e3ebdSchindo
321da2e3ebdSchin	IFS=' '
322da2e3ebdSchin	set x $str
323da2e3ebdSchin	shift
324da2e3ebdSchin	case $# in
325da2e3ebdSchin	0)	continue ;;
326da2e3ebdSchin	esac
327da2e3ebdSchin	f1=$1
328da2e3ebdSchin	case $f1 in
329da2e3ebdSchin	'-')	f1='' ;;
330da2e3ebdSchin	esac
331da2e3ebdSchin	shift
332da2e3ebdSchin	case $# in
333da2e3ebdSchin	0)	for d0 in '' ' '
334da2e3ebdSchin		do
335da2e3ebdSchin			for d1 in '' ' ' ':' ' :' ': ' ' : '
336da2e3ebdSchin			do
337da2e3ebdSchin				case $f1$d1 in
338da2e3ebdSchin				'')	split "$d0$f1$d1" "[0]" "()()" ;;
339da2e3ebdSchin				' ')	;;
340da2e3ebdSchin				*)	split "$d0$f1$d1" "[1]($f1)" "($f1)()" ;;
341da2e3ebdSchin				esac
342da2e3ebdSchin			done
343da2e3ebdSchin		done
344da2e3ebdSchin		continue
345da2e3ebdSchin		;;
346da2e3ebdSchin	esac
347da2e3ebdSchin	f2=$1
348da2e3ebdSchin	case $f2 in
349da2e3ebdSchin	'-')	f2='' ;;
350da2e3ebdSchin	esac
351da2e3ebdSchin	shift
352da2e3ebdSchin	case $# in
353da2e3ebdSchin	0)	for d0 in '' ' '
354da2e3ebdSchin		do
355da2e3ebdSchin			for d1 in ' ' ':' ' :' ': ' ' : '
356da2e3ebdSchin			do
357da2e3ebdSchin				case ' ' in
358da2e3ebdSchin				$f1$d1|$d1$f2)	continue ;;
359da2e3ebdSchin				esac
360da2e3ebdSchin				for d2 in '' ' ' ':' ' :' ': ' ' : '
361da2e3ebdSchin				do
362da2e3ebdSchin					case $f2$d2 in
363da2e3ebdSchin					'')	split "$d0$f1$d1$f2$d2" "[1]($f1)" "($f1)()" ;;
364da2e3ebdSchin					' ')	;;
365da2e3ebdSchin					*)	split "$d0$f1$d1$f2$d2" "[2]($f1)($f2)" "($f1)($f2)" ;;
366da2e3ebdSchin					esac
367da2e3ebdSchin				done
368da2e3ebdSchin			done
369da2e3ebdSchin		done
370da2e3ebdSchin		continue
371da2e3ebdSchin		;;
372da2e3ebdSchin	esac
373da2e3ebdSchin	f3=$1
374da2e3ebdSchin	case $f3 in
375da2e3ebdSchin	'-')	f3='' ;;
376da2e3ebdSchin	esac
377da2e3ebdSchin	shift
378da2e3ebdSchin	case $# in
379da2e3ebdSchin	0)	for d0 in '' ' '
380da2e3ebdSchin		do
381da2e3ebdSchin			for d1 in ':' ' :' ': ' ' : '
382da2e3ebdSchin			do
383da2e3ebdSchin				case ' ' in
384da2e3ebdSchin				$f1$d1|$d1$f2)	continue ;;
385da2e3ebdSchin				esac
386da2e3ebdSchin				for d2 in ' ' ':' ' :' ': ' ' : '
387da2e3ebdSchin				do
388da2e3ebdSchin					case $f2$d2 in
389da2e3ebdSchin					' ')	continue ;;
390da2e3ebdSchin					esac
391da2e3ebdSchin					case ' ' in
392da2e3ebdSchin					$f2$d2|$d2$f3)	continue ;;
393da2e3ebdSchin					esac
394da2e3ebdSchin					for d3 in '' ' ' ':' ' :' ': ' ' : '
395da2e3ebdSchin					do
396da2e3ebdSchin						case $f3$d3 in
397da2e3ebdSchin						'')	split "$d0$f1$d1$f2$d2$f3$d3" "[2]($f1)($f2)" "($f1)($f2)" ;;
398da2e3ebdSchin						' ')	;;
399da2e3ebdSchin						*)	x=$f2$d2$f3$d3
400da2e3ebdSchin							x=${x#' '}
401da2e3ebdSchin							x=${x%' '}
402da2e3ebdSchin							split "$d0$f1$d1$f2$d2$f3$d3" "[3]($f1)($f2)($f3)" "($f1)($x)"
403da2e3ebdSchin							;;
404da2e3ebdSchin						esac
405da2e3ebdSchin					done
406da2e3ebdSchin				done
407da2e3ebdSchin			done
408da2e3ebdSchin		done
409da2e3ebdSchin		continue
410da2e3ebdSchin		;;
411da2e3ebdSchin	esac
412da2e3ebdSchindone
413da2e3ebdSchinunset IFS
414da2e3ebdSchin
415da2e3ebdSchinif	[[ $( (print ${12345:?}) 2>&1) != *12345* ]]
41634f9b3eeSRoland Mainzthen	err_exit 'incorrect error message with ${12345?}'
417da2e3ebdSchinfi
418da2e3ebdSchinunset foobar
419da2e3ebdSchinif	[[ $( (print ${foobar:?}) 2>&1) != *foobar* ]]
42034f9b3eeSRoland Mainzthen	err_exit 'incorrect error message with ${foobar?}'
421da2e3ebdSchinfi
422da2e3ebdSchinunset bar
423da2e3ebdSchinif	[[ $( (print ${bar:?bam}) 2>&1) != *bar*bam* ]]
42434f9b3eeSRoland Mainzthen	err_exit 'incorrect error message with ${foobar?}'
425da2e3ebdSchinfi
426da2e3ebdSchin{ $SHELL -c '
427da2e3ebdSchinfunction foo
428da2e3ebdSchin{
429da2e3ebdSchin	typeset SECONDS=0
430da2e3ebdSchin	sleep 1.5
431da2e3ebdSchin	print $SECONDS
43234f9b3eeSRoland Mainz
433da2e3ebdSchin}
434da2e3ebdSchinx=$(foo)
43534f9b3eeSRoland Mainz(( x >1 && x < 2 ))
436da2e3ebdSchin'
437da2e3ebdSchin} 2> /dev/null   || err_exit 'SECONDS not working in function'
43834f9b3eeSRoland Mainzcat > $tmp/script <<-\!
439da2e3ebdSchin	posixfun()
440da2e3ebdSchin	{
441da2e3ebdSchin		unset x
442da2e3ebdSchin	 	nameref x=$1
443da2e3ebdSchin	 	print  -r -- "$x"
444da2e3ebdSchin	}
445da2e3ebdSchin	function fun
446da2e3ebdSchin	{
447da2e3ebdSchin	 	nameref x=$1
448da2e3ebdSchin	 	print  -r -- "$x"
449da2e3ebdSchin	}
450da2e3ebdSchin	if	[[ $1 ]]
451da2e3ebdSchin	then	file=${.sh.file}
452da2e3ebdSchin	else	print -r -- "${.sh.file}"
453da2e3ebdSchin	fi
454da2e3ebdSchin!
45534f9b3eeSRoland Mainzchmod +x $tmp/script
45634f9b3eeSRoland Mainz. $tmp/script  1
45734f9b3eeSRoland Mainz[[ $file == $tmp/script ]] || err_exit ".sh.file not working for dot scripts"
45834f9b3eeSRoland Mainz[[ $($SHELL $tmp/script) == $tmp/script ]] || err_exit ".sh.file not working for scripts"
45934f9b3eeSRoland Mainz[[ $(posixfun .sh.file) == $tmp/script ]] || err_exit ".sh.file not working for posix functions"
46034f9b3eeSRoland Mainz[[ $(fun .sh.file) == $tmp/script ]] || err_exit ".sh.file not working for functions"
461da2e3ebdSchin[[ $(posixfun .sh.fun) == posixfun ]] || err_exit ".sh.fun not working for posix functions"
462da2e3ebdSchin[[ $(fun .sh.fun) == fun ]] || err_exit ".sh.fun not working for functions"
463da2e3ebdSchin[[ $(posixfun .sh.subshell) == 1 ]] || err_exit ".sh.subshell not working for posix functions"
464da2e3ebdSchin[[ $(fun .sh.subshell) == 1 ]] || err_exit ".sh.subshell not working for functions"
465da2e3ebdSchin(
466da2e3ebdSchin    [[ $(posixfun .sh.subshell) == 2 ]]  || err_exit ".sh.subshell not working for posix functions in subshells"
467da2e3ebdSchin    [[ $(fun .sh.subshell) == 2 ]]  || err_exit ".sh.subshell not working for functions in subshells"
468da2e3ebdSchin    (( .sh.subshell == 1 )) || err_exit ".sh.subshell not working in a subshell"
469da2e3ebdSchin)
470da2e3ebdSchinTIMEFORMAT='this is a test'
471da2e3ebdSchin[[ $({ { time :;} 2>&1;}) == "$TIMEFORMAT" ]] || err_exit 'TIMEFORMAT not working'
472da2e3ebdSchin: ${.sh.version}
473da2e3ebdSchin[[ $(alias integer) == *.sh.* ]] && err_exit '.sh. prefixed to alias name'
474da2e3ebdSchin: ${.sh.version}
475da2e3ebdSchin[[ $(whence rm) == *.sh.* ]] && err_exit '.sh. prefixed to tracked alias name'
476da2e3ebdSchin: ${.sh.version}
4777c2fbfb3SApril Chin[[ $(cd /bin;env | grep PWD=) == *.sh.* ]] && err_exit '.sh. prefixed to PWD'
478da2e3ebdSchin# unset discipline bug fix
479da2e3ebdSchindave=dave
480da2e3ebdSchinfunction dave.unset
481da2e3ebdSchin{
482da2e3ebdSchin    unset dave
483da2e3ebdSchin}
484da2e3ebdSchinunset dave
485da2e3ebdSchin[[ $(typeset +f) == *dave.* ]] && err_exit 'unset discipline not removed'
4867c2fbfb3SApril Chin
487b30d1939SAndy Fiddamanx=$(
488b30d1939SAndy Fiddaman	dave=dave
489b30d1939SAndy Fiddaman	function dave.unset
490b30d1939SAndy Fiddaman	{
491b30d1939SAndy Fiddaman		print dave.unset
492b30d1939SAndy Fiddaman	}
493b30d1939SAndy Fiddaman)
494b30d1939SAndy Fiddaman[[ $x == dave.unset ]] || err_exit 'unset discipline not called with subset completion'
495b30d1939SAndy Fiddaman
49634f9b3eeSRoland Mainzprint 'print ${VAR}' > $tmp/script
4977c2fbfb3SApril Chinunset VAR
49834f9b3eeSRoland MainzVAR=new $tmp/script > $tmp/out
49934f9b3eeSRoland Mainzgot=$(<$tmp/out)
5007c2fbfb3SApril Chin[[ $got == new ]] || err_exit "previously unset environment variable not passed to script, expected 'new', got '$got'"
5017c2fbfb3SApril Chin[[ ! $VAR ]] || err_exit "previously unset environment variable set after script, expected '', got '$VAR'"
5027c2fbfb3SApril Chinunset VAR
5037c2fbfb3SApril ChinVAR=old
50434f9b3eeSRoland MainzVAR=new $tmp/script > $tmp/out
50534f9b3eeSRoland Mainzgot=$(<$tmp/out)
5067c2fbfb3SApril Chin[[ $got == new ]] || err_exit "environment variable covering local variable not passed to script, expected 'new', got '$got'"
5077c2fbfb3SApril Chin[[ $VAR == old ]] || err_exit "previously set local variable changed after script, expected 'old', got '$VAR'"
5087c2fbfb3SApril Chinunset VAR
5097c2fbfb3SApril Chinexport VAR=old
51034f9b3eeSRoland MainzVAR=new $tmp/script > $tmp/out
51134f9b3eeSRoland Mainzgot=$(<$tmp/out)
5127c2fbfb3SApril Chin[[ $got == new ]] || err_exit "environment variable covering environment variable not passed to script, expected 'new', got '$got'"
5137c2fbfb3SApril Chin[[ $VAR == old ]] || err_exit "previously set environment variable changed after script, expected 'old', got '$VAR'"
5147c2fbfb3SApril Chin
515da2e3ebdSchin(
516da2e3ebdSchin	unset dave
517da2e3ebdSchin	function  dave.append
518da2e3ebdSchin	{
519da2e3ebdSchin		.sh.value+=$dave
520da2e3ebdSchin		dave=
521da2e3ebdSchin	}
522da2e3ebdSchin	dave=foo; dave+=bar
523da2e3ebdSchin	[[ $dave == barfoo ]] || exit 2
52434f9b3eeSRoland Mainz) 2> /dev/null
525da2e3ebdSchincase $? in
526da2e3ebdSchin0)	 ;;
527da2e3ebdSchin1)	 err_exit 'append discipline not implemented';;
528da2e3ebdSchin*)	 err_exit 'append discipline not working';;
529da2e3ebdSchinesac
530da2e3ebdSchin.sh.foobar=hello
531da2e3ebdSchin{
532da2e3ebdSchin	function .sh.foobar.get
533da2e3ebdSchin	{
534da2e3ebdSchin		.sh.value=world
53534f9b3eeSRoland Mainz	}
53634f9b3eeSRoland Mainz} 2> /dev/null || err_exit "cannot add get discipline to .sh.foobar"
537da2e3ebdSchin[[ ${.sh.foobar} == world ]]  || err_exit 'get discipline for .sh.foobar not working'
538da2e3ebdSchinx='a|b'
539da2e3ebdSchinIFS='|'
540da2e3ebdSchinset -- $x
541da2e3ebdSchin[[ $2 == b ]] || err_exit '$2 should be b after set'
542da2e3ebdSchinexec 3>&2 2> /dev/null
543da2e3ebdSchinset -x
544da2e3ebdSchin( IFS= ) 2> /dev/null
545da2e3ebdSchinset +x
546da2e3ebdSchinexec 2>&3-
547da2e3ebdSchinset -- $x
548da2e3ebdSchin[[ $2 == b ]] || err_exit '$2 should be b after subshell'
549da2e3ebdSchin: & pid=$!
550da2e3ebdSchin( : & )
551da2e3ebdSchin[[ $pid == $! ]] || err_exit '$! value not preserved across subshells'
552da2e3ebdSchinunset foo
553da2e3ebdSchintypeset -A foo
554da2e3ebdSchinfunction foo.set
555da2e3ebdSchin{
556da2e3ebdSchin	case ${.sh.subscript} in
557da2e3ebdSchin	bar)	if	((.sh.value > 1 ))
558da2e3ebdSchin	        then	.sh.value=5
559da2e3ebdSchin			foo[barrier_hit]=yes
560da2e3ebdSchin		fi
561da2e3ebdSchin		;;
562da2e3ebdSchin	barrier_hit)
563b30d1939SAndy Fiddaman		if	[[ ${.sh.value} == yes ]]
564da2e3ebdSchin		then	foo[barrier_not_hit]=no
565da2e3ebdSchin		else	foo[barrier_not_hit]=yes
566da2e3ebdSchin		fi
567da2e3ebdSchin		;;
568da2e3ebdSchin	esac
569da2e3ebdSchin}
57034f9b3eeSRoland Mainzfoo[barrier_hit]=no
571da2e3ebdSchinfoo[bar]=1
572da2e3ebdSchin(( foo[bar] == 1 )) || err_exit 'foo[bar] should be 1'
573da2e3ebdSchin[[ ${foo[barrier_hit]} == no ]] || err_exit 'foo[barrier_hit] should be no'
574da2e3ebdSchin[[ ${foo[barrier_not_hit]} == yes ]] || err_exit 'foo[barrier_not_hit] should be yes'
57534f9b3eeSRoland Mainzfoo[barrier_hit]=no
576da2e3ebdSchinfoo[bar]=2
577da2e3ebdSchin(( foo[bar] == 5 )) || err_exit 'foo[bar] should be 5'
578da2e3ebdSchin[[ ${foo[barrier_hit]} == yes ]] || err_exit 'foo[barrier_hit] should be yes'
579da2e3ebdSchin[[ ${foo[barrier_not_hit]} == no ]] || err_exit 'foo[barrier_not_hit] should be no'
580da2e3ebdSchinunset x
581da2e3ebdSchintypeset -i x
582da2e3ebdSchinfunction x.set
583da2e3ebdSchin{
584da2e3ebdSchin	typeset sub=${.sh.subscript}
585da2e3ebdSchin	(( sub > 0 )) && (( x[sub-1]= x[sub-1] + .sh.value ))
586da2e3ebdSchin}
587da2e3ebdSchinx[0]=0 x[1]=1 x[2]=2 x[3]=3
588da2e3ebdSchin[[ ${x[@]} == '12 8 5 3' ]] || err_exit 'set discipline for indexed array not working correctly'
58934f9b3eeSRoland Mainzfloat seconds
590da2e3ebdSchin((SECONDS=3*4))
59134f9b3eeSRoland Mainzseconds=SECONDS
59234f9b3eeSRoland Mainz(( seconds < 12 || seconds > 12.1 )) &&  err_exit "SECONDS is $seconds and should be close to 12"
5937c2fbfb3SApril Chinunset a
5947c2fbfb3SApril Chinfunction a.set
5957c2fbfb3SApril Chin{
5967c2fbfb3SApril Chin	print -r -- "${.sh.name}=${.sh.value}"
5977c2fbfb3SApril Chin}
5987c2fbfb3SApril Chin[[ $(a=1) == a=1 ]] || err_exit 'set discipline not working in subshell assignment'
5997c2fbfb3SApril Chin[[ $(a=1 :) == a=1 ]] || err_exit 'set discipline not working in subshell command'
6007c2fbfb3SApril Chin
6017c2fbfb3SApril Chin[[ ${.sh.subshell} == 0 ]] || err_exit '${.sh.subshell} should be 0'
6027c2fbfb3SApril Chin(
6037c2fbfb3SApril Chin	[[ ${.sh.subshell} == 1 ]] || err_exit '${.sh.subshell} should be 1'
6047c2fbfb3SApril Chin	(
6057c2fbfb3SApril Chin		[[ ${.sh.subshell} == 2 ]] || err_exit '${.sh.subshell} should be 2'
6067c2fbfb3SApril Chin	)
6077c2fbfb3SApril Chin)
6087c2fbfb3SApril Chin
6097c2fbfb3SApril Chinset -- {1..32768}
6107c2fbfb3SApril Chin(( $# == 32768 )) || err_exit "\$# failed -- expected 32768, got $#"
6117c2fbfb3SApril Chinset --
6127c2fbfb3SApril Chin
6137c2fbfb3SApril Chinunset r v x
6147c2fbfb3SApril Chinpath=$PATH
6157c2fbfb3SApril Chinx=foo
6167c2fbfb3SApril Chinfor v in EDITOR VISUAL OPTIND CDPATH FPATH PATH ENV LINENO RANDOM SECONDS _
6177c2fbfb3SApril Chindo	nameref r=$v
6187c2fbfb3SApril Chin	unset $v
6197c2fbfb3SApril Chin	if	( $SHELL -c "unset $v; : \$$v" ) 2>/dev/null
6207c2fbfb3SApril Chin	then	[[ $r ]] && err_exit "unset $v failed -- expected '', got '$r'"
6217c2fbfb3SApril Chin		r=$x
6227c2fbfb3SApril Chin		[[ $r == $x ]] || err_exit "$v=$x failed -- expected '$x', got '$r'"
6237c2fbfb3SApril Chin	else	err_exit "unset $v; : \$$v failed"
6247c2fbfb3SApril Chin	fi
6257c2fbfb3SApril Chindone
62634f9b3eeSRoland Mainz
62734f9b3eeSRoland Mainzx=x
6287c2fbfb3SApril Chinfor v in LC_ALL LC_CTYPE LC_MESSAGES LC_COLLATE LC_NUMERIC
6297c2fbfb3SApril Chindo	nameref r=$v
6307c2fbfb3SApril Chin	unset $v
6317c2fbfb3SApril Chin	[[ $r ]] && err_exit "unset $v failed -- expected '', got '$r'"
6327c2fbfb3SApril Chin	d=$($SHELL -c "$v=$x" 2>&1)
6337c2fbfb3SApril Chin	[[ $d ]] || err_exit "$v=$x failed -- expected locale diagnostic"
63434f9b3eeSRoland Mainz	{ g=$( r=$x; print -- $r ); } 2>/dev/null
63534f9b3eeSRoland Mainz	[[ $g == '' ]] || err_exit "$v=$x failed -- expected '', got '$g'"
63634f9b3eeSRoland Mainz	{ g=$( r=C; r=$x; print -- $r ); } 2>/dev/null
63734f9b3eeSRoland Mainz	[[ $g == 'C' ]] || err_exit "$v=C; $v=$x failed -- expected 'C', got '$g'"
6387c2fbfb3SApril Chindone
6397c2fbfb3SApril ChinPATH=$path
6407c2fbfb3SApril Chin
64134f9b3eeSRoland Mainzcd $tmp
64234f9b3eeSRoland Mainz
64334f9b3eeSRoland Mainzprint print -n zzz > zzz
64434f9b3eeSRoland Mainzchmod +x zzz
64534f9b3eeSRoland Mainzexp='aaazzz'
64634f9b3eeSRoland Mainzgot=$($SHELL -c 'unset SHLVL; print -n aaa; ./zzz' 2>&1) >/dev/null 2>&1
64734f9b3eeSRoland Mainz[[ $got == "$exp" ]] || err_exit "unset SHLVL causes script failure -- expected '$exp', got '$got'"
64834f9b3eeSRoland Mainz
64934f9b3eeSRoland Mainzmkdir glean
65034f9b3eeSRoland Mainzfor cmd in date ok
65134f9b3eeSRoland Mainzdo	exp="$cmd ok"
65234f9b3eeSRoland Mainz	rm -f $cmd
65334f9b3eeSRoland Mainz	print print $exp > glean/$cmd
65434f9b3eeSRoland Mainz	chmod +x glean/$cmd
65534f9b3eeSRoland Mainz	got=$(CDPATH=:.. $SHELL -c "PATH=:/bin:/usr/bin; date > /dev/null; cd glean && ./$cmd" 2>&1)
65634f9b3eeSRoland Mainz	[[ $got == "$exp" ]] || err_exit "cd with CDPATH after PATH change failed -- expected '$exp', got '$got'"
65734f9b3eeSRoland Mainzdone
65834f9b3eeSRoland Mainz
6593e14f97fSRoger A. Faulknerv=LC_CTYPE
6603e14f97fSRoger A. Faulknerunset $v
6613e14f97fSRoger A. Faulkner[[ -v $v ]] && err_exit "unset $v; [[ -v $v ]] failed"
6623e14f97fSRoger A. Faulknereval $v=C
6633e14f97fSRoger A. Faulkner[[ -v $v ]] || err_exit "$v=C; [[ -v $v ]] failed"
6643e14f97fSRoger A. Faulkner
6653e14f97fSRoger A. Faulknercmd='set --nounset; unset foo; : ${!foo*}'
6663e14f97fSRoger A. Faulkner$SHELL -c "$cmd" 2>/dev/null || err_exit "'$cmd' exit status $?, expected 0"
6673e14f97fSRoger A. Faulkner
668b30d1939SAndy FiddamanSHLVL=1
669b30d1939SAndy Fiddamanlevel=$($SHELL -c $'$SHELL -c \'print -r "$SHLVL"\'')
670b30d1939SAndy Fiddaman[[ $level  == 3 ]]  || err_exit "SHLVL should be 3 not $level"
671b30d1939SAndy Fiddaman
672b30d1939SAndy Fiddaman[[ $($SHELL -c '{ x=1; : ${x.};print ok;}' 2> /dev/null) == ok ]] || err_exit '${x.} where x is a simple variable causes shell to abort'
673b30d1939SAndy Fiddaman
674b30d1939SAndy Fiddaman$SHELL -c 'unset .sh' 2> /dev/null
675b30d1939SAndy Fiddaman[[ $? == 1 ]] || err_exit 'unset .sh should return 1'
676b30d1939SAndy Fiddaman
677*5b8dd251SAndy Fiddaman# Keep the list in sync (minus ".sh") with shtab_variables[] in
678*5b8dd251SAndy Fiddaman# src/cmd/ksh93/data/variables.c Note: as long as changing $PATH forks a
679*5b8dd251SAndy Fiddaman# virtual subshell, "PATH" should also be excluded below.
680*5b8dd251SAndy Fiddamanset -- \
681*5b8dd251SAndy Fiddaman	"PS1" \
682*5b8dd251SAndy Fiddaman	"PS2" \
683*5b8dd251SAndy Fiddaman	"IFS" \
684*5b8dd251SAndy Fiddaman	"PWD" \
685*5b8dd251SAndy Fiddaman	"HOME" \
686*5b8dd251SAndy Fiddaman	"MAIL" \
687*5b8dd251SAndy Fiddaman	"REPLY" \
688*5b8dd251SAndy Fiddaman	"SHELL" \
689*5b8dd251SAndy Fiddaman	"EDITOR" \
690*5b8dd251SAndy Fiddaman	"MAILCHECK" \
691*5b8dd251SAndy Fiddaman	"RANDOM" \
692*5b8dd251SAndy Fiddaman	"ENV" \
693*5b8dd251SAndy Fiddaman	"HISTFILE" \
694*5b8dd251SAndy Fiddaman	"HISTSIZE" \
695*5b8dd251SAndy Fiddaman	"HISTEDIT" \
696*5b8dd251SAndy Fiddaman	"HISTCMD" \
697*5b8dd251SAndy Fiddaman	"FCEDIT" \
698*5b8dd251SAndy Fiddaman	"CDPATH" \
699*5b8dd251SAndy Fiddaman	"MAILPATH" \
700*5b8dd251SAndy Fiddaman	"PS3" \
701*5b8dd251SAndy Fiddaman	"OLDPWD" \
702*5b8dd251SAndy Fiddaman	"VISUAL" \
703*5b8dd251SAndy Fiddaman	"COLUMNS" \
704*5b8dd251SAndy Fiddaman	"LINES" \
705*5b8dd251SAndy Fiddaman	"PPID" \
706*5b8dd251SAndy Fiddaman	"_" \
707*5b8dd251SAndy Fiddaman	"TMOUT" \
708*5b8dd251SAndy Fiddaman	"SECONDS" \
709*5b8dd251SAndy Fiddaman	"LINENO" \
710*5b8dd251SAndy Fiddaman	"OPTARG" \
711*5b8dd251SAndy Fiddaman	"OPTIND" \
712*5b8dd251SAndy Fiddaman	"PS4" \
713*5b8dd251SAndy Fiddaman	"FPATH" \
714*5b8dd251SAndy Fiddaman	"LANG" \
715*5b8dd251SAndy Fiddaman	"LC_ALL" \
716*5b8dd251SAndy Fiddaman	"LC_COLLATE" \
717*5b8dd251SAndy Fiddaman	"LC_CTYPE" \
718*5b8dd251SAndy Fiddaman	"LC_MESSAGES" \
719*5b8dd251SAndy Fiddaman	"LC_NUMERIC" \
720*5b8dd251SAndy Fiddaman	"FIGNORE" \
721*5b8dd251SAndy Fiddaman	"KSH_VERSION" \
722*5b8dd251SAndy Fiddaman	"JOBMAX" \
723*5b8dd251SAndy Fiddaman	".sh.edchar" \
724*5b8dd251SAndy Fiddaman	".sh.edcol" \
725*5b8dd251SAndy Fiddaman	".sh.edtext" \
726*5b8dd251SAndy Fiddaman	".sh.edmode" \
727*5b8dd251SAndy Fiddaman	".sh.name" \
728*5b8dd251SAndy Fiddaman	".sh.subscript" \
729*5b8dd251SAndy Fiddaman	".sh.value" \
730*5b8dd251SAndy Fiddaman	".sh.version" \
731*5b8dd251SAndy Fiddaman	".sh.dollar" \
732*5b8dd251SAndy Fiddaman	".sh.match" \
733*5b8dd251SAndy Fiddaman	".sh.command" \
734*5b8dd251SAndy Fiddaman	".sh.file" \
735*5b8dd251SAndy Fiddaman	".sh.fun" \
736*5b8dd251SAndy Fiddaman	".sh.lineno" \
737*5b8dd251SAndy Fiddaman	".sh.subshell" \
738*5b8dd251SAndy Fiddaman	".sh.level" \
739*5b8dd251SAndy Fiddaman	".sh.stats" \
740*5b8dd251SAndy Fiddaman	".sh.math" \
741*5b8dd251SAndy Fiddaman	".sh.pool" \
742*5b8dd251SAndy Fiddaman	".sh.pid" \
743*5b8dd251SAndy Fiddaman	"SHLVL" \
744*5b8dd251SAndy Fiddaman	"CSWIDTH"
745*5b8dd251SAndy Fiddaman
746*5b8dd251SAndy Fiddaman# ... upper/lowercase test
747*5b8dd251SAndy Fiddaman$SHELL -c '
748*5b8dd251SAndy Fiddaman       typeset -u upper
749*5b8dd251SAndy Fiddaman       typeset -l lower
750*5b8dd251SAndy Fiddaman       errors=0
751*5b8dd251SAndy Fiddaman       PS1=/dev/null/test_my_case_too
752*5b8dd251SAndy Fiddaman       PS2=$PS1 PS3=$PS1 PS4=$PS1 OPTARG=$PS1 IFS=$PS1 FPATH=$PS1 FIGNORE=$PS1 CSWIDTH=$PS1
753*5b8dd251SAndy Fiddaman       for var
754*5b8dd251SAndy Fiddaman       do      case $var in
755*5b8dd251SAndy Fiddaman               RANDOM | HISTCMD | _ | SECONDS | LINENO | JOBMAX | .sh.stats)
756*5b8dd251SAndy Fiddaman                       # these are expected to fail below as their values change; just test against crashing
757*5b8dd251SAndy Fiddaman                       typeset -u "$var"
758*5b8dd251SAndy Fiddaman                       typeset -l "$var"
759*5b8dd251SAndy Fiddaman                       continue ;;
760*5b8dd251SAndy Fiddaman               esac
761*5b8dd251SAndy Fiddaman               nameref val=$var
762*5b8dd251SAndy Fiddaman               upper=$val
763*5b8dd251SAndy Fiddaman               lower=$val
764*5b8dd251SAndy Fiddaman               typeset -u "$var"
765*5b8dd251SAndy Fiddaman               if      [[ $val != "$upper" ]]
766*5b8dd251SAndy Fiddaman               then    echo "  $0: typeset -u does not work on special variable $var" \
767*5b8dd251SAndy Fiddaman                               "(expected $(printf %q "$upper"), got $(printf %q "$val"))" >&2
768*5b8dd251SAndy Fiddaman                       let errors++
769*5b8dd251SAndy Fiddaman               fi
770*5b8dd251SAndy Fiddaman               typeset -l "$var"
771*5b8dd251SAndy Fiddaman               if      [[ $val != "$lower" ]]
772*5b8dd251SAndy Fiddaman               then    echo "  $0: typeset -l does not work on special variable $var" \
773*5b8dd251SAndy Fiddaman                               "(expected $(printf %q "$lower"), got $(printf %q "$val"))" >&2
774*5b8dd251SAndy Fiddaman                       let errors++
775*5b8dd251SAndy Fiddaman               fi
776*5b8dd251SAndy Fiddaman       done
777*5b8dd251SAndy Fiddaman       exit $((errors + 1))
778*5b8dd251SAndy Fiddaman' changecase_test "$@" PATH    # do include PATH here as well
779*5b8dd251SAndy Fiddaman(((e = $?) == 1)) || err_exit "typeset -l/-u doesn't work on special variables" \
780*5b8dd251SAndy Fiddaman       "(exit status $e$( ((e>128)) && print -n / && kill -l "$e"))"
781*5b8dd251SAndy Fiddaman
782b30d1939SAndy Fiddamanexit $((Errors<125?Errors:125))
783