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