1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2008 AT&T Intellectual Property # 5# and is licensed under the # 6# Common Public License, Version 1.0 # 7# by AT&T Intellectual Property # 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' 229unset -n foo bar 230typeset -A foo 231foo[x.y]=(x=3 y=4) 232nameref bar=foo[x.y] 233[[ ${bar.x} == 3 ]] || err_exit 'nameref to subscript containing . fails' 234[[ ${!bar} == 'foo[x.y]' ]] || err_exit '${!var} not correct for nameref to an array instance' 235typeset +n bar 236nameref bar=foo 237[[ ${!bar} == foo ]] || err_exit '${!var} not correct for nameref to array variable' 238$SHELL -c 'function bar { nameref x=foo[++];};typeset -A foo;bar' 2> /dev/null ||err_exit 'nameref of associative array tries to evaluate subscript' 239i=$($SHELL -c 'nameref foo=bar; bar[2]=(x=3 y=4); nameref x=foo[2].y;print -r -- $x' 2> /dev/null) 240[[ $i == 4 ]] || err_exit 'creating reference from subscripted variable whose name is a reference failed' 241[[ $($SHELL 2> /dev/null <<- '+++EOF' 242 function bar 243 { 244 nameref x=$1 245 print -r -- "$x" 246 } 247 function foo 248 { 249 typeset var=( foo=hello) 250 bar var 251 } 252 foo 253+++EOF 254) == *foo=hello* ]] || err_exit 'unable to display compound variable from name reference of local variable' 255#set -x 256for c in '=' '[' ']' '\' "'" '"' '<' '=' '(' 257do [[ $($SHELL 2> /dev/null <<- ++EOF++ 258 x;i=\\$c;typeset -A a; a[\$i]=foo;typeset -n x=a[\$i]; print "\$x" 259 ++EOF++ 260) != foo ]] && err_exit 'nameref x=[$c] '"not working for c=$c" 261done 262unset -n foo x 263unset foo x 264typeset -A foo 265nameref x=foo[xyz] 266foo[xyz]=ok 267[[ $x == ok ]] || err_exit 'nameref to unset subscript not working' 268function function2 269{ 270 nameref v=$1 271 v.x=19 v.y=20 272} 273function function1 274{ 275 typeset compound_var=() 276 function2 compound_var 277 printf "x=%d, y=%d\n" compound_var.x compound_var.y 278} 279x="$(function1)" 280[[ "$x" != 'x=19, y=20' ]] && err_exit "expected 'x=19, y=20', got '${x}'" 281typeset +n bar 282unset foo bar 283[[ $(function a 284{ 285 for i in foo bar 286 do typeset -n v=$i 287 print $v 288 done | cat 289} 290foo=1 bar=2;a) == $'1\n2' ]] 2> /dev/null || err_exit 'nameref in pipeline broken' 291function a 292{ 293 typeset -n v=vars.data._1 294 print "${v.a} ${v.b}" 295} 296vars=(data=()) 297vars.data._1.a=a.1 298vars.data._1.b=b.1 299[[ $(a) == 'a.1 b.1' ]] || err_exit 'nameref choosing wrong scope -- ' 300exit $((Errors)) 301