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