xref: /onnv-gate/usr/src/lib/libshell/common/tests/nameref.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
3010898Sroland.mainz@nrubsig.org
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
344887Schinfunction checkref
354887Schin{
364887Schin	nameref foo=$1 bar=$2
374887Schin	if	[[ $foo !=  $bar ]]
384887Schin	then	err_exit "foo=$foo != bar=$bar"
394887Schin	fi
404887Schin	foo=hello
414887Schin	if	[[ $foo !=  $bar ]]
424887Schin	then	err_exit "foo=$foo != bar=$bar"
434887Schin	fi
444887Schin	foo.child=child
454887Schin	if	[[ ${foo.child} !=  ${bar.child} ]]
464887Schin	then	err_exit "foo.child=${foo.child} != bar=${bar.child}"
474887Schin	fi
484887Schin}
494887Schin
504887Schinname=first
514887Schincheckref name name
524887Schinname.child=second
534887Schincheckref name name
544887Schin.foo=top
554887Schin.foo.bar=next
564887Schincheckref .foo.bar .foo.bar
574887Schinif	[[ ${.foo.bar} !=  hello ]]
584887Schinthen	err_exit ".foo.bar=${.foo.bar} != hello"
594887Schinfi
604887Schinif	[[ ${.foo.bar.child} !=  child ]]
614887Schinthen	err_exit ".foo.bar.child=${.foo.bar.child} != child"
624887Schinfi
634887Schinfunction func1
644887Schin{
654887Schin        nameref color=$1
664887Schin        func2 color
674887Schin}
684887Schin
694887Schinfunction func2
704887Schin{
714887Schin        nameref color=$1
724887Schin        set -s -- ${!color[@]}
734887Schin	print -r -- "$@"
744887Schin}
754887Schin
764887Schintypeset -A color
774887Schincolor[apple]=red
784887Schincolor[grape]=purple
794887Schincolor[banana]=yellow
804887Schinif	[[ $(func1 color) != 'apple banana grape' ]]
814887Schinthen	err_exit "nameref or nameref not working"
824887Schinfi
834887Schinnameref x=.foo.bar
844887Schinif	[[ ${!x} != .foo.bar ]]
854887Schinthen	err_exit "${!x} not working"
864887Schinfi
8710898Sroland.mainz@nrubsig.orgtypeset +n x $(typeset +n)
884887Schinunset x
894887Schinnameref x=.foo.bar
904887Schinfunction x.set
914887Schin{
924887Schin	[[ ${.sh.value} ]] && print hello
934887Schin}
944887Schinif	[[ $(.foo.bar.set) != $(x.set) ]]
954887Schinthen	err_exit "function references  not working"
964887Schinfi
974887Schinif	[[ $(typeset +n) != x ]]
984887Schinthen	err_exit "typeset +n doesn't list names of reference variables"
994887Schinfi
1004887Schinif	[[ $(typeset -n) != x=.foo.bar ]]
1014887Schinthen	err_exit "typeset +n doesn't list values of reference variables"
1024887Schinfi
10310898Sroland.mainz@nrubsig.orgfile=$tmp/test
1044887Schintypeset +n foo bar 2> /dev/null
1054887Schinunset foo bar
1064887Schinexport bar=foo
1074887Schinnameref foo=bar
1084887Schinif	[[ $foo != foo ]]
1094887Schinthen	err_exit "value of nameref foo !=  $foo"
1104887Schinfi
1114887Schincat > $file <<\!
1124887Schinprint -r -- $foo
1134887Schin!
1144887Schinchmod +x "$file"
1154887Schiny=$( $file)
1164887Schinif	[[ $y != '' ]]
1174887Schinthen	err_exit "reference variable not cleared"
1184887Schinfi
11910898Sroland.mainz@nrubsig.org{
1204887Schin	command nameref xx=yy
1214887Schin	command nameref yy=xx
1224887Schin} 2> /dev/null && err_exit "self reference not detected"
1234887Schintypeset +n foo bar
1244887Schinunset foo bar
1254887Schinset foo
1264887Schinnameref bar=$1
1274887Schinfoo=hello
1284887Schinif	[[ $bar !=  hello ]]
1294887Schinthen	err_exit 'nameref of positional paramters outside of function not working'
1304887Schinfi
1314887Schinunset foo bar
1324887Schinbar=123
13310898Sroland.mainz@nrubsig.orgfunction foobar
1344887Schin{
1354887Schin	typeset -n foo=bar
1364887Schin	typeset -n foo=bar
1374887Schin}
1384887Schinfoobar 2> /dev/null || err_exit 'nameref not unsetting previous reference'
1394887Schin(
1404887Schin	nameref short=verylong
1414887Schin	short=( A=a B=b )
1424887Schin	if	[[ ${verylong.A} != a ]]
1434887Schin	then	err_exit 'nameref short to longname compound assignment error'
1444887Schin	fi
1454887Schin) 2> /dev/null|| err_exit 'nameref short to longname compound assignment error'
1464887Schinunset x
1474887Schinif	[[	$(var1=1 var2=2
1484887Schin		for i in var1 var2
1494887Schin		do	nameref x=$i
1504887Schin			print $x
1514887Schin		done) != $'1\n2' ]]
1524887Schinthen	err_exit 'for loop nameref optimization error'
1534887Schinfi
1544887Schinif	[[	$(typeset -A var1 var2
1554887Schin		var1[sub1]=1 var2[sub2]=1
1564887Schin		for i in var1 var2
1574887Schin		do
1584887Schin		        typeset -n array=$i
1594887Schin		        print ${!array[*]}
1604887Schin		done) != $'sub1\nsub2' ]]
1614887Schinthen 	err_exit 'for loop nameref optimization test2 error'
1624887Schinfi
1634887Schin
1644887Schinunset -n x foo bar
1654887Schinif	[[ $(nameref x=foo;for x in foo bar;do print ${!x};done) != $'foo\nbar' ]]
1664887Schinthen	err_exit 'for loop optimization with namerefs not working'
1674887Schinfi
1684887Schinif	[[ $(
1694887Schin	p=(x=(r=3) y=(r=4))
1704887Schin	for i in x y
1714887Schin	do	nameref x=p.$i
1724887Schin		print ${x.r}
1734887Schin	done
1744887Schin) != $'3\n4' ]]
1754887Schinthen	err_exit 'nameref optimization error'
1764887Schinfi
1774887Schin[[ $(
1784887Schinunset x y var
1794887Schinvar=(foo=bar)
1804887Schinfor i in y var
1814887Schindo	typeset -n x=$i
1824887Schin	if	[[ ${!x.@} ]]
1834887Schin	then	print ok
1844887Schin	fi
1854887Schin	typeset +n x
1864887Schindone) != ok ]] && err_exit 'invalid for loop optimization of name references'
1874887Schinfunction setval # name value
1884887Schin{
1894887Schin        nameref arg=$1
1904887Schin	nameref var=arg.bar
1914887Schin	var=$2
1924887Schin}
1934887Schinfoo=( integer bar=0)
1944887Schinsetval foo 5
1954887Schin(( foo.bar == 5)) || err_exit 'nested nameref not working'
1964887Schinfunction selfref
1974887Schin{
1984887Schin        typeset -n ps=$1
1994887Schin        print -r -- "${ps}"
2004887Schin}
2014887Schinps=(a=1 b=2)
2024887Schin[[ $(selfref ps) == *a=1* ]] ||  err_exit 'local nameref cannot reference global variable of the same name'
2034887Schinfunction subref
2044887Schin{
2054887Schin	typeset -n foo=$1
2064887Schin	print -r -- ${foo.a}
2074887Schin}
2084887Schin[[ $(subref ps) == 1 ]] ||  err_exit 'local nameref cannot reference global variable child'
2094887Schin
2104887Schinfunction local
2114887Schin{
2124887Schin	typeset ps=(typeset -i a=3 b=4)
2134887Schin	[[ $(subref ps) == 3 ]] ||  err_exit 'local nameref cannot reference caller compound variable'
2144887Schin}
2154887Schinlocal
2164887Schinunset -f local
2174887Schinfunction local
2184887Schin{
2194887Schin	qs=(integer  a=3; integer b=4)
2204887Schin}
2214887Schinlocal 2> /dev/null || err_exit 'function local has non-zero exit status'
22210898Sroland.mainz@nrubsig.org[[ ${qs.a} == 3 ]] || err_exit 'function cannot set compound global variable'
2234887Schinunset fun i
2244887Schinfoo=(x=hi)
2254887Schinfunction fun
2264887Schin{
2274887Schin        nameref i=$1
2284887Schin        print -r -- "${i.x}"
2294887Schin}
2304887Schini=foo
2314887Schin[[ $(fun $i) == hi ]] || err_exit 'nameref for compound variable with in function name of caller fails'
2328462SApril.Chin@Sun.COMunset -n foo bar
2338462SApril.Chin@Sun.COMtypeset -A foo
2348462SApril.Chin@Sun.COMfoo[x.y]=(x=3 y=4)
2358462SApril.Chin@Sun.COMnameref bar=foo[x.y]
2368462SApril.Chin@Sun.COM[[ ${bar.x} == 3 ]] || err_exit 'nameref to subscript containing . fails'
2378462SApril.Chin@Sun.COM[[ ${!bar} == 'foo[x.y]' ]] || err_exit '${!var} not correct for nameref to an array instance'
2388462SApril.Chin@Sun.COMtypeset +n bar
2398462SApril.Chin@Sun.COMnameref bar=foo
2408462SApril.Chin@Sun.COM[[ ${!bar} == foo ]] || err_exit '${!var} not correct for nameref to array variable'
2418462SApril.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'
2428462SApril.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)
2438462SApril.Chin@Sun.COM[[ $i == 4 ]] || err_exit 'creating reference from subscripted variable whose name is a reference failed'
2448462SApril.Chin@Sun.COM[[ $($SHELL 2> /dev/null <<- '+++EOF'
2458462SApril.Chin@Sun.COM	function bar
2468462SApril.Chin@Sun.COM	{
2478462SApril.Chin@Sun.COM	 	nameref x=$1
2488462SApril.Chin@Sun.COM	 	print -r -- "$x"
2498462SApril.Chin@Sun.COM	}
2508462SApril.Chin@Sun.COM	function foo
2518462SApril.Chin@Sun.COM	{
2528462SApril.Chin@Sun.COM	 	typeset var=( foo=hello)
2538462SApril.Chin@Sun.COM	 	bar var
2548462SApril.Chin@Sun.COM	}
2558462SApril.Chin@Sun.COM	foo
2568462SApril.Chin@Sun.COM+++EOF
2578462SApril.Chin@Sun.COM) ==  *foo=hello* ]] || err_exit 'unable to display compound variable from name reference of local variable'
2588462SApril.Chin@Sun.COM#set -x
2598462SApril.Chin@Sun.COMfor c in '=' '[' ']' '\' "'" '"' '<' '=' '('
2608462SApril.Chin@Sun.COMdo	[[ $($SHELL 2> /dev/null <<- ++EOF++
2618462SApril.Chin@Sun.COM	x;i=\\$c;typeset -A a; a[\$i]=foo;typeset -n x=a[\$i]; print "\$x"
2628462SApril.Chin@Sun.COM	++EOF++
2638462SApril.Chin@Sun.COM) != foo ]] && err_exit 'nameref x=[$c] '"not working for c=$c"
2648462SApril.Chin@Sun.COMdone
2658462SApril.Chin@Sun.COMunset -n foo x
2668462SApril.Chin@Sun.COMunset foo x
2678462SApril.Chin@Sun.COMtypeset -A foo
2688462SApril.Chin@Sun.COMnameref x=foo[xyz]
2698462SApril.Chin@Sun.COMfoo[xyz]=ok
2708462SApril.Chin@Sun.COM[[ $x == ok ]] || err_exit 'nameref to unset subscript not working'
2718462SApril.Chin@Sun.COMfunction function2
2728462SApril.Chin@Sun.COM{
2738462SApril.Chin@Sun.COM	nameref v=$1
2748462SApril.Chin@Sun.COM	v.x=19 v.y=20
2758462SApril.Chin@Sun.COM}
2768462SApril.Chin@Sun.COMfunction function1
2778462SApril.Chin@Sun.COM{
2788462SApril.Chin@Sun.COM	typeset compound_var=()
2798462SApril.Chin@Sun.COM	function2 compound_var
2808462SApril.Chin@Sun.COM	printf "x=%d, y=%d\n" compound_var.x compound_var.y
2818462SApril.Chin@Sun.COM}
2828462SApril.Chin@Sun.COMx="$(function1)"
2838462SApril.Chin@Sun.COM[[ "$x" != 'x=19, y=20' ]] && err_exit "expected 'x=19, y=20', got '${x}'"
2848462SApril.Chin@Sun.COMtypeset +n bar
2858462SApril.Chin@Sun.COMunset foo bar
2868462SApril.Chin@Sun.COM[[ $(function a
2878462SApril.Chin@Sun.COM{
2888462SApril.Chin@Sun.COM	for i in  foo bar
2898462SApril.Chin@Sun.COM	do	typeset -n v=$i
2908462SApril.Chin@Sun.COM		print $v
2918462SApril.Chin@Sun.COM	done | cat
2928462SApril.Chin@Sun.COM}
2938462SApril.Chin@Sun.COMfoo=1 bar=2;a) == $'1\n2' ]] 2> /dev/null || err_exit 'nameref in pipeline broken'
2948462SApril.Chin@Sun.COMfunction a
2958462SApril.Chin@Sun.COM{
2968462SApril.Chin@Sun.COM	typeset -n v=vars.data._1
2978462SApril.Chin@Sun.COM	print "${v.a} ${v.b}"
2988462SApril.Chin@Sun.COM}
2998462SApril.Chin@Sun.COMvars=(data=())
3008462SApril.Chin@Sun.COMvars.data._1.a=a.1
3018462SApril.Chin@Sun.COMvars.data._1.b=b.1
3028462SApril.Chin@Sun.COM[[ $(a) == 'a.1 b.1' ]] || err_exit 'nameref choosing wrong scope -- '
30310898Sroland.mainz@nrubsig.orgtypeset +n bam zip foo
30410898Sroland.mainz@nrubsig.orgunset bam zip foo
30510898Sroland.mainz@nrubsig.orgtypeset -A foo
30610898Sroland.mainz@nrubsig.orgfoo[2]=bar
30710898Sroland.mainz@nrubsig.orgtypeset -n bam=foo[2]
30810898Sroland.mainz@nrubsig.orgtypeset -n zip=bam
30910898Sroland.mainz@nrubsig.org[[ $zip == bar ]] || err_exit 'nameref to another nameref to array element fails'
31010898Sroland.mainz@nrubsig.org[[ -R zip ]] || err_exit '[[ -R zip ]] should detect that zip is a reference'
31110898Sroland.mainz@nrubsig.org[[ -R bam ]] || err_exit '[[ -R bam ]] should detect that bam is a reference'
31210898Sroland.mainz@nrubsig.org[[ -R zip ]] || err_exit '[[ -v zip ]] should detect that zip is set'
31310898Sroland.mainz@nrubsig.org[[ -v bam ]] || err_exit '[[ -v bam ]] should detect that bam is set'
31410898Sroland.mainz@nrubsig.org[[ -R 123 ]] && err_exit '[[ -R 123 ]] should detect that 123 is not a reference'
31510898Sroland.mainz@nrubsig.org[[ -v 123 ]] && err_exit '[[ -v 123 ]] should detect that 123 is not set'
31610898Sroland.mainz@nrubsig.org
31710898Sroland.mainz@nrubsig.orgunset ref x
31810898Sroland.mainz@nrubsig.orgtypeset -n ref
31910898Sroland.mainz@nrubsig.orgx=3
32010898Sroland.mainz@nrubsig.orgfunction foobar
32110898Sroland.mainz@nrubsig.org{
32210898Sroland.mainz@nrubsig.org	typeset xxx=3
32310898Sroland.mainz@nrubsig.org	ref=xxx
32410898Sroland.mainz@nrubsig.org	return 0
32510898Sroland.mainz@nrubsig.org}
32610898Sroland.mainz@nrubsig.orgfoobar 2> /dev/null && err_exit 'invalid reference should cause foobar to fail'
32710898Sroland.mainz@nrubsig.org[[ -v ref ]] && err_exit '$ref should be unset'
32810898Sroland.mainz@nrubsig.orgref=x
32910898Sroland.mainz@nrubsig.org[[ $ref == 3 ]] || err_exit "\$ref is $ref, it should be 3"
33010898Sroland.mainz@nrubsig.orgfunction foobar
33110898Sroland.mainz@nrubsig.org{
33210898Sroland.mainz@nrubsig.org        typeset fvar=()
33310898Sroland.mainz@nrubsig.org        typeset -n ref=fvar.foo
33410898Sroland.mainz@nrubsig.org        ref=ok
33510898Sroland.mainz@nrubsig.org        print -r $ref
33610898Sroland.mainz@nrubsig.org}
33710898Sroland.mainz@nrubsig.org[[ $(foobar) ==  ok ]] 2> /dev/null  || err_exit 'nameref in function not creating variable in proper scope'
33810898Sroland.mainz@nrubsig.orgfunction foobar
33910898Sroland.mainz@nrubsig.org{
34010898Sroland.mainz@nrubsig.org        nameref doc=docs
34110898Sroland.mainz@nrubsig.org        nameref bar=doc.num
34210898Sroland.mainz@nrubsig.org	[[ $bar == 2 ]] || err_exit 'nameref scoping error'
34310898Sroland.mainz@nrubsig.org}
34410898Sroland.mainz@nrubsig.org
34510898Sroland.mainz@nrubsig.orgdocs=(num=2)
34610898Sroland.mainz@nrubsig.orgfoobar
34710898Sroland.mainz@nrubsig.org
34810898Sroland.mainz@nrubsig.orgtypeset +n x y
34910898Sroland.mainz@nrubsig.orgunset x y
35010898Sroland.mainz@nrubsig.orgtypeset -A x
35110898Sroland.mainz@nrubsig.orgx[a]=(b=c)
35210898Sroland.mainz@nrubsig.orgtypeset -n y=x[a]
35310898Sroland.mainz@nrubsig.org[[ ${!y.@} == 'x[a].b' ]] || err_exit 'reference to array element not expanded with ${!y.@}'
35410898Sroland.mainz@nrubsig.org
35510898Sroland.mainz@nrubsig.orgtypeset +n v
35610898Sroland.mainz@nrubsig.orgv=()
35710898Sroland.mainz@nrubsig.orgk=a.b.c/d
35810898Sroland.mainz@nrubsig.orgcommand typeset -n n=v.${k//['./']/_} 2> /dev/null || err_exit 'patterns with quotes not handled correctly with name reference assignment'
35910898Sroland.mainz@nrubsig.org
36010898Sroland.mainz@nrubsig.orgtypeset _n sp
36110898Sroland.mainz@nrubsig.orgnameref sp=addrsp
36210898Sroland.mainz@nrubsig.orgsp[14]=( size=1 )
36310898Sroland.mainz@nrubsig.org[[ -v sp[19] ]]  && err_exit '[[ -v sp[19] ]] where sp is a nameref should not be set'
36410898Sroland.mainz@nrubsig.org
3654887Schinexit $((Errors))
366