1da2e3ebdSchin########################################################################
2da2e3ebdSchin#                                                                      #
3da2e3ebdSchin#               This software is part of the ast package               #
4*b30d1939SAndy Fiddaman#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5da2e3ebdSchin#                      and is licensed under the                       #
6*b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
77c2fbfb3SApril Chin#                    by AT&T Intellectual Property                     #
8da2e3ebdSchin#                                                                      #
9da2e3ebdSchin#                A copy of the License is available at                 #
10*b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11*b30d1939SAndy 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
3034f9b3eeSRoland Mainz
3134f9b3eeSRoland Mainztmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
3234f9b3eeSRoland Mainztrap "cd /; rm -rf $tmp" EXIT
3334f9b3eeSRoland Mainz
34da2e3ebdSchinfunction checkref
35da2e3ebdSchin{
36da2e3ebdSchin	nameref foo=$1 bar=$2
37da2e3ebdSchin	if	[[ $foo !=  $bar ]]
38da2e3ebdSchin	then	err_exit "foo=$foo != bar=$bar"
39da2e3ebdSchin	fi
40da2e3ebdSchin	foo=hello
41da2e3ebdSchin	if	[[ $foo !=  $bar ]]
42da2e3ebdSchin	then	err_exit "foo=$foo != bar=$bar"
43da2e3ebdSchin	fi
44da2e3ebdSchin	foo.child=child
45da2e3ebdSchin	if	[[ ${foo.child} !=  ${bar.child} ]]
46da2e3ebdSchin	then	err_exit "foo.child=${foo.child} != bar=${bar.child}"
47da2e3ebdSchin	fi
48da2e3ebdSchin}
49da2e3ebdSchin
50da2e3ebdSchinname=first
51da2e3ebdSchincheckref name name
52da2e3ebdSchinname.child=second
53da2e3ebdSchincheckref name name
54da2e3ebdSchin.foo=top
55da2e3ebdSchin.foo.bar=next
56da2e3ebdSchincheckref .foo.bar .foo.bar
57da2e3ebdSchinif	[[ ${.foo.bar} !=  hello ]]
58da2e3ebdSchinthen	err_exit ".foo.bar=${.foo.bar} != hello"
59da2e3ebdSchinfi
60da2e3ebdSchinif	[[ ${.foo.bar.child} !=  child ]]
61da2e3ebdSchinthen	err_exit ".foo.bar.child=${.foo.bar.child} != child"
62da2e3ebdSchinfi
63da2e3ebdSchinfunction func1
64da2e3ebdSchin{
65da2e3ebdSchin        nameref color=$1
66da2e3ebdSchin        func2 color
67da2e3ebdSchin}
68da2e3ebdSchin
69da2e3ebdSchinfunction func2
70da2e3ebdSchin{
71da2e3ebdSchin        nameref color=$1
72da2e3ebdSchin        set -s -- ${!color[@]}
73da2e3ebdSchin	print -r -- "$@"
74da2e3ebdSchin}
75da2e3ebdSchin
76da2e3ebdSchintypeset -A color
77da2e3ebdSchincolor[apple]=red
78da2e3ebdSchincolor[grape]=purple
79da2e3ebdSchincolor[banana]=yellow
80da2e3ebdSchinif	[[ $(func1 color) != 'apple banana grape' ]]
81da2e3ebdSchinthen	err_exit "nameref or nameref not working"
82da2e3ebdSchinfi
83da2e3ebdSchinnameref x=.foo.bar
84da2e3ebdSchinif	[[ ${!x} != .foo.bar ]]
85da2e3ebdSchinthen	err_exit "${!x} not working"
86da2e3ebdSchinfi
8734f9b3eeSRoland Mainztypeset +n x $(typeset +n)
88da2e3ebdSchinunset x
89da2e3ebdSchinnameref x=.foo.bar
90da2e3ebdSchinfunction x.set
91da2e3ebdSchin{
92da2e3ebdSchin	[[ ${.sh.value} ]] && print hello
93da2e3ebdSchin}
94da2e3ebdSchinif	[[ $(.foo.bar.set) != $(x.set) ]]
95da2e3ebdSchinthen	err_exit "function references  not working"
96da2e3ebdSchinfi
97da2e3ebdSchinif	[[ $(typeset +n) != x ]]
98da2e3ebdSchinthen	err_exit "typeset +n doesn't list names of reference variables"
99da2e3ebdSchinfi
100da2e3ebdSchinif	[[ $(typeset -n) != x=.foo.bar ]]
101da2e3ebdSchinthen	err_exit "typeset +n doesn't list values of reference variables"
102da2e3ebdSchinfi
10334f9b3eeSRoland Mainzfile=$tmp/test
104da2e3ebdSchintypeset +n foo bar 2> /dev/null
105da2e3ebdSchinunset foo bar
106da2e3ebdSchinexport bar=foo
107da2e3ebdSchinnameref foo=bar
108da2e3ebdSchinif	[[ $foo != foo ]]
109da2e3ebdSchinthen	err_exit "value of nameref foo !=  $foo"
110da2e3ebdSchinfi
111da2e3ebdSchincat > $file <<\!
112da2e3ebdSchinprint -r -- $foo
113da2e3ebdSchin!
114da2e3ebdSchinchmod +x "$file"
115da2e3ebdSchiny=$( $file)
116da2e3ebdSchinif	[[ $y != '' ]]
117da2e3ebdSchinthen	err_exit "reference variable not cleared"
118da2e3ebdSchinfi
11934f9b3eeSRoland Mainz{
120da2e3ebdSchin	command nameref xx=yy
121da2e3ebdSchin	command nameref yy=xx
122da2e3ebdSchin} 2> /dev/null && err_exit "self reference not detected"
123da2e3ebdSchintypeset +n foo bar
124da2e3ebdSchinunset foo bar
125da2e3ebdSchinset foo
126da2e3ebdSchinnameref bar=$1
127da2e3ebdSchinfoo=hello
128da2e3ebdSchinif	[[ $bar !=  hello ]]
129da2e3ebdSchinthen	err_exit 'nameref of positional paramters outside of function not working'
130da2e3ebdSchinfi
131da2e3ebdSchinunset foo bar
132da2e3ebdSchinbar=123
13334f9b3eeSRoland Mainzfunction foobar
134da2e3ebdSchin{
135da2e3ebdSchin	typeset -n foo=bar
136da2e3ebdSchin	typeset -n foo=bar
137da2e3ebdSchin}
138da2e3ebdSchinfoobar 2> /dev/null || err_exit 'nameref not unsetting previous reference'
139da2e3ebdSchin(
140da2e3ebdSchin	nameref short=verylong
141da2e3ebdSchin	short=( A=a B=b )
142da2e3ebdSchin	if	[[ ${verylong.A} != a ]]
143da2e3ebdSchin	then	err_exit 'nameref short to longname compound assignment error'
144da2e3ebdSchin	fi
145da2e3ebdSchin) 2> /dev/null|| err_exit 'nameref short to longname compound assignment error'
146da2e3ebdSchinunset x
147da2e3ebdSchinif	[[	$(var1=1 var2=2
148da2e3ebdSchin		for i in var1 var2
149da2e3ebdSchin		do	nameref x=$i
150da2e3ebdSchin			print $x
151da2e3ebdSchin		done) != $'1\n2' ]]
152da2e3ebdSchinthen	err_exit 'for loop nameref optimization error'
153da2e3ebdSchinfi
154da2e3ebdSchinif	[[	$(typeset -A var1 var2
155da2e3ebdSchin		var1[sub1]=1 var2[sub2]=1
156da2e3ebdSchin		for i in var1 var2
157da2e3ebdSchin		do
158da2e3ebdSchin		        typeset -n array=$i
159da2e3ebdSchin		        print ${!array[*]}
160da2e3ebdSchin		done) != $'sub1\nsub2' ]]
161da2e3ebdSchinthen 	err_exit 'for loop nameref optimization test2 error'
162da2e3ebdSchinfi
163da2e3ebdSchin
164da2e3ebdSchinunset -n x foo bar
165da2e3ebdSchinif	[[ $(nameref x=foo;for x in foo bar;do print ${!x};done) != $'foo\nbar' ]]
166da2e3ebdSchinthen	err_exit 'for loop optimization with namerefs not working'
167da2e3ebdSchinfi
168da2e3ebdSchinif	[[ $(
169da2e3ebdSchin	p=(x=(r=3) y=(r=4))
170da2e3ebdSchin	for i in x y
171da2e3ebdSchin	do	nameref x=p.$i
172da2e3ebdSchin		print ${x.r}
173da2e3ebdSchin	done
174da2e3ebdSchin) != $'3\n4' ]]
175da2e3ebdSchinthen	err_exit 'nameref optimization error'
176da2e3ebdSchinfi
177da2e3ebdSchin[[ $(
178da2e3ebdSchinunset x y var
179da2e3ebdSchinvar=(foo=bar)
180da2e3ebdSchinfor i in y var
181da2e3ebdSchindo	typeset -n x=$i
182da2e3ebdSchin	if	[[ ${!x.@} ]]
183da2e3ebdSchin	then	print ok
184da2e3ebdSchin	fi
185da2e3ebdSchin	typeset +n x
186da2e3ebdSchindone) != ok ]] && err_exit 'invalid for loop optimization of name references'
187da2e3ebdSchinfunction setval # name value
188da2e3ebdSchin{
189da2e3ebdSchin        nameref arg=$1
190da2e3ebdSchin	nameref var=arg.bar
191da2e3ebdSchin	var=$2
192da2e3ebdSchin}
193da2e3ebdSchinfoo=( integer bar=0)
194da2e3ebdSchinsetval foo 5
195da2e3ebdSchin(( foo.bar == 5)) || err_exit 'nested nameref not working'
196da2e3ebdSchinfunction selfref
197da2e3ebdSchin{
198da2e3ebdSchin        typeset -n ps=$1
199da2e3ebdSchin        print -r -- "${ps}"
200da2e3ebdSchin}
201da2e3ebdSchinps=(a=1 b=2)
202da2e3ebdSchin[[ $(selfref ps) == *a=1* ]] ||  err_exit 'local nameref cannot reference global variable of the same name'
203da2e3ebdSchinfunction subref
204da2e3ebdSchin{
205da2e3ebdSchin	typeset -n foo=$1
206da2e3ebdSchin	print -r -- ${foo.a}
207da2e3ebdSchin}
208da2e3ebdSchin[[ $(subref ps) == 1 ]] ||  err_exit 'local nameref cannot reference global variable child'
209da2e3ebdSchin
210da2e3ebdSchinfunction local
211da2e3ebdSchin{
212da2e3ebdSchin	typeset ps=(typeset -i a=3 b=4)
213da2e3ebdSchin	[[ $(subref ps) == 3 ]] ||  err_exit 'local nameref cannot reference caller compound variable'
214da2e3ebdSchin}
215da2e3ebdSchinlocal
216da2e3ebdSchinunset -f local
217da2e3ebdSchinfunction local
218da2e3ebdSchin{
219da2e3ebdSchin	qs=(integer  a=3; integer b=4)
220da2e3ebdSchin}
221da2e3ebdSchinlocal 2> /dev/null || err_exit 'function local has non-zero exit status'
22234f9b3eeSRoland Mainz[[ ${qs.a} == 3 ]] || err_exit 'function cannot set compound global variable'
223da2e3ebdSchinunset fun i
224da2e3ebdSchinfoo=(x=hi)
225da2e3ebdSchinfunction fun
226da2e3ebdSchin{
227da2e3ebdSchin        nameref i=$1
228da2e3ebdSchin        print -r -- "${i.x}"
229da2e3ebdSchin}
230da2e3ebdSchini=foo
231da2e3ebdSchin[[ $(fun $i) == hi ]] || err_exit 'nameref for compound variable with in function name of caller fails'
2327c2fbfb3SApril Chinunset -n foo bar
2337c2fbfb3SApril Chintypeset -A foo
2347c2fbfb3SApril Chinfoo[x.y]=(x=3 y=4)
2357c2fbfb3SApril Chinnameref bar=foo[x.y]
2367c2fbfb3SApril Chin[[ ${bar.x} == 3 ]] || err_exit 'nameref to subscript containing . fails'
2377c2fbfb3SApril Chin[[ ${!bar} == 'foo[x.y]' ]] || err_exit '${!var} not correct for nameref to an array instance'
2387c2fbfb3SApril Chintypeset +n bar
2397c2fbfb3SApril Chinnameref bar=foo
2407c2fbfb3SApril Chin[[ ${!bar} == foo ]] || err_exit '${!var} not correct for nameref to array variable'
2417c2fbfb3SApril Chin$SHELL -c 'function bar { nameref x=foo[++];};typeset -A foo;bar' 2> /dev/null ||err_exit 'nameref of associative array tries to evaluate subscript'
2427c2fbfb3SApril Chini=$($SHELL -c 'nameref foo=bar; bar[2]=(x=3 y=4); nameref x=foo[2].y;print -r -- $x' 2> /dev/null)
2437c2fbfb3SApril Chin[[ $i == 4 ]] || err_exit 'creating reference from subscripted variable whose name is a reference failed'
2447c2fbfb3SApril Chin[[ $($SHELL 2> /dev/null <<- '+++EOF'
2457c2fbfb3SApril Chin	function bar
2467c2fbfb3SApril Chin	{
2477c2fbfb3SApril Chin	 	nameref x=$1
2487c2fbfb3SApril Chin	 	print -r -- "$x"
2497c2fbfb3SApril Chin	}
2507c2fbfb3SApril Chin	function foo
2517c2fbfb3SApril Chin	{
2527c2fbfb3SApril Chin	 	typeset var=( foo=hello)
2537c2fbfb3SApril Chin	 	bar var
2547c2fbfb3SApril Chin	}
2557c2fbfb3SApril Chin	foo
2567c2fbfb3SApril Chin+++EOF
2577c2fbfb3SApril Chin) ==  *foo=hello* ]] || err_exit 'unable to display compound variable from name reference of local variable'
2587c2fbfb3SApril Chin#set -x
2597c2fbfb3SApril Chinfor c in '=' '[' ']' '\' "'" '"' '<' '=' '('
2607c2fbfb3SApril Chindo	[[ $($SHELL 2> /dev/null <<- ++EOF++
261*b30d1939SAndy Fiddaman	i=\\$c;typeset -A a; a[\$i]=foo;typeset -n x=a[\$i]; print "\$x"
2627c2fbfb3SApril Chin	++EOF++
263*b30d1939SAndy Fiddaman) != foo ]] && err_exit 'nameref x=a[$c] '"not working for c=$c"
2647c2fbfb3SApril Chindone
265*b30d1939SAndy Fiddamanfor c in '=' '[' ']' '\' "'" '"' '<' '=' '('
266*b30d1939SAndy Fiddamando      [[ $($SHELL 2> /dev/null <<- ++EOF++
267*b30d1939SAndy Fiddaman	i=\\$c;typeset -A a; a[\$i]=foo;b=a[\$i];typeset -n x=\$b; print "\$x"
268*b30d1939SAndy Fiddaman	++EOF++
269*b30d1939SAndy Fiddaman) != foo ]] && err_exit 'nameref x=$b with b=a[$c] '"not working for c=$c"
270*b30d1939SAndy Fiddamandone
271*b30d1939SAndy Fiddaman
2727c2fbfb3SApril Chinunset -n foo x
2737c2fbfb3SApril Chinunset foo x
2747c2fbfb3SApril Chintypeset -A foo
2757c2fbfb3SApril Chinnameref x=foo[xyz]
2767c2fbfb3SApril Chinfoo[xyz]=ok
2777c2fbfb3SApril Chin[[ $x == ok ]] || err_exit 'nameref to unset subscript not working'
2787c2fbfb3SApril Chinfunction function2
2797c2fbfb3SApril Chin{
2807c2fbfb3SApril Chin	nameref v=$1
2817c2fbfb3SApril Chin	v.x=19 v.y=20
2827c2fbfb3SApril Chin}
2837c2fbfb3SApril Chinfunction function1
2847c2fbfb3SApril Chin{
2857c2fbfb3SApril Chin	typeset compound_var=()
2867c2fbfb3SApril Chin	function2 compound_var
2877c2fbfb3SApril Chin	printf "x=%d, y=%d\n" compound_var.x compound_var.y
2887c2fbfb3SApril Chin}
2897c2fbfb3SApril Chinx="$(function1)"
2907c2fbfb3SApril Chin[[ "$x" != 'x=19, y=20' ]] && err_exit "expected 'x=19, y=20', got '${x}'"
2917c2fbfb3SApril Chintypeset +n bar
2927c2fbfb3SApril Chinunset foo bar
2937c2fbfb3SApril Chin[[ $(function a
2947c2fbfb3SApril Chin{
2957c2fbfb3SApril Chin	for i in  foo bar
2967c2fbfb3SApril Chin	do	typeset -n v=$i
2977c2fbfb3SApril Chin		print $v
2987c2fbfb3SApril Chin	done | cat
2997c2fbfb3SApril Chin}
3007c2fbfb3SApril Chinfoo=1 bar=2;a) == $'1\n2' ]] 2> /dev/null || err_exit 'nameref in pipeline broken'
3017c2fbfb3SApril Chinfunction a
3027c2fbfb3SApril Chin{
3037c2fbfb3SApril Chin	typeset -n v=vars.data._1
3047c2fbfb3SApril Chin	print "${v.a} ${v.b}"
3057c2fbfb3SApril Chin}
3067c2fbfb3SApril Chinvars=(data=())
3077c2fbfb3SApril Chinvars.data._1.a=a.1
3087c2fbfb3SApril Chinvars.data._1.b=b.1
3097c2fbfb3SApril Chin[[ $(a) == 'a.1 b.1' ]] || err_exit 'nameref choosing wrong scope -- '
31034f9b3eeSRoland Mainztypeset +n bam zip foo
31134f9b3eeSRoland Mainzunset bam zip foo
31234f9b3eeSRoland Mainztypeset -A foo
31334f9b3eeSRoland Mainzfoo[2]=bar
31434f9b3eeSRoland Mainztypeset -n bam=foo[2]
31534f9b3eeSRoland Mainztypeset -n zip=bam
31634f9b3eeSRoland Mainz[[ $zip == bar ]] || err_exit 'nameref to another nameref to array element fails'
31734f9b3eeSRoland Mainz[[ -R zip ]] || err_exit '[[ -R zip ]] should detect that zip is a reference'
31834f9b3eeSRoland Mainz[[ -R bam ]] || err_exit '[[ -R bam ]] should detect that bam is a reference'
31934f9b3eeSRoland Mainz[[ -R zip ]] || err_exit '[[ -v zip ]] should detect that zip is set'
32034f9b3eeSRoland Mainz[[ -v bam ]] || err_exit '[[ -v bam ]] should detect that bam is set'
32134f9b3eeSRoland Mainz[[ -R 123 ]] && err_exit '[[ -R 123 ]] should detect that 123 is not a reference'
32234f9b3eeSRoland Mainz[[ -v 123 ]] && err_exit '[[ -v 123 ]] should detect that 123 is not set'
32334f9b3eeSRoland Mainz
32434f9b3eeSRoland Mainzunset ref x
32534f9b3eeSRoland Mainztypeset -n ref
32634f9b3eeSRoland Mainzx=3
32734f9b3eeSRoland Mainzfunction foobar
32834f9b3eeSRoland Mainz{
32934f9b3eeSRoland Mainz	typeset xxx=3
33034f9b3eeSRoland Mainz	ref=xxx
33134f9b3eeSRoland Mainz	return 0
33234f9b3eeSRoland Mainz}
33334f9b3eeSRoland Mainzfoobar 2> /dev/null && err_exit 'invalid reference should cause foobar to fail'
33434f9b3eeSRoland Mainz[[ -v ref ]] && err_exit '$ref should be unset'
33534f9b3eeSRoland Mainzref=x
33634f9b3eeSRoland Mainz[[ $ref == 3 ]] || err_exit "\$ref is $ref, it should be 3"
33734f9b3eeSRoland Mainzfunction foobar
33834f9b3eeSRoland Mainz{
33934f9b3eeSRoland Mainz        typeset fvar=()
34034f9b3eeSRoland Mainz        typeset -n ref=fvar.foo
34134f9b3eeSRoland Mainz        ref=ok
34234f9b3eeSRoland Mainz        print -r $ref
34334f9b3eeSRoland Mainz}
34434f9b3eeSRoland Mainz[[ $(foobar) ==  ok ]] 2> /dev/null  || err_exit 'nameref in function not creating variable in proper scope'
34534f9b3eeSRoland Mainzfunction foobar
34634f9b3eeSRoland Mainz{
34734f9b3eeSRoland Mainz        nameref doc=docs
34834f9b3eeSRoland Mainz        nameref bar=doc.num
34934f9b3eeSRoland Mainz	[[ $bar == 2 ]] || err_exit 'nameref scoping error'
35034f9b3eeSRoland Mainz}
35134f9b3eeSRoland Mainz
35234f9b3eeSRoland Mainzdocs=(num=2)
35334f9b3eeSRoland Mainzfoobar
35434f9b3eeSRoland Mainz
35534f9b3eeSRoland Mainztypeset +n x y
35634f9b3eeSRoland Mainzunset x y
35734f9b3eeSRoland Mainztypeset -A x
35834f9b3eeSRoland Mainzx[a]=(b=c)
35934f9b3eeSRoland Mainztypeset -n y=x[a]
36034f9b3eeSRoland Mainz[[ ${!y.@} == 'x[a].b' ]] || err_exit 'reference to array element not expanded with ${!y.@}'
36134f9b3eeSRoland Mainz
36234f9b3eeSRoland Mainztypeset +n v
36334f9b3eeSRoland Mainzv=()
36434f9b3eeSRoland Mainzk=a.b.c/d
36534f9b3eeSRoland Mainzcommand typeset -n n=v.${k//['./']/_} 2> /dev/null || err_exit 'patterns with quotes not handled correctly with name reference assignment'
36634f9b3eeSRoland Mainz
36734f9b3eeSRoland Mainztypeset _n sp
36834f9b3eeSRoland Mainznameref sp=addrsp
36934f9b3eeSRoland Mainzsp[14]=( size=1 )
37034f9b3eeSRoland Mainz[[ -v sp[19] ]]  && err_exit '[[ -v sp[19] ]] where sp is a nameref should not be set'
37134f9b3eeSRoland Mainz
372*b30d1939SAndy Fiddamanfunction fun2
373*b30d1939SAndy Fiddaman{
374*b30d1939SAndy Fiddaman	nameref var=$1
375*b30d1939SAndy Fiddaman	var.foo=bar
376*b30d1939SAndy Fiddaman}
377*b30d1939SAndy Fiddaman
378*b30d1939SAndy Fiddamanfunction fun1
379*b30d1939SAndy Fiddaman{
380*b30d1939SAndy Fiddaman	compound -S container
381*b30d1939SAndy Fiddaman	fun2 container
382*b30d1939SAndy Fiddaman	[[ $container == *foo=bar* ]] || err_exit 'name references to static compound variables in parent scope not working'
383*b30d1939SAndy Fiddaman}
384*b30d1939SAndy Fiddamanfun1
385*b30d1939SAndy Fiddaman
386*b30d1939SAndy Fiddamanfunction fun2
387*b30d1939SAndy Fiddaman{
388*b30d1939SAndy Fiddaman	nameref var=$1
389*b30d1939SAndy Fiddaman	var.foo=bar
390*b30d1939SAndy Fiddaman}
391*b30d1939SAndy Fiddaman
392*b30d1939SAndy Fiddamantypeset -T container_t=(
393*b30d1939SAndy Fiddaman	typeset foo
394*b30d1939SAndy Fiddaman)
395*b30d1939SAndy Fiddaman
396*b30d1939SAndy Fiddamanfunction fun1
397*b30d1939SAndy Fiddaman{
398*b30d1939SAndy Fiddaman	container_t -S container
399*b30d1939SAndy Fiddaman	fun2 container
400*b30d1939SAndy Fiddaman	[[ $container == *foo=bar* ]] || err_exit 'name references to static type variables in parent scope not working'
401*b30d1939SAndy Fiddaman}
402*b30d1939SAndy Fiddamanfun1
403*b30d1939SAndy Fiddaman
404*b30d1939SAndy Fiddamanfunction fun2
405*b30d1939SAndy Fiddaman{
406*b30d1939SAndy Fiddaman	nameref var=$1
407*b30d1939SAndy Fiddaman	nameref node=var.foo
408*b30d1939SAndy Fiddaman	node=bar
409*b30d1939SAndy Fiddaman}
410*b30d1939SAndy Fiddamanfunction fun3
411*b30d1939SAndy Fiddaman{
412*b30d1939SAndy Fiddaman       fun2 container #2> /dev/null
413*b30d1939SAndy Fiddaman}
414*b30d1939SAndy Fiddamancompound container
415*b30d1939SAndy Fiddamanfun3
416*b30d1939SAndy Fiddaman[[ $container == *foo=bar* ]] || err_exit 'name reference to a name reference variable in a function not working'
417*b30d1939SAndy Fiddaman
418*b30d1939SAndy Fiddamantypeset -A x=( [a]=1 )
419*b30d1939SAndy Fiddamannameref c=x[h]
420*b30d1939SAndy Fiddaman[[ -v x[h] ]] && err_exit 'creating reference to non-existant associative array element causes element to get added'
421*b30d1939SAndy Fiddaman
422*b30d1939SAndy Fiddamanunset a
423*b30d1939SAndy Fiddamanfunction x
424*b30d1939SAndy Fiddaman{
425*b30d1939SAndy Fiddaman	nameref a=a
426*b30d1939SAndy Fiddaman	(( $# > 0 )) && typeset -A a
427*b30d1939SAndy Fiddaman	a[a b]=${1-99}  # this was cauing a syntax on the second call
428*b30d1939SAndy Fiddaman}
429*b30d1939SAndy Fiddamanx 7
430*b30d1939SAndy Fiddamanx 2> /dev/null
431*b30d1939SAndy Fiddaman[[ ${a[a b]} == 99 ]] || err_exit 'nameref not handling subscript correctly'
432*b30d1939SAndy Fiddaman
433*b30d1939SAndy Fiddamannameref sizes=baz
434*b30d1939SAndy Fiddamantypeset -A -i sizes
435*b30d1939SAndy Fiddamansizes[bar]=1
436*b30d1939SAndy Fiddaman[[ ${sizes[*]} == 1 ]] || err_exit 'adding -Ai attribute to name referenced variable not working'
437*b30d1939SAndy Fiddaman
438*b30d1939SAndy Fiddaman$SHELL 2> /dev/null -c 'nameref foo=bar; typeset -A foo; (( (x=foo[a])==0 ))' || err_exit 'references inside arithmetic expressions not working'
439*b30d1939SAndy Fiddaman:
440*b30d1939SAndy Fiddaman
441*b30d1939SAndy Fiddamanunset ar z
442*b30d1939SAndy Fiddamaninteger -a ar
443*b30d1939SAndy Fiddamannameref z=ar[0]
444*b30d1939SAndy Fiddaman(( z[2]=3))
445*b30d1939SAndy Fiddaman[[ ${ar[0][2]} == 3 ]] || err_exit "\${ar[0][2]} is '${ar[0][2]}' but should be 3"
446*b30d1939SAndy Fiddaman(( ar[0][2] == 3 )) || err_exit "ar[0][2] is '${ar[0][2]}' but should be 3"
447*b30d1939SAndy Fiddaman
448*b30d1939SAndy Fiddamanunset c x
449*b30d1939SAndy Fiddamantypeset +n c x
450*b30d1939SAndy Fiddamancompound c=( typeset -a x )
451*b30d1939SAndy Fiddamannameref x=c.x
452*b30d1939SAndy Fiddamanx[4]=1
453*b30d1939SAndy Fiddaman[[ ${ typeset -p c.x ;} == *-C* ]] && err_exit 'c.x should not have -C attributes'
454*b30d1939SAndy Fiddaman
455*b30d1939SAndy Fiddaman{ $SHELL 2> /dev/null  <<- \EOF
456*b30d1939SAndy Fiddaman	typeset -T xxx_t=(
457*b30d1939SAndy Fiddaman		float x=1 y=2
458*b30d1939SAndy Fiddaman		typeset name=abc
459*b30d1939SAndy Fiddaman	)
460*b30d1939SAndy Fiddaman	xxx_t x
461*b30d1939SAndy Fiddaman	nameref r=x.y
462*b30d1939SAndy Fiddaman	[[ $r == 2 ]] || exit 1
463*b30d1939SAndy Fiddaman	unset x
464*b30d1939SAndy Fiddaman	[[ ${!r} == .deleted ]] || exit 2
465*b30d1939SAndy FiddamanEOF
466*b30d1939SAndy Fiddaman} 2> /dev/null #|| print -u2 bad
467*b30d1939SAndy Fiddamanexitval=$?
468*b30d1939SAndy Fiddamanif	[[ $(kill -l $exitval) == SEGV ]]
469*b30d1939SAndy Fiddamanthen	print -u2 'name reference to unset type instance causes segmentation violation'
470*b30d1939SAndy Fiddamanelse 	if((exitval))
471*b30d1939SAndy Fiddaman	then	print -u2 'name reference to unset type instance not redirected to .deleted'
472*b30d1939SAndy Fiddaman	fi
473*b30d1939SAndy Fiddamanfi
474*b30d1939SAndy Fiddaman
475*b30d1939SAndy Fiddamantypeset +n nr
476*b30d1939SAndy Fiddamanunset c nr
477*b30d1939SAndy Fiddamancompound c
478*b30d1939SAndy Fiddamancompound -A c.a
479*b30d1939SAndy Fiddamannameref nr=c.a[hello]
480*b30d1939SAndy Fiddaman[[ ${!nr} == "c.a[hello]" ]] || err_exit 'name reference nr to unset associative array instance does not expand ${!nr} correctly.'
481*b30d1939SAndy Fiddaman
482*b30d1939SAndy Fiddamantypeset +n nr
483*b30d1939SAndy Fiddamancompound -a c.b
484*b30d1939SAndy Fiddamannameref nr=c.b[2]
485*b30d1939SAndy Fiddaman[[ ${!nr} == "c.b[2]" ]] || err_exit 'name reference nr to unset indexed array instance does not expand ${!nr} correctly.'
486*b30d1939SAndy Fiddaman
487*b30d1939SAndy Fiddamantypeset +n a b
488*b30d1939SAndy Fiddamanunset a b
489*b30d1939SAndy Fiddamantypeset -n a=ls[0] b=ls[1]
490*b30d1939SAndy Fiddamanread line << \!
491*b30d1939SAndy Fiddaman3 4
492*b30d1939SAndy Fiddaman!
493*b30d1939SAndy Fiddamanset -A ls -- $line
494*b30d1939SAndy Fiddaman[[ $a == 3 ]] || err_exit 'name reference to ls[0] when ls is not an array fails'
495*b30d1939SAndy Fiddaman
496*b30d1939SAndy Fiddaman$SHELL  2> /dev/null <<-\EOF || err_exit 'nameref to array element fails'
497*b30d1939SAndy Fiddaman	set -o errexit
498*b30d1939SAndy Fiddaman	function bf {
499*b30d1939SAndy Fiddaman		nameref treename=$1
500*b30d1939SAndy Fiddaman		nodepath="treename" ;
501*b30d1939SAndy Fiddaman		nameref x="$nodepath"
502*b30d1939SAndy Fiddaman		compound -A x.nodes
503*b30d1939SAndy Fiddaman		nameref node=treename.nodes[4]
504*b30d1939SAndy Fiddaman		node=()
505*b30d1939SAndy Fiddaman		typeset +p node.elements
506*b30d1939SAndy Fiddaman	}
507*b30d1939SAndy Fiddaman	compound c
508*b30d1939SAndy Fiddaman	bf c
509*b30d1939SAndy FiddamanEOF
510*b30d1939SAndy Fiddaman
511*b30d1939SAndy Fiddamanfunction add_compound
512*b30d1939SAndy Fiddaman{
513*b30d1939SAndy Fiddaman	nameref arr=$1
514*b30d1939SAndy Fiddaman	arr[34]+=( float val=1.1 )
515*b30d1939SAndy Fiddaman}
516*b30d1939SAndy Fiddamancompound -a rootcpv
517*b30d1939SAndy Fiddamannameref mycpv=rootcpv[4][8][16][32][64]
518*b30d1939SAndy Fiddamancompound -a mycpv.myindexedcompoundarray
519*b30d1939SAndy Fiddamanadd_compound mycpv.myindexedcompoundarray
520*b30d1939SAndy Fiddaman(( mycpv.myindexedcompoundarray[34].val == 1.1 )) ||  err_exit 'nameref scoping error'
521*b30d1939SAndy Fiddaman
522*b30d1939SAndy Fiddamanfunction add_file_to_tree
523*b30d1939SAndy Fiddaman{
524*b30d1939SAndy Fiddaman	nameref node=$1
525*b30d1939SAndy Fiddaman	compound -A node.elements
526*b30d1939SAndy Fiddaman	node.elements[/]=(filepath=foobar)
527*b30d1939SAndy Fiddaman}
528*b30d1939SAndy Fiddamanfunction main
529*b30d1939SAndy Fiddaman{
530*b30d1939SAndy Fiddaman	compound filetree
531*b30d1939SAndy Fiddaman	add_file_to_tree filetree
532*b30d1939SAndy Fiddaman}
533*b30d1939SAndy Fiddamanmain 2> /dev/null
534*b30d1939SAndy Fiddaman[[ $? == 0 ]] || err_exit 'nameref binding to calling function compound variable failed'
535*b30d1939SAndy Fiddaman
536*b30d1939SAndy Fiddamanunset l
537*b30d1939SAndy Fiddamantypeset -a -C l
538*b30d1939SAndy Fiddamanprintf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l[4][6]
539*b30d1939SAndy Fiddamanexp=$(print -v l)
540*b30d1939SAndy Fiddamanunset l
541*b30d1939SAndy Fiddamantypeset -a -C l
542*b30d1939SAndy Fiddamannameref l4=l[4]
543*b30d1939SAndy Fiddamanprintf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4[6]
544*b30d1939SAndy Fiddaman[[ $(print -v l) == "$exp" ]] || err_exit  'nameref l4=l[4] not working'
545*b30d1939SAndy Fiddamanunset l
546*b30d1939SAndy Fiddamantypeset -a -C l
547*b30d1939SAndy Fiddamannameref l46=l[4][6]
548*b30d1939SAndy Fiddamanprintf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l46
549*b30d1939SAndy Fiddaman[[ $(print -v l) == "$exp" ]] || err_exit  'nameref l46=l[4][6] not working'
550*b30d1939SAndy Fiddaman
551*b30d1939SAndy Fiddamanexp=$'(\n\t[4]=(\n\t\ttypeset -a ar=(\n\t\t\t1\n\t\t\t2\n\t\t)\n\t\tb=1\n\t)\n)'
552*b30d1939SAndy Fiddamanunset l
553*b30d1939SAndy Fiddamantypeset +n l4
554*b30d1939SAndy Fiddamantypeset -a -C l
555*b30d1939SAndy Fiddamannameref l4=l[4]
556*b30d1939SAndy Fiddamanprintf "( typeset -a ar=( 1\n2\n) b=1 )\n" | read -C l4
557*b30d1939SAndy Fiddaman[[ $(print -v l) == "$exp" ]] || err_exit  'nameref l4=l[4] not working with indexed array read'
558*b30d1939SAndy Fiddaman
559*b30d1939SAndy Fiddamanunset l
560*b30d1939SAndy Fiddamantypeset +n l4
561*b30d1939SAndy Fiddamantypeset -A -C l
562*b30d1939SAndy Fiddamannameref l4=l[4]
563*b30d1939SAndy Fiddamanprintf "( typeset -a ar=( 1\n2\n) b=1 )\n" | read -C l4
564*b30d1939SAndy Fiddaman[[ $(print -v l) == "$exp" ]] || err_exit  'nameref l4=l[4] not working with associative array read'
565*b30d1939SAndy Fiddaman
566*b30d1939SAndy Fiddamanexp=$'(\n\t[9]=(\n\t\tfish=4\n\t)\n)'
567*b30d1939SAndy Fiddamanfunction add_eval
568*b30d1939SAndy Fiddaman{
569*b30d1939SAndy Fiddaman	nameref pos=$1
570*b30d1939SAndy Fiddaman	source /dev/stdin <<<"$2"
571*b30d1939SAndy Fiddaman	typeset -m pos=addvar
572*b30d1939SAndy Fiddaman}
573*b30d1939SAndy Fiddamanfunction do_local_plain
574*b30d1939SAndy Fiddaman{
575*b30d1939SAndy Fiddaman	compound -A local_tree
576*b30d1939SAndy Fiddaman	add_eval local_tree[9].fish "typeset -i addvar=4"
577*b30d1939SAndy Fiddaman	[[ $(print -v local_tree) == "$exp" ]] || err_exit 'do_local_plain failed'
578*b30d1939SAndy Fiddaman}
579*b30d1939SAndy Fiddamanfunction do_global_throughnameref
580*b30d1939SAndy Fiddaman{
581*b30d1939SAndy Fiddaman	nameref tr=global_tree
582*b30d1939SAndy Fiddaman	add_eval tr[9].fish "typeset -i addvar=4"
583*b30d1939SAndy Fiddaman	[[ $(print -v tr) == "$exp" ]] || err_exit 'do_global_throughnameref failed'
584*b30d1939SAndy Fiddaman}
585*b30d1939SAndy Fiddamanfunction do_local_throughnameref
586*b30d1939SAndy Fiddaman{
587*b30d1939SAndy Fiddaman	compound -A local_tree
588*b30d1939SAndy Fiddaman	nameref tr=local_tree
589*b30d1939SAndy Fiddaman	add_eval tr[9].fish "typeset -i addvar=4"
590*b30d1939SAndy Fiddaman	[[ $(print -v tr) == "$exp" ]] || err_exit 'do_local_throughnameref failed'
591*b30d1939SAndy Fiddaman}
592*b30d1939SAndy Fiddamancompound -A global_tree
593*b30d1939SAndy Fiddamando_global_throughnameref
594*b30d1939SAndy Fiddamando_local_throughnameref
595*b30d1939SAndy Fiddamando_local_plain
596*b30d1939SAndy Fiddaman
597*b30d1939SAndy Fiddamanunset ar
598*b30d1939SAndy Fiddamancompound -a ar
599*b30d1939SAndy Fiddamanfunction read_c
600*b30d1939SAndy Fiddaman{
601*b30d1939SAndy Fiddaman	nameref v=$1
602*b30d1939SAndy Fiddaman	read -C v
603*b30d1939SAndy Fiddaman}
604*b30d1939SAndy Fiddamanprint "( typeset -i x=36 ) " | read_c ar[5][9][2]
605*b30d1939SAndy Fiddamanexp=$'(\n\t[5]=(\n\t\t[9]=(\n\t\t\t[2]=(\n\t\t\t\ttypeset -i x=36\n\t\t\t)\n\t\t)\n\t)\n)'
606*b30d1939SAndy Fiddaman[[ $(print -v ar) == "$exp" ]] || err_exit 'read into nameref of global array instance from within a function fails'
607*b30d1939SAndy Fiddaman
608*b30d1939SAndy Fiddamanfunction read_c
609*b30d1939SAndy Fiddaman{
610*b30d1939SAndy Fiddaman	nameref v=$1
611*b30d1939SAndy Fiddaman	read -C v
612*b30d1939SAndy Fiddaman}
613*b30d1939SAndy Fiddamanfunction main
614*b30d1939SAndy Fiddaman{
615*b30d1939SAndy Fiddaman	compound -a ar
616*b30d1939SAndy Fiddaman	nameref nar=ar
617*b30d1939SAndy Fiddaman	print "( typeset -i x=36 ) " | read_c nar[5][9][2]
618*b30d1939SAndy Fiddaman	exp=$'(\n\t[5]=(\n\t\t[9]=(\n\t\t\t[2]=(\n\t\t\t\ttypeset -i x=36\n\t\t\t)\n\t\t)\n\t)\n)'
619*b30d1939SAndy Fiddaman	[[ $(print -v nar) == "$exp" ]] || err_exit 'read from a nameref variable from calling scope fails'
620*b30d1939SAndy Fiddaman}
621*b30d1939SAndy Fiddamanmain
622*b30d1939SAndy Fiddaman
623*b30d1939SAndy Fiddamanfunction rf2
624*b30d1939SAndy Fiddaman{
625*b30d1939SAndy Fiddaman	nameref val=$1
626*b30d1939SAndy Fiddaman	read -C val
627*b30d1939SAndy Fiddaman}
628*b30d1939SAndy Fiddamanfunction rf
629*b30d1939SAndy Fiddaman{
630*b30d1939SAndy Fiddaman	nameref val=$1
631*b30d1939SAndy Fiddaman	rf2 val
632*b30d1939SAndy Fiddaman}
633*b30d1939SAndy Fiddamanfunction main
634*b30d1939SAndy Fiddaman{
635*b30d1939SAndy Fiddaman	compound c
636*b30d1939SAndy Fiddaman	typeset -A -C c.l
637*b30d1939SAndy Fiddaman	nameref l4=c.l[4]
638*b30d1939SAndy Fiddaman	printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | rf l4
639*b30d1939SAndy Fiddaman	exp=$'(\n\ttypeset -C -A l=(\n\t\t[4]=(\n\t\t\ttypeset -a ar=(\n\t\t\t\t1\n\t\t\t\t2\n\t\t\t\t3\n\t\t\t)\n\t\t\tb=1\n\t\t)\n\t)\n)'
640*b30d1939SAndy Fiddaman	[[ $(print -v c) == "$exp" ]] || err_exit 'read -C with nameref to array element fails'
641*b30d1939SAndy Fiddaman}
642*b30d1939SAndy Fiddamanmain
643*b30d1939SAndy Fiddaman
644*b30d1939SAndy Fiddaman# bug reported by ek
645*b30d1939SAndy Fiddamancfg=( alarms=(type=3))
646*b30d1939SAndy Fiddamanfunction a
647*b30d1939SAndy Fiddaman{
648*b30d1939SAndy Fiddaman	typeset -n y=$1
649*b30d1939SAndy Fiddaman	print -- ${y.type}
650*b30d1939SAndy Fiddaman}
651*b30d1939SAndy Fiddamanfunction b
652*b30d1939SAndy Fiddaman{
653*b30d1939SAndy Fiddaman    a $1
654*b30d1939SAndy Fiddaman}
655*b30d1939SAndy Fiddaman[[  $(a cfg.alarms) == 3 ]] || err_exit  "nameref scoping error in function"
656*b30d1939SAndy Fiddaman[[  $(b cfg.alarms) == 3 ]] || err_exit  "nameref scoping error in nested function"
657*b30d1939SAndy Fiddaman
658*b30d1939SAndy Fiddamanfunction yy
659*b30d1939SAndy Fiddaman{
660*b30d1939SAndy Fiddaman	nameref n=$1
661*b30d1939SAndy Fiddaman	n=( z=4 )
662*b30d1939SAndy Fiddaman}
663*b30d1939SAndy Fiddamanyy foo
664*b30d1939SAndy Fiddamanunset foo
665*b30d1939SAndy Fiddaman[[ $foo ]] && err_exit 'unset after creating via nameref in function not working'
666*b30d1939SAndy Fiddaman
667*b30d1939SAndy Fiddamanunset arr
668*b30d1939SAndy Fiddamantypeset -a arr=( ( 1 2 3 ) ( 4 5 6 ) ( 7 8 9 ))
669*b30d1939SAndy Fiddamantypeset -n ref=arr[1]
670*b30d1939SAndy Fiddaman[[ $ref == 4 ]] || err_exit '$ref should be 4'
671*b30d1939SAndy Fiddaman[[ ${ref[@]} == '4 5 6' ]] || err_exit '${ref[@]} should be "4 5 6"'
672*b30d1939SAndy Fiddaman[[ $ref == "${arr[1]}" ]] || err_exit '$ref shuld be ${arr[1]}'
673*b30d1939SAndy Fiddaman[[ ${ref[@]} == "${arr[1][@]}" ]] || err_exit '${ref[@]} should be ${arr[1][@]}'
674*b30d1939SAndy Fiddaman
675*b30d1939SAndy Fiddamanfunction fun2
676*b30d1939SAndy Fiddaman{
677*b30d1939SAndy Fiddaman	nameref var=$1.foo
678*b30d1939SAndy Fiddaman	var=$2
679*b30d1939SAndy Fiddaman}
680*b30d1939SAndy Fiddamanfunction fun1
681*b30d1939SAndy Fiddaman{
682*b30d1939SAndy Fiddaman	xxx=$1
683*b30d1939SAndy Fiddaman	fun2 $xxx bam
684*b30d1939SAndy Fiddaman}
685*b30d1939SAndy Fiddamanargs=(bar=yes)
686*b30d1939SAndy Fiddamanfun1 args
687*b30d1939SAndy Fiddaman[[ $args == *foo=bam* ]] || err_exit 'nameref does not bind to correct scope'
688*b30d1939SAndy Fiddaman
689*b30d1939SAndy Fiddamantypeset +n ref
690*b30d1939SAndy Fiddamanunset ref ar
691*b30d1939SAndy Fiddamantypeset -a arr=( 1 2 3 )
692*b30d1939SAndy Fiddamantypeset -n ref='arr[2]'
693*b30d1939SAndy Fiddaman[[ $(typeset -p ref) == *'arr[2]'* ]] || err_exit 'typeset -p ref when ref is a reference to an index array element is wrong'
694*b30d1939SAndy Fiddaman
695*b30d1939SAndy Fiddaman$SHELL  2> /dev/null -c 'function x { nameref lv=gg ; compound -A lv.c=( [4]=( x=1 )) ; } ; compound gg ; x' || err_exit 'compound array assignment with nameref in a function failed'
696*b30d1939SAndy Fiddaman
697*b30d1939SAndy Fiddamanexit $((Errors<125?Errors:125))
698