xref: /titanic_44/usr/src/lib/libshell/common/tests/nameref.sh (revision 3289e1bdec732dbdf04517907516fd0d00f6a6f8)
1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#           Copyright (c) 1982-2007 AT&T Knowledge Ventures            #
5#                      and is licensed under the                       #
6#                  Common Public License, Version 1.0                  #
7#                      by AT&T Knowledge Ventures                      #
8#                                                                      #
9#                A copy of the License is available at                 #
10#            http://www.opensource.org/licenses/cpl1.0.txt             #
11#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                  David Korn <dgk@research.att.com>                   #
18#                                                                      #
19########################################################################
20function err_exit
21{
22	print -u2 -n "\t"
23	print -u2 -r ${Command}[$1]: "${@:2}"
24	let Errors+=1
25}
26alias err_exit='err_exit $LINENO'
27
28Command=${0##*/}
29integer Errors=0
30function checkref
31{
32	nameref foo=$1 bar=$2
33	if	[[ $foo !=  $bar ]]
34	then	err_exit "foo=$foo != bar=$bar"
35	fi
36	foo=hello
37	if	[[ $foo !=  $bar ]]
38	then	err_exit "foo=$foo != bar=$bar"
39	fi
40	foo.child=child
41	if	[[ ${foo.child} !=  ${bar.child} ]]
42	then	err_exit "foo.child=${foo.child} != bar=${bar.child}"
43	fi
44}
45
46name=first
47checkref name name
48name.child=second
49checkref name name
50.foo=top
51.foo.bar=next
52checkref .foo.bar .foo.bar
53if	[[ ${.foo.bar} !=  hello ]]
54then	err_exit ".foo.bar=${.foo.bar} != hello"
55fi
56if	[[ ${.foo.bar.child} !=  child ]]
57then	err_exit ".foo.bar.child=${.foo.bar.child} != child"
58fi
59function func1
60{
61        nameref color=$1
62        func2 color
63}
64
65function func2
66{
67        nameref color=$1
68        set -s -- ${!color[@]}
69	print -r -- "$@"
70}
71
72typeset -A color
73color[apple]=red
74color[grape]=purple
75color[banana]=yellow
76if	[[ $(func1 color) != 'apple banana grape' ]]
77then	err_exit "nameref or nameref not working"
78fi
79nameref x=.foo.bar
80if	[[ ${!x} != .foo.bar ]]
81then	err_exit "${!x} not working"
82fi
83typeset +n x $(typeset +n)
84unset x
85nameref x=.foo.bar
86function x.set
87{
88	[[ ${.sh.value} ]] && print hello
89}
90if	[[ $(.foo.bar.set) != $(x.set) ]]
91then	err_exit "function references  not working"
92fi
93if	[[ $(typeset +n) != x ]]
94then	err_exit "typeset +n doesn't list names of reference variables"
95fi
96if	[[ $(typeset -n) != x=.foo.bar ]]
97then	err_exit "typeset +n doesn't list values of reference variables"
98fi
99file=/tmp/shtest$$
100typeset +n foo bar 2> /dev/null
101unset foo bar
102export bar=foo
103nameref foo=bar
104if	[[ $foo != foo ]]
105then	err_exit "value of nameref foo !=  $foo"
106fi
107trap "rm -f $file" EXIT INT
108cat > $file <<\!
109print -r -- $foo
110!
111chmod +x "$file"
112y=$( $file)
113if	[[ $y != '' ]]
114then	err_exit "reference variable not cleared"
115fi
116{
117	command nameref xx=yy
118	command nameref yy=xx
119} 2> /dev/null && err_exit "self reference not detected"
120typeset +n foo bar
121unset foo bar
122set foo
123nameref bar=$1
124foo=hello
125if	[[ $bar !=  hello ]]
126then	err_exit 'nameref of positional paramters outside of function not working'
127fi
128unset foo bar
129bar=123
130function foobar
131{
132	typeset -n foo=bar
133	typeset -n foo=bar
134}
135foobar 2> /dev/null || err_exit 'nameref not unsetting previous reference'
136(
137	nameref short=verylong
138	short=( A=a B=b )
139	if	[[ ${verylong.A} != a ]]
140	then	err_exit 'nameref short to longname compound assignment error'
141	fi
142) 2> /dev/null|| err_exit 'nameref short to longname compound assignment error'
143unset x
144if	[[	$(var1=1 var2=2
145		for i in var1 var2
146		do	nameref x=$i
147			print $x
148		done) != $'1\n2' ]]
149then	err_exit 'for loop nameref optimization error'
150fi
151if	[[	$(typeset -A var1 var2
152		var1[sub1]=1 var2[sub2]=1
153		for i in var1 var2
154		do
155		        typeset -n array=$i
156		        print ${!array[*]}
157		done) != $'sub1\nsub2' ]]
158then 	err_exit 'for loop nameref optimization test2 error'
159fi
160
161unset -n x foo bar
162if	[[ $(nameref x=foo;for x in foo bar;do print ${!x};done) != $'foo\nbar' ]]
163then	err_exit 'for loop optimization with namerefs not working'
164fi
165if	[[ $(
166	p=(x=(r=3) y=(r=4))
167	for i in x y
168	do	nameref x=p.$i
169		print ${x.r}
170	done
171) != $'3\n4' ]]
172then	err_exit 'nameref optimization error'
173fi
174[[ $(
175unset x y var
176var=(foo=bar)
177for i in y var
178do	typeset -n x=$i
179	if	[[ ${!x.@} ]]
180	then	print ok
181	fi
182	typeset +n x
183done) != ok ]] && err_exit 'invalid for loop optimization of name references'
184function setval # name value
185{
186        nameref arg=$1
187	nameref var=arg.bar
188	var=$2
189}
190foo=( integer bar=0)
191setval foo 5
192(( foo.bar == 5)) || err_exit 'nested nameref not working'
193function selfref
194{
195        typeset -n ps=$1
196        print -r -- "${ps}"
197}
198ps=(a=1 b=2)
199[[ $(selfref ps) == *a=1* ]] ||  err_exit 'local nameref cannot reference global variable of the same name'
200function subref
201{
202	typeset -n foo=$1
203	print -r -- ${foo.a}
204}
205[[ $(subref ps) == 1 ]] ||  err_exit 'local nameref cannot reference global variable child'
206
207function local
208{
209	typeset ps=(typeset -i a=3 b=4)
210	[[ $(subref ps) == 3 ]] ||  err_exit 'local nameref cannot reference caller compound variable'
211}
212local
213unset -f local
214function local
215{
216	qs=(integer  a=3; integer b=4)
217}
218local 2> /dev/null || err_exit 'function local has non-zero exit status'
219[[ ${qs.a} == 3 ]] || err_exit 'function cannot set compound global variable'
220unset fun i
221foo=(x=hi)
222function fun
223{
224        nameref i=$1
225        print -r -- "${i.x}"
226}
227i=foo
228[[ $(fun $i) == hi ]] || err_exit 'nameref for compound variable with in function name of caller fails'
229exit $((Errors))
230