xref: /onnv-gate/usr/src/lib/libshell/common/tests/variables.sh (revision 12068:08a39a083754)
14887Schin########################################################################
24887Schin#                                                                      #
34887Schin#               This software is part of the ast package               #
4*12068SRoger.Faulkner@Oracle.COM#          Copyright (c) 1982-2010 AT&T Intellectual Property          #
54887Schin#                      and is licensed under the                       #
64887Schin#                  Common Public License, Version 1.0                  #
78462SApril.Chin@Sun.COM#                    by AT&T Intellectual Property                     #
84887Schin#                                                                      #
94887Schin#                A copy of the License is available at                 #
104887Schin#            http://www.opensource.org/licenses/cpl1.0.txt             #
114887Schin#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
124887Schin#                                                                      #
134887Schin#              Information and Software Systems Research               #
144887Schin#                            AT&T Research                             #
154887Schin#                           Florham Park NJ                            #
164887Schin#                                                                      #
174887Schin#                  David Korn <dgk@research.att.com>                   #
184887Schin#                                                                      #
194887Schin########################################################################
204887Schinfunction err_exit
214887Schin{
224887Schin	print -u2 -n "\t"
234887Schin	print -u2 -r ${Command}[$1]: "${@:2}"
244887Schin	let Errors+=1
254887Schin}
264887Schinalias err_exit='err_exit $LINENO'
274887Schin
284887SchinCommand=${0##*/}
294887Schininteger Errors=0
308462SApril.Chin@Sun.COM
3110898Sroland.mainz@nrubsig.orgtmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3210898Sroland.mainz@nrubsig.orgtrap "cd /; rm -rf $tmp" EXIT
3310898Sroland.mainz@nrubsig.org
348462SApril.Chin@Sun.COM[[ ${.sh.version} == "$KSH_VERSION" ]] || err_exit '.sh.version != KSH_VERSION'
358462SApril.Chin@Sun.COMunset ss
3610898Sroland.mainz@nrubsig.org[[ ${@ss} ]] && err_exit '${@ss} should be empty string when ss is unset'
3710898Sroland.mainz@nrubsig.org[[ ${!ss} == ss ]] ||  err_exit '${!ss} should be ss when ss is unset'
3810898Sroland.mainz@nrubsig.org[[ ${#ss} == 0 ]] ||  err_exit '${#ss} should be 0 when ss is unset'
394887Schin# RANDOM
404887Schinif	(( RANDOM==RANDOM || $RANDOM==$RANDOM ))
414887Schinthen	err_exit RANDOM variable not working
424887Schinfi
434887Schin# SECONDS
444887Schinsleep 3
454887Schinif	(( SECONDS < 2 ))
464887Schinthen	err_exit SECONDS variable not working
474887Schinfi
484887Schin# _
494887Schinset abc def
504887Schinif	[[ $_ != def ]]
514887Schinthen	err_exit _ variable not working
524887Schinfi
534887Schin# ERRNO
544887Schin#set abc def
554887Schin#rm -f foobar#
564887Schin#ERRNO=
574887Schin#2> /dev/null < foobar#
584887Schin#if	(( ERRNO == 0 ))
594887Schin#then	err_exit ERRNO variable not working
604887Schin#fi
614887Schin# PWD
624887Schinif	[[ !  $PWD -ef . ]]
6310898Sroland.mainz@nrubsig.orgthen	err_exit PWD variable failed, not equivalent to .
644887Schinfi
654887Schin# PPID
6610898Sroland.mainz@nrubsig.orgexp=$$
6710898Sroland.mainz@nrubsig.orggot=${ $SHELL -c 'print $PPID'; }
6810898Sroland.mainz@nrubsig.orgif	[[ ${ $SHELL -c 'print $PPID'; } != $$ ]]
6910898Sroland.mainz@nrubsig.orgthen	err_exit "PPID variable failed -- expected '$exp', got '$got'"
704887Schinfi
714887Schin# OLDPWD
724887Schinold=$PWD
734887Schincd /
744887Schinif	[[ $OLDPWD != $old ]]
7510898Sroland.mainz@nrubsig.orgthen	err_exit "OLDPWD variable failed -- expected '$old', got '$OLDPWD'"
764887Schinfi
774887Schincd $old || err_exit cd failed
784887Schin# REPLY
794887Schinread <<-!
804887Schin	foobar
814887Schin	!
824887Schinif	[[ $REPLY != foobar ]]
834887Schinthen	err_exit REPLY variable not working
844887Schinfi
854887Schininteger save=$LINENO
864887Schin# LINENO
874887SchinLINENO=10
884887Schin#
894887Schin#  These lines intentionally left blank
904887Schin#
914887Schinif	(( LINENO != 13))
924887Schinthen	err_exit LINENO variable not working
934887Schinfi
944887SchinLINENO=save+10
954887SchinIFS=:
964887Schinx=a::b::c
974887Schinif	[[ $x != a::b::c ]]
9810898Sroland.mainz@nrubsig.orgthen	err_exit "word splitting on constants"
994887Schinfi
1004887Schinset -- $x
1014887Schinif	[[ $# != 5 ]]
1024887Schinthen	err_exit ":: doesn't separate null arguments "
1034887Schinfi
1044887Schinset x
1054887Schinif	x$1=0 2> /dev/null
1064887Schinthen	err_exit "x\$1=value treated as an assignment"
1074887Schinfi
1084887Schin# check for attributes across subshells
1094887Schintypeset -i x=3
1104887Schiny=1/0
1118462SApril.Chin@Sun.COMif	( typeset x=y ) 2> /dev/null
1128462SApril.Chin@Sun.COMthen	err_exit "attributes not passed to subshells"
1134887Schinfi
1144887Schinunset x
1154887Schinfunction x.set
1164887Schin{
1174887Schin	nameref foo=${.sh.name}.save
1184887Schin	foo=${.sh.value}
1194887Schin	.sh.value=$0
1204887Schin}
1214887Schinx=bar
1224887Schinif	[[ $x != x.set ]]
1234887Schinthen	err_exit 'x.set does not override assignment'
1244887Schinfi
1254887Schinx.get()
1264887Schin{
1274887Schin	nameref foo=${.sh.name}.save
1284887Schin	.sh.value=$foo
1294887Schin}
1304887Schin
1314887Schinif	[[ $x != bar ]]
1324887Schinthen	err_exit 'x.get does not work correctly'
1334887Schinfi
1344887Schintypeset +n foo
1354887Schinunset foo
1364887Schinfoo=bar
1374887Schin(
1384887Schin	unset foo
1394887Schin	set +u
1404887Schin	if	[[ $foo != '' ]]
1414887Schin	then	err_exit '$foo not null after unset in subsehll'
1424887Schin	fi
1434887Schin)
1444887Schinif	[[ $foo != bar ]]
1454887Schinthen	err_exit 'unset foo in subshell produces side effect '
1464887Schinfi
1474887Schinunset foo
1484887Schinif	[[ $( { : ${foo?hi there} ; } 2>&1) != *'hi there' ]]
1494887Schinthen	err_exit '${foo?hi there} with foo unset does not print hi there on 2'
1504887Schinfi
1514887Schinx=$0
1524887Schinset foobar
1534887Schinif	[[ ${@:0} != "$x foobar" ]]
1544887Schinthen	err_exit '${@:0} not expanding correctly'
1554887Schinfi
1564887Schinset --
1574887Schinif	[[ ${*:0:1} != "$0" ]]
1584887Schinthen	err_exit '${@:0} not expanding correctly'
1594887Schinfi
1604887SchinACCESS=0
1614887Schinfunction COUNT.set
1624887Schin{
1634887Schin        (( ACCESS++ ))
1644887Schin}
1654887SchinCOUNT=0
1664887Schin(( COUNT++ ))
1674887Schinif	(( COUNT != 1 || ACCESS!=2 ))
1684887Schinthen	err_exit " set discipline failure COUNT=$COUNT ACCESS=$ACCESS"
1694887Schinfi
1704887SchinLANG=C > /dev/null 2>&1
1714887Schinif	[[ $LANG != C ]]
1724887Schinthen	err_exit "C locale not working"
1734887Schinfi
1744887Schinunset RANDOM
1754887Schinunset -n foo
1764887Schinfoo=junk
1774887Schinfunction foo.get
1784887Schin{
17910898Sroland.mainz@nrubsig.org	.sh.value=stuff
1804887Schin	unset -f foo.get
1814887Schin}
1824887Schinif	[[ $foo != stuff ]]
1834887Schinthen	err_exit "foo.get discipline not working"
1844887Schinfi
1854887Schinif	[[ $foo != junk ]]
1864887Schinthen	err_exit "foo.get discipline not working after unset"
1874887Schinfi
1884887Schin# special variables
1894887Schinset -- 1 2 3 4 5 6 7 8 9 10
1904887Schinsleep 1000 &
1914887Schinif	[[ $(print -r -- ${#10}) != 2 ]]
1924887Schinthen	err_exit '${#10}, where ${10}=10 not working'
1934887Schinfi
1944887Schinfor i in @ '*' ! '#' - '?' '$'
1954887Schindo	false
1964887Schin	eval foo='$'$i bar='$'{$i}
1974887Schin	if	[[ ${foo} != "${bar}" ]]
1984887Schin	then	err_exit "\$$i not equal to \${$i}"
1994887Schin	fi
2004887Schin	command eval bar='$'{$i%?} 2> /dev/null || err_exit "\${$i%?} gives syntax error"
2014887Schin	if	[[ $i != [@*] && ${foo%?} != "$bar"  ]]
2024887Schin	then	err_exit "\${$i%?} not correct"
2034887Schin	fi
2044887Schin	command eval bar='$'{$i#?} 2> /dev/null || err_exit "\${$i#?} gives syntax error"
2054887Schin	if	[[ $i != [@*] && ${foo#?} != "$bar"  ]]
2064887Schin	then	err_exit "\${$i#?} not correct"
2074887Schin	fi
2084887Schin	command eval foo='$'{$i} bar='$'{#$i} || err_exit "\${#$i} gives synta
2094887Schinx error"
2104887Schin	if	[[ $i != @([@*]) && ${#foo} != "$bar" ]]
2114887Schin	then	err_exit "\${#$i} not correct"
2124887Schin	fi
2134887Schindone
2144887Schinkill $!
2154887Schinunset x
2164887SchinCDPATH=/
21710898Sroland.mainz@nrubsig.orgx=$(cd ${tmp#/})
21810898Sroland.mainz@nrubsig.orgif	[[ $x != $tmp ]]
2194887Schinthen	err_exit 'CDPATH does not display new directory'
2204887Schinfi
2214887SchinCDPATH=/:
22210898Sroland.mainz@nrubsig.orgx=$(cd ${tmp%/*}; cd ${tmp##*/})
2234887Schinif	[[ $x ]]
2244887Schinthen	err_exit 'CDPATH displays new directory when not used'
2254887Schinfi
22610898Sroland.mainz@nrubsig.orgx=$(cd ${tmp#/})
22710898Sroland.mainz@nrubsig.orgif	[[ $x != $tmp ]]
22810898Sroland.mainz@nrubsig.orgthen	err_exit "CDPATH ${tmp#/} does not display new directory"
2294887Schinfi
2304887SchinTMOUT=100
2314887Schin(TMOUT=20)
2324887Schinif	(( TMOUT !=100 ))
2334887Schinthen	err_exit 'setting TMOUT in subshell affects parent'
2344887Schinfi
2354887Schinunset y
2364887Schinfunction setdisc # var
2374887Schin{
2384887Schin        eval function $1.get'
2394887Schin        {
2404887Schin                .sh.value=good
2414887Schin        }
2424887Schin        '
2434887Schin}
2444887Schiny=bad
2454887Schinsetdisc y
2464887Schinif	[[ $y != good ]]
2474887Schinthen	err_exit 'setdisc function not working'
2484887Schinfi
2494887Schininteger x=$LINENO
2504887Schin: $'\
2514887Schin'
2524887Schinif	(( LINENO != x+3  ))
2534887Schinthen	err_exit '\<newline> gets linenumber count wrong'
2544887Schinfi
2554887Schinset --
2564887Schinset -- "${@-}"
2574887Schinif	(( $# !=1 ))
2584887Schinthen	err_exit	'"${@-}" not expanding to null string'
2594887Schinfi
2608462SApril.Chin@Sun.COMfor i in : % + / 3b '**' '***' '@@' '{' '[' '}' !!  '*a' '$foo'
2614887Schindo      (eval : \${"$i"} 2> /dev/null) && err_exit "\${$i} not an syntax error"
2624887Schindone
2634887Schinunset IFS
2644887Schin( IFS='  ' ; read -r a b c <<-!
2654887Schin	x  y z
2664887Schin	!
2674887Schin	if	[[ $b ]]
2684887Schin	then	err_exit 'IFS="  " not causing adjacent space to be null string'
2694887Schin	fi
2704887Schin)
2714887Schinread -r a b c <<-!
2724887Schinx  y z
2734887Schin!
2744887Schinif	[[ $b != y ]]
2754887Schinthen	err_exit 'IFS not restored after subshell'
2764887Schinfi
2774887Schin
2784887Schin# The next part generates 3428 IFS set/read tests.
2794887Schin
2804887Schinunset IFS x
2814887Schinfunction split
2824887Schin{
2834887Schin	i=$1 s=$2 r=$3
2844887Schin	IFS=': '
2854887Schin	set -- $i
2864887Schin	IFS=' '
2874887Schin	g="[$#]"
2884887Schin	while	:
2894887Schin	do	case $# in
2904887Schin		0)	break ;;
2914887Schin		esac
2924887Schin		g="$g($1)"
2934887Schin		shift
2944887Schin	done
2954887Schin	case "$g" in
2964887Schin	"$s")	;;
2974887Schin	*)	err_exit "IFS=': '; set -- '$i'; expected '$s' got '$g'" ;;
2984887Schin	esac
2994887Schin	print "$i" | IFS=": " read arg rem; g="($arg)($rem)"
3004887Schin	case "$g" in
3014887Schin	"$r")	;;
3024887Schin	*)	err_exit "IFS=': '; read '$i'; expected '$r' got '$g'" ;;
3034887Schin	esac
3044887Schin}
3054887Schinfor str in 	\
3064887Schin	'-'	\
3074887Schin	'a'	\
3084887Schin	'- -'	\
3094887Schin	'- a'	\
3104887Schin	'a -'	\
3114887Schin	'a b'	\
3124887Schin	'- - -'	\
3134887Schin	'- - a'	\
3144887Schin	'- a -'	\
3154887Schin	'- a b'	\
3164887Schin	'a - -'	\
3174887Schin	'a - b'	\
3184887Schin	'a b -'	\
3194887Schin	'a b c'
3204887Schindo
3214887Schin	IFS=' '
3224887Schin	set x $str
3234887Schin	shift
3244887Schin	case $# in
3254887Schin	0)	continue ;;
3264887Schin	esac
3274887Schin	f1=$1
3284887Schin	case $f1 in
3294887Schin	'-')	f1='' ;;
3304887Schin	esac
3314887Schin	shift
3324887Schin	case $# in
3334887Schin	0)	for d0 in '' ' '
3344887Schin		do
3354887Schin			for d1 in '' ' ' ':' ' :' ': ' ' : '
3364887Schin			do
3374887Schin				case $f1$d1 in
3384887Schin				'')	split "$d0$f1$d1" "[0]" "()()" ;;
3394887Schin				' ')	;;
3404887Schin				*)	split "$d0$f1$d1" "[1]($f1)" "($f1)()" ;;
3414887Schin				esac
3424887Schin			done
3434887Schin		done
3444887Schin		continue
3454887Schin		;;
3464887Schin	esac
3474887Schin	f2=$1
3484887Schin	case $f2 in
3494887Schin	'-')	f2='' ;;
3504887Schin	esac
3514887Schin	shift
3524887Schin	case $# in
3534887Schin	0)	for d0 in '' ' '
3544887Schin		do
3554887Schin			for d1 in ' ' ':' ' :' ': ' ' : '
3564887Schin			do
3574887Schin				case ' ' in
3584887Schin				$f1$d1|$d1$f2)	continue ;;
3594887Schin				esac
3604887Schin				for d2 in '' ' ' ':' ' :' ': ' ' : '
3614887Schin				do
3624887Schin					case $f2$d2 in
3634887Schin					'')	split "$d0$f1$d1$f2$d2" "[1]($f1)" "($f1)()" ;;
3644887Schin					' ')	;;
3654887Schin					*)	split "$d0$f1$d1$f2$d2" "[2]($f1)($f2)" "($f1)($f2)" ;;
3664887Schin					esac
3674887Schin				done
3684887Schin			done
3694887Schin		done
3704887Schin		continue
3714887Schin		;;
3724887Schin	esac
3734887Schin	f3=$1
3744887Schin	case $f3 in
3754887Schin	'-')	f3='' ;;
3764887Schin	esac
3774887Schin	shift
3784887Schin	case $# in
3794887Schin	0)	for d0 in '' ' '
3804887Schin		do
3814887Schin			for d1 in ':' ' :' ': ' ' : '
3824887Schin			do
3834887Schin				case ' ' in
3844887Schin				$f1$d1|$d1$f2)	continue ;;
3854887Schin				esac
3864887Schin				for d2 in ' ' ':' ' :' ': ' ' : '
3874887Schin				do
3884887Schin					case $f2$d2 in
3894887Schin					' ')	continue ;;
3904887Schin					esac
3914887Schin					case ' ' in
3924887Schin					$f2$d2|$d2$f3)	continue ;;
3934887Schin					esac
3944887Schin					for d3 in '' ' ' ':' ' :' ': ' ' : '
3954887Schin					do
3964887Schin						case $f3$d3 in
3974887Schin						'')	split "$d0$f1$d1$f2$d2$f3$d3" "[2]($f1)($f2)" "($f1)($f2)" ;;
3984887Schin						' ')	;;
3994887Schin						*)	x=$f2$d2$f3$d3
4004887Schin							x=${x#' '}
4014887Schin							x=${x%' '}
4024887Schin							split "$d0$f1$d1$f2$d2$f3$d3" "[3]($f1)($f2)($f3)" "($f1)($x)"
4034887Schin							;;
4044887Schin						esac
4054887Schin					done
4064887Schin				done
4074887Schin			done
4084887Schin		done
4094887Schin		continue
4104887Schin		;;
4114887Schin	esac
4124887Schindone
4134887Schinunset IFS
4144887Schin
4154887Schinif	[[ $( (print ${12345:?}) 2>&1) != *12345* ]]
41610898Sroland.mainz@nrubsig.orgthen	err_exit 'incorrect error message with ${12345?}'
4174887Schinfi
4184887Schinunset foobar
4194887Schinif	[[ $( (print ${foobar:?}) 2>&1) != *foobar* ]]
42010898Sroland.mainz@nrubsig.orgthen	err_exit 'incorrect error message with ${foobar?}'
4214887Schinfi
4224887Schinunset bar
4234887Schinif	[[ $( (print ${bar:?bam}) 2>&1) != *bar*bam* ]]
42410898Sroland.mainz@nrubsig.orgthen	err_exit 'incorrect error message with ${foobar?}'
4254887Schinfi
4264887Schin{ $SHELL -c '
4274887Schinfunction foo
4284887Schin{
4294887Schin	typeset SECONDS=0
4304887Schin	sleep 1.5
4314887Schin	print $SECONDS
43210898Sroland.mainz@nrubsig.org
4334887Schin}
4344887Schinx=$(foo)
43510898Sroland.mainz@nrubsig.org(( x >1 && x < 2 ))
4364887Schin'
4374887Schin} 2> /dev/null   || err_exit 'SECONDS not working in function'
43810898Sroland.mainz@nrubsig.orgcat > $tmp/script <<-\!
4394887Schin	posixfun()
4404887Schin	{
4414887Schin		unset x
4424887Schin	 	nameref x=$1
4434887Schin	 	print  -r -- "$x"
4444887Schin	}
4454887Schin	function fun
4464887Schin	{
4474887Schin	 	nameref x=$1
4484887Schin	 	print  -r -- "$x"
4494887Schin	}
4504887Schin	if	[[ $1 ]]
4514887Schin	then	file=${.sh.file}
4524887Schin	else	print -r -- "${.sh.file}"
4534887Schin	fi
4544887Schin!
45510898Sroland.mainz@nrubsig.orgchmod +x $tmp/script
45610898Sroland.mainz@nrubsig.org. $tmp/script  1
45710898Sroland.mainz@nrubsig.org[[ $file == $tmp/script ]] || err_exit ".sh.file not working for dot scripts"
45810898Sroland.mainz@nrubsig.org[[ $($SHELL $tmp/script) == $tmp/script ]] || err_exit ".sh.file not working for scripts"
45910898Sroland.mainz@nrubsig.org[[ $(posixfun .sh.file) == $tmp/script ]] || err_exit ".sh.file not working for posix functions"
46010898Sroland.mainz@nrubsig.org[[ $(fun .sh.file) == $tmp/script ]] || err_exit ".sh.file not working for functions"
4614887Schin[[ $(posixfun .sh.fun) == posixfun ]] || err_exit ".sh.fun not working for posix functions"
4624887Schin[[ $(fun .sh.fun) == fun ]] || err_exit ".sh.fun not working for functions"
4634887Schin[[ $(posixfun .sh.subshell) == 1 ]] || err_exit ".sh.subshell not working for posix functions"
4644887Schin[[ $(fun .sh.subshell) == 1 ]] || err_exit ".sh.subshell not working for functions"
4654887Schin(
4664887Schin    [[ $(posixfun .sh.subshell) == 2 ]]  || err_exit ".sh.subshell not working for posix functions in subshells"
4674887Schin    [[ $(fun .sh.subshell) == 2 ]]  || err_exit ".sh.subshell not working for functions in subshells"
4684887Schin    (( .sh.subshell == 1 )) || err_exit ".sh.subshell not working in a subshell"
4694887Schin)
4704887SchinTIMEFORMAT='this is a test'
4714887Schin[[ $({ { time :;} 2>&1;}) == "$TIMEFORMAT" ]] || err_exit 'TIMEFORMAT not working'
4724887Schin: ${.sh.version}
4734887Schin[[ $(alias integer) == *.sh.* ]] && err_exit '.sh. prefixed to alias name'
4744887Schin: ${.sh.version}
4754887Schin[[ $(whence rm) == *.sh.* ]] && err_exit '.sh. prefixed to tracked alias name'
4764887Schin: ${.sh.version}
4778462SApril.Chin@Sun.COM[[ $(cd /bin;env | grep PWD=) == *.sh.* ]] && err_exit '.sh. prefixed to PWD'
4784887Schin# unset discipline bug fix
4794887Schindave=dave
4804887Schinfunction dave.unset
4814887Schin{
4824887Schin    unset dave
4834887Schin}
4844887Schinunset dave
4854887Schin[[ $(typeset +f) == *dave.* ]] && err_exit 'unset discipline not removed'
4868462SApril.Chin@Sun.COM
48710898Sroland.mainz@nrubsig.orgprint 'print ${VAR}' > $tmp/script
4888462SApril.Chin@Sun.COMunset VAR
48910898Sroland.mainz@nrubsig.orgVAR=new $tmp/script > $tmp/out
49010898Sroland.mainz@nrubsig.orggot=$(<$tmp/out)
4918462SApril.Chin@Sun.COM[[ $got == new ]] || err_exit "previously unset environment variable not passed to script, expected 'new', got '$got'"
4928462SApril.Chin@Sun.COM[[ ! $VAR ]] || err_exit "previously unset environment variable set after script, expected '', got '$VAR'"
4938462SApril.Chin@Sun.COMunset VAR
4948462SApril.Chin@Sun.COMVAR=old
49510898Sroland.mainz@nrubsig.orgVAR=new $tmp/script > $tmp/out
49610898Sroland.mainz@nrubsig.orggot=$(<$tmp/out)
4978462SApril.Chin@Sun.COM[[ $got == new ]] || err_exit "environment variable covering local variable not passed to script, expected 'new', got '$got'"
4988462SApril.Chin@Sun.COM[[ $VAR == old ]] || err_exit "previously set local variable changed after script, expected 'old', got '$VAR'"
4998462SApril.Chin@Sun.COMunset VAR
5008462SApril.Chin@Sun.COMexport VAR=old
50110898Sroland.mainz@nrubsig.orgVAR=new $tmp/script > $tmp/out
50210898Sroland.mainz@nrubsig.orggot=$(<$tmp/out)
5038462SApril.Chin@Sun.COM[[ $got == new ]] || err_exit "environment variable covering environment variable not passed to script, expected 'new', got '$got'"
5048462SApril.Chin@Sun.COM[[ $VAR == old ]] || err_exit "previously set environment variable changed after script, expected 'old', got '$VAR'"
5058462SApril.Chin@Sun.COM
5064887Schin(
5074887Schin	unset dave
5084887Schin	function  dave.append
5094887Schin	{
5104887Schin		.sh.value+=$dave
5114887Schin		dave=
5124887Schin	}
5134887Schin	dave=foo; dave+=bar
5144887Schin	[[ $dave == barfoo ]] || exit 2
51510898Sroland.mainz@nrubsig.org) 2> /dev/null
5164887Schincase $? in
5174887Schin0)	 ;;
5184887Schin1)	 err_exit 'append discipline not implemented';;
5194887Schin*)	 err_exit 'append discipline not working';;
5204887Schinesac
5214887Schin.sh.foobar=hello
5224887Schin{
5234887Schin	function .sh.foobar.get
5244887Schin	{
5254887Schin		.sh.value=world
52610898Sroland.mainz@nrubsig.org	}
52710898Sroland.mainz@nrubsig.org} 2> /dev/null || err_exit "cannot add get discipline to .sh.foobar"
5284887Schin[[ ${.sh.foobar} == world ]]  || err_exit 'get discipline for .sh.foobar not working'
5294887Schinx='a|b'
5304887SchinIFS='|'
5314887Schinset -- $x
5324887Schin[[ $2 == b ]] || err_exit '$2 should be b after set'
5334887Schinexec 3>&2 2> /dev/null
5344887Schinset -x
5354887Schin( IFS= ) 2> /dev/null
5364887Schinset +x
5374887Schinexec 2>&3-
5384887Schinset -- $x
5394887Schin[[ $2 == b ]] || err_exit '$2 should be b after subshell'
5404887Schin: & pid=$!
5414887Schin( : & )
5424887Schin[[ $pid == $! ]] || err_exit '$! value not preserved across subshells'
5434887Schinunset foo
5444887Schintypeset -A foo
5454887Schinfunction foo.set
5464887Schin{
5474887Schin	case ${.sh.subscript} in
5484887Schin	bar)	if	((.sh.value > 1 ))
5494887Schin	        then	.sh.value=5
5504887Schin			foo[barrier_hit]=yes
5514887Schin		fi
5524887Schin		;;
5534887Schin	barrier_hit)
5544887Schin		if	[[ ${.sh.value} = yes ]]
5554887Schin		then	foo[barrier_not_hit]=no
5564887Schin		else	foo[barrier_not_hit]=yes
5574887Schin		fi
5584887Schin		;;
5594887Schin	esac
5604887Schin}
56110898Sroland.mainz@nrubsig.orgfoo[barrier_hit]=no
5624887Schinfoo[bar]=1
5634887Schin(( foo[bar] == 1 )) || err_exit 'foo[bar] should be 1'
5644887Schin[[ ${foo[barrier_hit]} == no ]] || err_exit 'foo[barrier_hit] should be no'
5654887Schin[[ ${foo[barrier_not_hit]} == yes ]] || err_exit 'foo[barrier_not_hit] should be yes'
56610898Sroland.mainz@nrubsig.orgfoo[barrier_hit]=no
5674887Schinfoo[bar]=2
5684887Schin(( foo[bar] == 5 )) || err_exit 'foo[bar] should be 5'
5694887Schin[[ ${foo[barrier_hit]} == yes ]] || err_exit 'foo[barrier_hit] should be yes'
5704887Schin[[ ${foo[barrier_not_hit]} == no ]] || err_exit 'foo[barrier_not_hit] should be no'
5714887Schinunset x
5724887Schintypeset -i x
5734887Schinfunction x.set
5744887Schin{
5754887Schin	typeset sub=${.sh.subscript}
5764887Schin	(( sub > 0 )) && (( x[sub-1]= x[sub-1] + .sh.value ))
5774887Schin}
5784887Schinx[0]=0 x[1]=1 x[2]=2 x[3]=3
5794887Schin[[ ${x[@]} == '12 8 5 3' ]] || err_exit 'set discipline for indexed array not working correctly'
58010898Sroland.mainz@nrubsig.orgfloat seconds
5814887Schin((SECONDS=3*4))
58210898Sroland.mainz@nrubsig.orgseconds=SECONDS
58310898Sroland.mainz@nrubsig.org(( seconds < 12 || seconds > 12.1 )) &&  err_exit "SECONDS is $seconds and should be close to 12"
5848462SApril.Chin@Sun.COMunset a
5858462SApril.Chin@Sun.COMfunction a.set
5868462SApril.Chin@Sun.COM{
5878462SApril.Chin@Sun.COM	print -r -- "${.sh.name}=${.sh.value}"
5888462SApril.Chin@Sun.COM}
5898462SApril.Chin@Sun.COM[[ $(a=1) == a=1 ]] || err_exit 'set discipline not working in subshell assignment'
5908462SApril.Chin@Sun.COM[[ $(a=1 :) == a=1 ]] || err_exit 'set discipline not working in subshell command'
5918462SApril.Chin@Sun.COM
5928462SApril.Chin@Sun.COM[[ ${.sh.subshell} == 0 ]] || err_exit '${.sh.subshell} should be 0'
5938462SApril.Chin@Sun.COM(
5948462SApril.Chin@Sun.COM	[[ ${.sh.subshell} == 1 ]] || err_exit '${.sh.subshell} should be 1'
5958462SApril.Chin@Sun.COM	(
5968462SApril.Chin@Sun.COM		[[ ${.sh.subshell} == 2 ]] || err_exit '${.sh.subshell} should be 2'
5978462SApril.Chin@Sun.COM	)
5988462SApril.Chin@Sun.COM)
5998462SApril.Chin@Sun.COM
6008462SApril.Chin@Sun.COMset -- {1..32768}
6018462SApril.Chin@Sun.COM(( $# == 32768 )) || err_exit "\$# failed -- expected 32768, got $#"
6028462SApril.Chin@Sun.COMset --
6038462SApril.Chin@Sun.COM
6048462SApril.Chin@Sun.COMunset r v x
6058462SApril.Chin@Sun.COMpath=$PATH
6068462SApril.Chin@Sun.COMx=foo
6078462SApril.Chin@Sun.COMfor v in EDITOR VISUAL OPTIND CDPATH FPATH PATH ENV LINENO RANDOM SECONDS _
6088462SApril.Chin@Sun.COMdo	nameref r=$v
6098462SApril.Chin@Sun.COM	unset $v
6108462SApril.Chin@Sun.COM	if	( $SHELL -c "unset $v; : \$$v" ) 2>/dev/null
6118462SApril.Chin@Sun.COM	then	[[ $r ]] && err_exit "unset $v failed -- expected '', got '$r'"
6128462SApril.Chin@Sun.COM		r=$x
6138462SApril.Chin@Sun.COM		[[ $r == $x ]] || err_exit "$v=$x failed -- expected '$x', got '$r'"
6148462SApril.Chin@Sun.COM	else	err_exit "unset $v; : \$$v failed"
6158462SApril.Chin@Sun.COM	fi
6168462SApril.Chin@Sun.COMdone
61710898Sroland.mainz@nrubsig.org
61810898Sroland.mainz@nrubsig.orgx=x
6198462SApril.Chin@Sun.COMfor v in LC_ALL LC_CTYPE LC_MESSAGES LC_COLLATE LC_NUMERIC
6208462SApril.Chin@Sun.COMdo	nameref r=$v
6218462SApril.Chin@Sun.COM	unset $v
6228462SApril.Chin@Sun.COM	[[ $r ]] && err_exit "unset $v failed -- expected '', got '$r'"
6238462SApril.Chin@Sun.COM	d=$($SHELL -c "$v=$x" 2>&1)
6248462SApril.Chin@Sun.COM	[[ $d ]] || err_exit "$v=$x failed -- expected locale diagnostic"
62510898Sroland.mainz@nrubsig.org	{ g=$( r=$x; print -- $r ); } 2>/dev/null
62610898Sroland.mainz@nrubsig.org	[[ $g == '' ]] || err_exit "$v=$x failed -- expected '', got '$g'"
62710898Sroland.mainz@nrubsig.org	{ g=$( r=C; r=$x; print -- $r ); } 2>/dev/null
62810898Sroland.mainz@nrubsig.org	[[ $g == 'C' ]] || err_exit "$v=C; $v=$x failed -- expected 'C', got '$g'"
6298462SApril.Chin@Sun.COMdone
6308462SApril.Chin@Sun.COMPATH=$path
6318462SApril.Chin@Sun.COM
63210898Sroland.mainz@nrubsig.orgcd $tmp
63310898Sroland.mainz@nrubsig.org
63410898Sroland.mainz@nrubsig.orgprint print -n zzz > zzz
63510898Sroland.mainz@nrubsig.orgchmod +x zzz
63610898Sroland.mainz@nrubsig.orgexp='aaazzz'
63710898Sroland.mainz@nrubsig.orggot=$($SHELL -c 'unset SHLVL; print -n aaa; ./zzz' 2>&1) >/dev/null 2>&1
63810898Sroland.mainz@nrubsig.org[[ $got == "$exp" ]] || err_exit "unset SHLVL causes script failure -- expected '$exp', got '$got'"
63910898Sroland.mainz@nrubsig.org
64010898Sroland.mainz@nrubsig.orgmkdir glean
64110898Sroland.mainz@nrubsig.orgfor cmd in date ok
64210898Sroland.mainz@nrubsig.orgdo	exp="$cmd ok"
64310898Sroland.mainz@nrubsig.org	rm -f $cmd
64410898Sroland.mainz@nrubsig.org	print print $exp > glean/$cmd
64510898Sroland.mainz@nrubsig.org	chmod +x glean/$cmd
64610898Sroland.mainz@nrubsig.org	got=$(CDPATH=:.. $SHELL -c "PATH=:/bin:/usr/bin; date > /dev/null; cd glean && ./$cmd" 2>&1)
64710898Sroland.mainz@nrubsig.org	[[ $got == "$exp" ]] || err_exit "cd with CDPATH after PATH change failed -- expected '$exp', got '$got'"
64810898Sroland.mainz@nrubsig.orgdone
64910898Sroland.mainz@nrubsig.org
650*12068SRoger.Faulkner@Oracle.COMv=LC_CTYPE
651*12068SRoger.Faulkner@Oracle.COMunset $v
652*12068SRoger.Faulkner@Oracle.COM[[ -v $v ]] && err_exit "unset $v; [[ -v $v ]] failed"
653*12068SRoger.Faulkner@Oracle.COMeval $v=C
654*12068SRoger.Faulkner@Oracle.COM[[ -v $v ]] || err_exit "$v=C; [[ -v $v ]] failed"
655*12068SRoger.Faulkner@Oracle.COM
656*12068SRoger.Faulkner@Oracle.COMcmd='set --nounset; unset foo; : ${!foo*}'
657*12068SRoger.Faulkner@Oracle.COM$SHELL -c "$cmd" 2>/dev/null || err_exit "'$cmd' exit status $?, expected 0"
658*12068SRoger.Faulkner@Oracle.COM
6594887Schinexit $((Errors))
660