14887Schin########################################################################
24887Schin#                                                                      #
34887Schin#               This software is part of the ast package               #
4*8462SApril.Chin@Sun.COM#          Copyright (c) 1982-2008 AT&T Intellectual Property          #
54887Schin#                      and is licensed under the                       #
64887Schin#                  Common Public License, Version 1.0                  #
7*8462SApril.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
304887Schinfunction checkref
314887Schin{
324887Schin	nameref foo=$1 bar=$2
334887Schin	if	[[ $foo !=  $bar ]]
344887Schin	then	err_exit "foo=$foo != bar=$bar"
354887Schin	fi
364887Schin	foo=hello
374887Schin	if	[[ $foo !=  $bar ]]
384887Schin	then	err_exit "foo=$foo != bar=$bar"
394887Schin	fi
404887Schin	foo.child=child
414887Schin	if	[[ ${foo.child} !=  ${bar.child} ]]
424887Schin	then	err_exit "foo.child=${foo.child} != bar=${bar.child}"
434887Schin	fi
444887Schin}
454887Schin
464887Schinname=first
474887Schincheckref name name
484887Schinname.child=second
494887Schincheckref name name
504887Schin.foo=top
514887Schin.foo.bar=next
524887Schincheckref .foo.bar .foo.bar
534887Schinif	[[ ${.foo.bar} !=  hello ]]
544887Schinthen	err_exit ".foo.bar=${.foo.bar} != hello"
554887Schinfi
564887Schinif	[[ ${.foo.bar.child} !=  child ]]
574887Schinthen	err_exit ".foo.bar.child=${.foo.bar.child} != child"
584887Schinfi
594887Schinfunction func1
604887Schin{
614887Schin        nameref color=$1
624887Schin        func2 color
634887Schin}
644887Schin
654887Schinfunction func2
664887Schin{
674887Schin        nameref color=$1
684887Schin        set -s -- ${!color[@]}
694887Schin	print -r -- "$@"
704887Schin}
714887Schin
724887Schintypeset -A color
734887Schincolor[apple]=red
744887Schincolor[grape]=purple
754887Schincolor[banana]=yellow
764887Schinif	[[ $(func1 color) != 'apple banana grape' ]]
774887Schinthen	err_exit "nameref or nameref not working"
784887Schinfi
794887Schinnameref x=.foo.bar
804887Schinif	[[ ${!x} != .foo.bar ]]
814887Schinthen	err_exit "${!x} not working"
824887Schinfi
834887Schintypeset +n x $(typeset +n)
844887Schinunset x
854887Schinnameref x=.foo.bar
864887Schinfunction x.set
874887Schin{
884887Schin	[[ ${.sh.value} ]] && print hello
894887Schin}
904887Schinif	[[ $(.foo.bar.set) != $(x.set) ]]
914887Schinthen	err_exit "function references  not working"
924887Schinfi
934887Schinif	[[ $(typeset +n) != x ]]
944887Schinthen	err_exit "typeset +n doesn't list names of reference variables"
954887Schinfi
964887Schinif	[[ $(typeset -n) != x=.foo.bar ]]
974887Schinthen	err_exit "typeset +n doesn't list values of reference variables"
984887Schinfi
994887Schinfile=/tmp/shtest$$
1004887Schintypeset +n foo bar 2> /dev/null
1014887Schinunset foo bar
1024887Schinexport bar=foo
1034887Schinnameref foo=bar
1044887Schinif	[[ $foo != foo ]]
1054887Schinthen	err_exit "value of nameref foo !=  $foo"
1064887Schinfi
1074887Schintrap "rm -f $file" EXIT INT
1084887Schincat > $file <<\!
1094887Schinprint -r -- $foo
1104887Schin!
1114887Schinchmod +x "$file"
1124887Schiny=$( $file)
1134887Schinif	[[ $y != '' ]]
1144887Schinthen	err_exit "reference variable not cleared"
1154887Schinfi
1164887Schin{
1174887Schin	command nameref xx=yy
1184887Schin	command nameref yy=xx
1194887Schin} 2> /dev/null && err_exit "self reference not detected"
1204887Schintypeset +n foo bar
1214887Schinunset foo bar
1224887Schinset foo
1234887Schinnameref bar=$1
1244887Schinfoo=hello
1254887Schinif	[[ $bar !=  hello ]]
1264887Schinthen	err_exit 'nameref of positional paramters outside of function not working'
1274887Schinfi
1284887Schinunset foo bar
1294887Schinbar=123
1304887Schinfunction foobar
1314887Schin{
1324887Schin	typeset -n foo=bar
1334887Schin	typeset -n foo=bar
1344887Schin}
1354887Schinfoobar 2> /dev/null || err_exit 'nameref not unsetting previous reference'
1364887Schin(
1374887Schin	nameref short=verylong
1384887Schin	short=( A=a B=b )
1394887Schin	if	[[ ${verylong.A} != a ]]
1404887Schin	then	err_exit 'nameref short to longname compound assignment error'
1414887Schin	fi
1424887Schin) 2> /dev/null|| err_exit 'nameref short to longname compound assignment error'
1434887Schinunset x
1444887Schinif	[[	$(var1=1 var2=2
1454887Schin		for i in var1 var2
1464887Schin		do	nameref x=$i
1474887Schin			print $x
1484887Schin		done) != $'1\n2' ]]
1494887Schinthen	err_exit 'for loop nameref optimization error'
1504887Schinfi
1514887Schinif	[[	$(typeset -A var1 var2
1524887Schin		var1[sub1]=1 var2[sub2]=1
1534887Schin		for i in var1 var2
1544887Schin		do
1554887Schin		        typeset -n array=$i
1564887Schin		        print ${!array[*]}
1574887Schin		done) != $'sub1\nsub2' ]]
1584887Schinthen 	err_exit 'for loop nameref optimization test2 error'
1594887Schinfi
1604887Schin
1614887Schinunset -n x foo bar
1624887Schinif	[[ $(nameref x=foo;for x in foo bar;do print ${!x};done) != $'foo\nbar' ]]
1634887Schinthen	err_exit 'for loop optimization with namerefs not working'
1644887Schinfi
1654887Schinif	[[ $(
1664887Schin	p=(x=(r=3) y=(r=4))
1674887Schin	for i in x y
1684887Schin	do	nameref x=p.$i
1694887Schin		print ${x.r}
1704887Schin	done
1714887Schin) != $'3\n4' ]]
1724887Schinthen	err_exit 'nameref optimization error'
1734887Schinfi
1744887Schin[[ $(
1754887Schinunset x y var
1764887Schinvar=(foo=bar)
1774887Schinfor i in y var
1784887Schindo	typeset -n x=$i
1794887Schin	if	[[ ${!x.@} ]]
1804887Schin	then	print ok
1814887Schin	fi
1824887Schin	typeset +n x
1834887Schindone) != ok ]] && err_exit 'invalid for loop optimization of name references'
1844887Schinfunction setval # name value
1854887Schin{
1864887Schin        nameref arg=$1
1874887Schin	nameref var=arg.bar
1884887Schin	var=$2
1894887Schin}
1904887Schinfoo=( integer bar=0)
1914887Schinsetval foo 5
1924887Schin(( foo.bar == 5)) || err_exit 'nested nameref not working'
1934887Schinfunction selfref
1944887Schin{
1954887Schin        typeset -n ps=$1
1964887Schin        print -r -- "${ps}"
1974887Schin}
1984887Schinps=(a=1 b=2)
1994887Schin[[ $(selfref ps) == *a=1* ]] ||  err_exit 'local nameref cannot reference global variable of the same name'
2004887Schinfunction subref
2014887Schin{
2024887Schin	typeset -n foo=$1
2034887Schin	print -r -- ${foo.a}
2044887Schin}
2054887Schin[[ $(subref ps) == 1 ]] ||  err_exit 'local nameref cannot reference global variable child'
2064887Schin
2074887Schinfunction local
2084887Schin{
2094887Schin	typeset ps=(typeset -i a=3 b=4)
2104887Schin	[[ $(subref ps) == 3 ]] ||  err_exit 'local nameref cannot reference caller compound variable'
2114887Schin}
2124887Schinlocal
2134887Schinunset -f local
2144887Schinfunction local
2154887Schin{
2164887Schin	qs=(integer  a=3; integer b=4)
2174887Schin}
2184887Schinlocal 2> /dev/null || err_exit 'function local has non-zero exit status'
2194887Schin[[ ${qs.a} == 3 ]] || err_exit 'function cannot set compound global variable'
2204887Schinunset fun i
2214887Schinfoo=(x=hi)
2224887Schinfunction fun
2234887Schin{
2244887Schin        nameref i=$1
2254887Schin        print -r -- "${i.x}"
2264887Schin}
2274887Schini=foo
2284887Schin[[ $(fun $i) == hi ]] || err_exit 'nameref for compound variable with in function name of caller fails'
229*8462SApril.Chin@Sun.COMunset -n foo bar
230*8462SApril.Chin@Sun.COMtypeset -A foo
231*8462SApril.Chin@Sun.COMfoo[x.y]=(x=3 y=4)
232*8462SApril.Chin@Sun.COMnameref bar=foo[x.y]
233*8462SApril.Chin@Sun.COM[[ ${bar.x} == 3 ]] || err_exit 'nameref to subscript containing . fails'
234*8462SApril.Chin@Sun.COM[[ ${!bar} == 'foo[x.y]' ]] || err_exit '${!var} not correct for nameref to an array instance'
235*8462SApril.Chin@Sun.COMtypeset +n bar
236*8462SApril.Chin@Sun.COMnameref bar=foo
237*8462SApril.Chin@Sun.COM[[ ${!bar} == foo ]] || err_exit '${!var} not correct for nameref to array variable'
238*8462SApril.Chin@Sun.COM$SHELL -c 'function bar { nameref x=foo[++];};typeset -A foo;bar' 2> /dev/null ||err_exit 'nameref of associative array tries to evaluate subscript'
239*8462SApril.Chin@Sun.COMi=$($SHELL -c 'nameref foo=bar; bar[2]=(x=3 y=4); nameref x=foo[2].y;print -r -- $x' 2> /dev/null)
240*8462SApril.Chin@Sun.COM[[ $i == 4 ]] || err_exit 'creating reference from subscripted variable whose name is a reference failed'
241*8462SApril.Chin@Sun.COM[[ $($SHELL 2> /dev/null <<- '+++EOF'
242*8462SApril.Chin@Sun.COM	function bar
243*8462SApril.Chin@Sun.COM	{
244*8462SApril.Chin@Sun.COM	 	nameref x=$1
245*8462SApril.Chin@Sun.COM	 	print -r -- "$x"
246*8462SApril.Chin@Sun.COM	}
247*8462SApril.Chin@Sun.COM	function foo
248*8462SApril.Chin@Sun.COM	{
249*8462SApril.Chin@Sun.COM	 	typeset var=( foo=hello)
250*8462SApril.Chin@Sun.COM	 	bar var
251*8462SApril.Chin@Sun.COM	}
252*8462SApril.Chin@Sun.COM	foo
253*8462SApril.Chin@Sun.COM+++EOF
254*8462SApril.Chin@Sun.COM) ==  *foo=hello* ]] || err_exit 'unable to display compound variable from name reference of local variable'
255*8462SApril.Chin@Sun.COM#set -x
256*8462SApril.Chin@Sun.COMfor c in '=' '[' ']' '\' "'" '"' '<' '=' '('
257*8462SApril.Chin@Sun.COMdo	[[ $($SHELL 2> /dev/null <<- ++EOF++
258*8462SApril.Chin@Sun.COM	x;i=\\$c;typeset -A a; a[\$i]=foo;typeset -n x=a[\$i]; print "\$x"
259*8462SApril.Chin@Sun.COM	++EOF++
260*8462SApril.Chin@Sun.COM) != foo ]] && err_exit 'nameref x=[$c] '"not working for c=$c"
261*8462SApril.Chin@Sun.COMdone
262*8462SApril.Chin@Sun.COMunset -n foo x
263*8462SApril.Chin@Sun.COMunset foo x
264*8462SApril.Chin@Sun.COMtypeset -A foo
265*8462SApril.Chin@Sun.COMnameref x=foo[xyz]
266*8462SApril.Chin@Sun.COMfoo[xyz]=ok
267*8462SApril.Chin@Sun.COM[[ $x == ok ]] || err_exit 'nameref to unset subscript not working'
268*8462SApril.Chin@Sun.COMfunction function2
269*8462SApril.Chin@Sun.COM{
270*8462SApril.Chin@Sun.COM	nameref v=$1
271*8462SApril.Chin@Sun.COM	v.x=19 v.y=20
272*8462SApril.Chin@Sun.COM}
273*8462SApril.Chin@Sun.COMfunction function1
274*8462SApril.Chin@Sun.COM{
275*8462SApril.Chin@Sun.COM	typeset compound_var=()
276*8462SApril.Chin@Sun.COM	function2 compound_var
277*8462SApril.Chin@Sun.COM	printf "x=%d, y=%d\n" compound_var.x compound_var.y
278*8462SApril.Chin@Sun.COM}
279*8462SApril.Chin@Sun.COMx="$(function1)"
280*8462SApril.Chin@Sun.COM[[ "$x" != 'x=19, y=20' ]] && err_exit "expected 'x=19, y=20', got '${x}'"
281*8462SApril.Chin@Sun.COMtypeset +n bar
282*8462SApril.Chin@Sun.COMunset foo bar
283*8462SApril.Chin@Sun.COM[[ $(function a
284*8462SApril.Chin@Sun.COM{
285*8462SApril.Chin@Sun.COM	for i in  foo bar
286*8462SApril.Chin@Sun.COM	do	typeset -n v=$i
287*8462SApril.Chin@Sun.COM		print $v
288*8462SApril.Chin@Sun.COM	done | cat
289*8462SApril.Chin@Sun.COM}
290*8462SApril.Chin@Sun.COMfoo=1 bar=2;a) == $'1\n2' ]] 2> /dev/null || err_exit 'nameref in pipeline broken'
291*8462SApril.Chin@Sun.COMfunction a
292*8462SApril.Chin@Sun.COM{
293*8462SApril.Chin@Sun.COM	typeset -n v=vars.data._1
294*8462SApril.Chin@Sun.COM	print "${v.a} ${v.b}"
295*8462SApril.Chin@Sun.COM}
296*8462SApril.Chin@Sun.COMvars=(data=())
297*8462SApril.Chin@Sun.COMvars.data._1.a=a.1
298*8462SApril.Chin@Sun.COMvars.data._1.b=b.1
299*8462SApril.Chin@Sun.COM[[ $(a) == 'a.1 b.1' ]] || err_exit 'nameref choosing wrong scope -- '
3004887Schinexit $((Errors))
301