summaryrefslogtreecommitdiff
path: root/src/cmd/ksh93/tests/nameref.sh
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/cmd/ksh93/tests/nameref.sh
downloadksh-upstream.tar.gz
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/cmd/ksh93/tests/nameref.sh')
-rwxr-xr-xsrc/cmd/ksh93/tests/nameref.sh658
1 files changed, 658 insertions, 0 deletions
diff --git a/src/cmd/ksh93/tests/nameref.sh b/src/cmd/ksh93/tests/nameref.sh
new file mode 100755
index 0000000..7eb0b21
--- /dev/null
+++ b/src/cmd/ksh93/tests/nameref.sh
@@ -0,0 +1,658 @@
+########################################################################
+# #
+# This software is part of the ast package #
+# Copyright (c) 1982-2011 AT&T Intellectual Property #
+# and is licensed under the #
+# Eclipse Public License, Version 1.0 #
+# by AT&T Intellectual Property #
+# #
+# A copy of the License is available at #
+# http://www.eclipse.org/org/documents/epl-v10.html #
+# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
+# #
+# Information and Software Systems Research #
+# AT&T Research #
+# Florham Park NJ #
+# #
+# David Korn <dgk@research.att.com> #
+# #
+########################################################################
+function err_exit
+{
+ print -u2 -n "\t"
+ print -u2 -r ${Command}[$1]: "${@:2}"
+ let Errors+=1
+}
+alias err_exit='err_exit $LINENO'
+
+Command=${0##*/}
+integer Errors=0
+
+tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
+trap "cd /; rm -rf $tmp" EXIT
+
+function checkref
+{
+ nameref foo=$1 bar=$2
+ if [[ $foo != $bar ]]
+ then err_exit "foo=$foo != bar=$bar"
+ fi
+ foo=hello
+ if [[ $foo != $bar ]]
+ then err_exit "foo=$foo != bar=$bar"
+ fi
+ foo.child=child
+ if [[ ${foo.child} != ${bar.child} ]]
+ then err_exit "foo.child=${foo.child} != bar=${bar.child}"
+ fi
+}
+
+name=first
+checkref name name
+name.child=second
+checkref name name
+.foo=top
+.foo.bar=next
+checkref .foo.bar .foo.bar
+if [[ ${.foo.bar} != hello ]]
+then err_exit ".foo.bar=${.foo.bar} != hello"
+fi
+if [[ ${.foo.bar.child} != child ]]
+then err_exit ".foo.bar.child=${.foo.bar.child} != child"
+fi
+function func1
+{
+ nameref color=$1
+ func2 color
+}
+
+function func2
+{
+ nameref color=$1
+ set -s -- ${!color[@]}
+ print -r -- "$@"
+}
+
+typeset -A color
+color[apple]=red
+color[grape]=purple
+color[banana]=yellow
+if [[ $(func1 color) != 'apple banana grape' ]]
+then err_exit "nameref or nameref not working"
+fi
+nameref x=.foo.bar
+if [[ ${!x} != .foo.bar ]]
+then err_exit "${!x} not working"
+fi
+typeset +n x $(typeset +n)
+unset x
+nameref x=.foo.bar
+function x.set
+{
+ [[ ${.sh.value} ]] && print hello
+}
+if [[ $(.foo.bar.set) != $(x.set) ]]
+then err_exit "function references not working"
+fi
+if [[ $(typeset +n) != x ]]
+then err_exit "typeset +n doesn't list names of reference variables"
+fi
+if [[ $(typeset -n) != x=.foo.bar ]]
+then err_exit "typeset +n doesn't list values of reference variables"
+fi
+file=$tmp/test
+typeset +n foo bar 2> /dev/null
+unset foo bar
+export bar=foo
+nameref foo=bar
+if [[ $foo != foo ]]
+then err_exit "value of nameref foo != $foo"
+fi
+cat > $file <<\!
+print -r -- $foo
+!
+chmod +x "$file"
+y=$( $file)
+if [[ $y != '' ]]
+then err_exit "reference variable not cleared"
+fi
+{
+ command nameref xx=yy
+ command nameref yy=xx
+} 2> /dev/null && err_exit "self reference not detected"
+typeset +n foo bar
+unset foo bar
+set foo
+nameref bar=$1
+foo=hello
+if [[ $bar != hello ]]
+then err_exit 'nameref of positional paramters outside of function not working'
+fi
+unset foo bar
+bar=123
+function foobar
+{
+ typeset -n foo=bar
+ typeset -n foo=bar
+}
+foobar 2> /dev/null || err_exit 'nameref not unsetting previous reference'
+(
+ nameref short=verylong
+ short=( A=a B=b )
+ if [[ ${verylong.A} != a ]]
+ then err_exit 'nameref short to longname compound assignment error'
+ fi
+) 2> /dev/null|| err_exit 'nameref short to longname compound assignment error'
+unset x
+if [[ $(var1=1 var2=2
+ for i in var1 var2
+ do nameref x=$i
+ print $x
+ done) != $'1\n2' ]]
+then err_exit 'for loop nameref optimization error'
+fi
+if [[ $(typeset -A var1 var2
+ var1[sub1]=1 var2[sub2]=1
+ for i in var1 var2
+ do
+ typeset -n array=$i
+ print ${!array[*]}
+ done) != $'sub1\nsub2' ]]
+then err_exit 'for loop nameref optimization test2 error'
+fi
+
+unset -n x foo bar
+if [[ $(nameref x=foo;for x in foo bar;do print ${!x};done) != $'foo\nbar' ]]
+then err_exit 'for loop optimization with namerefs not working'
+fi
+if [[ $(
+ p=(x=(r=3) y=(r=4))
+ for i in x y
+ do nameref x=p.$i
+ print ${x.r}
+ done
+) != $'3\n4' ]]
+then err_exit 'nameref optimization error'
+fi
+[[ $(
+unset x y var
+var=(foo=bar)
+for i in y var
+do typeset -n x=$i
+ if [[ ${!x.@} ]]
+ then print ok
+ fi
+ typeset +n x
+done) != ok ]] && err_exit 'invalid for loop optimization of name references'
+function setval # name value
+{
+ nameref arg=$1
+ nameref var=arg.bar
+ var=$2
+}
+foo=( integer bar=0)
+setval foo 5
+(( foo.bar == 5)) || err_exit 'nested nameref not working'
+function selfref
+{
+ typeset -n ps=$1
+ print -r -- "${ps}"
+}
+ps=(a=1 b=2)
+[[ $(selfref ps) == *a=1* ]] || err_exit 'local nameref cannot reference global variable of the same name'
+function subref
+{
+ typeset -n foo=$1
+ print -r -- ${foo.a}
+}
+[[ $(subref ps) == 1 ]] || err_exit 'local nameref cannot reference global variable child'
+
+function local
+{
+ typeset ps=(typeset -i a=3 b=4)
+ [[ $(subref ps) == 3 ]] || err_exit 'local nameref cannot reference caller compound variable'
+}
+local
+unset -f local
+function local
+{
+ qs=(integer a=3; integer b=4)
+}
+local 2> /dev/null || err_exit 'function local has non-zero exit status'
+[[ ${qs.a} == 3 ]] || err_exit 'function cannot set compound global variable'
+unset fun i
+foo=(x=hi)
+function fun
+{
+ nameref i=$1
+ print -r -- "${i.x}"
+}
+i=foo
+[[ $(fun $i) == hi ]] || err_exit 'nameref for compound variable with in function name of caller fails'
+unset -n foo bar
+typeset -A foo
+foo[x.y]=(x=3 y=4)
+nameref bar=foo[x.y]
+[[ ${bar.x} == 3 ]] || err_exit 'nameref to subscript containing . fails'
+[[ ${!bar} == 'foo[x.y]' ]] || err_exit '${!var} not correct for nameref to an array instance'
+typeset +n bar
+nameref bar=foo
+[[ ${!bar} == foo ]] || err_exit '${!var} not correct for nameref to array variable'
+$SHELL -c 'function bar { nameref x=foo[++];};typeset -A foo;bar' 2> /dev/null ||err_exit 'nameref of associative array tries to evaluate subscript'
+i=$($SHELL -c 'nameref foo=bar; bar[2]=(x=3 y=4); nameref x=foo[2].y;print -r -- $x' 2> /dev/null)
+[[ $i == 4 ]] || err_exit 'creating reference from subscripted variable whose name is a reference failed'
+[[ $($SHELL 2> /dev/null <<- '+++EOF'
+ function bar
+ {
+ nameref x=$1
+ print -r -- "$x"
+ }
+ function foo
+ {
+ typeset var=( foo=hello)
+ bar var
+ }
+ foo
++++EOF
+) == *foo=hello* ]] || err_exit 'unable to display compound variable from name reference of local variable'
+#set -x
+for c in '=' '[' ']' '\' "'" '"' '<' '=' '('
+do [[ $($SHELL 2> /dev/null <<- ++EOF++
+ i=\\$c;typeset -A a; a[\$i]=foo;typeset -n x=a[\$i]; print "\$x"
+ ++EOF++
+) != foo ]] && err_exit 'nameref x=a[$c] '"not working for c=$c"
+done
+for c in '=' '[' ']' '\' "'" '"' '<' '=' '('
+do [[ $($SHELL 2> /dev/null <<- ++EOF++
+ i=\\$c;typeset -A a; a[\$i]=foo;b=a[\$i];typeset -n x=\$b; print "\$x"
+ ++EOF++
+) != foo ]] && err_exit 'nameref x=$b with b=a[$c] '"not working for c=$c"
+done
+
+unset -n foo x
+unset foo x
+typeset -A foo
+nameref x=foo[xyz]
+foo[xyz]=ok
+[[ $x == ok ]] || err_exit 'nameref to unset subscript not working'
+function function2
+{
+ nameref v=$1
+ v.x=19 v.y=20
+}
+function function1
+{
+ typeset compound_var=()
+ function2 compound_var
+ printf "x=%d, y=%d\n" compound_var.x compound_var.y
+}
+x="$(function1)"
+[[ "$x" != 'x=19, y=20' ]] && err_exit "expected 'x=19, y=20', got '${x}'"
+typeset +n bar
+unset foo bar
+[[ $(function a
+{
+ for i in foo bar
+ do typeset -n v=$i
+ print $v
+ done | cat
+}
+foo=1 bar=2;a) == $'1\n2' ]] 2> /dev/null || err_exit 'nameref in pipeline broken'
+function a
+{
+ typeset -n v=vars.data._1
+ print "${v.a} ${v.b}"
+}
+vars=(data=())
+vars.data._1.a=a.1
+vars.data._1.b=b.1
+[[ $(a) == 'a.1 b.1' ]] || err_exit 'nameref choosing wrong scope -- '
+typeset +n bam zip foo
+unset bam zip foo
+typeset -A foo
+foo[2]=bar
+typeset -n bam=foo[2]
+typeset -n zip=bam
+[[ $zip == bar ]] || err_exit 'nameref to another nameref to array element fails'
+[[ -R zip ]] || err_exit '[[ -R zip ]] should detect that zip is a reference'
+[[ -R bam ]] || err_exit '[[ -R bam ]] should detect that bam is a reference'
+[[ -R zip ]] || err_exit '[[ -v zip ]] should detect that zip is set'
+[[ -v bam ]] || err_exit '[[ -v bam ]] should detect that bam is set'
+[[ -R 123 ]] && err_exit '[[ -R 123 ]] should detect that 123 is not a reference'
+[[ -v 123 ]] && err_exit '[[ -v 123 ]] should detect that 123 is not set'
+
+unset ref x
+typeset -n ref
+x=3
+function foobar
+{
+ typeset xxx=3
+ ref=xxx
+ return 0
+}
+foobar 2> /dev/null && err_exit 'invalid reference should cause foobar to fail'
+[[ -v ref ]] && err_exit '$ref should be unset'
+ref=x
+[[ $ref == 3 ]] || err_exit "\$ref is $ref, it should be 3"
+function foobar
+{
+ typeset fvar=()
+ typeset -n ref=fvar.foo
+ ref=ok
+ print -r $ref
+}
+[[ $(foobar) == ok ]] 2> /dev/null || err_exit 'nameref in function not creating variable in proper scope'
+function foobar
+{
+ nameref doc=docs
+ nameref bar=doc.num
+ [[ $bar == 2 ]] || err_exit 'nameref scoping error'
+}
+
+docs=(num=2)
+foobar
+
+typeset +n x y
+unset x y
+typeset -A x
+x[a]=(b=c)
+typeset -n y=x[a]
+[[ ${!y.@} == 'x[a].b' ]] || err_exit 'reference to array element not expanded with ${!y.@}'
+
+typeset +n v
+v=()
+k=a.b.c/d
+command typeset -n n=v.${k//['./']/_} 2> /dev/null || err_exit 'patterns with quotes not handled correctly with name reference assignment'
+
+typeset _n sp
+nameref sp=addrsp
+sp[14]=( size=1 )
+[[ -v sp[19] ]] && err_exit '[[ -v sp[19] ]] where sp is a nameref should not be set'
+
+function fun2
+{
+ nameref var=$1
+ var.foo=bar
+}
+
+function fun1
+{
+ compound -S container
+ fun2 container
+ [[ $container == *foo=bar* ]] || err_exit 'name references to static compound variables in parent scope not working'
+}
+fun1
+
+function fun2
+{
+ nameref var=$1
+ var.foo=bar
+}
+
+typeset -T container_t=(
+ typeset foo
+)
+
+function fun1
+{
+ container_t -S container
+ fun2 container
+ [[ $container == *foo=bar* ]] || err_exit 'name references to static type variables in parent scope not working'
+}
+fun1
+
+function fun2
+{
+ nameref var=$1
+ nameref node=var.foo
+ node=bar
+}
+function fun3
+{
+ fun2 container #2> /dev/null
+}
+compound container
+fun3
+[[ $container == *foo=bar* ]] || err_exit 'name reference to a name reference variable in a function not working'
+
+typeset -A x=( [a]=1 )
+nameref c=x[h]
+[[ -v x[h] ]] && err_exit 'creating reference to non-existant associative array element causes element to get added'
+
+unset a
+function x
+{
+ nameref a=a
+ (( $# > 0 )) && typeset -A a
+ a[a b]=${1-99} # this was cauing a syntax on the second call
+}
+x 7
+x 2> /dev/null
+[[ ${a[a b]} == 99 ]] || err_exit 'nameref not handling subscript correctly'
+
+nameref sizes=baz
+typeset -A -i sizes
+sizes[bar]=1
+[[ ${sizes[*]} == 1 ]] || err_exit 'adding -Ai attribute to name referenced variable not working'
+
+$SHELL 2> /dev/null -c 'nameref foo=bar; typeset -A foo; (( (x=foo[a])==0 ))' || err_exit 'references inside arithmetic expressions not working'
+:
+
+unset ar z
+integer -a ar
+nameref z=ar[0]
+(( z[2]=3))
+[[ ${ar[0][2]} == 3 ]] || err_exit "\${ar[0][2]} is '${ar[0][2]}' but should be 3"
+(( ar[0][2] == 3 )) || err_exit "ar[0][2] is '${ar[0][2]}' but should be 3"
+
+unset c x
+typeset +n c x
+compound c=( typeset -a x )
+nameref x=c.x
+x[4]=1
+[[ ${ typeset -p c.x ;} == *-C* ]] && err_exit 'c.x should not have -C attributes'
+
+{ $SHELL 2> /dev/null <<- \EOF
+ typeset -T xxx_t=(
+ float x=1 y=2
+ typeset name=abc
+ )
+ xxx_t x
+ nameref r=x.y
+ [[ $r == 2 ]] || exit 1
+ unset x
+ [[ ${!r} == .deleted ]] || exit 2
+EOF
+} 2> /dev/null #|| print -u2 bad
+exitval=$?
+if [[ $(kill -l $exitval) == SEGV ]]
+then print -u2 'name reference to unset type instance causes segmentation violation'
+else if((exitval))
+ then print -u2 'name reference to unset type instance not redirected to .deleted'
+ fi
+fi
+
+typeset +n nr
+unset c nr
+compound c
+compound -A c.a
+nameref nr=c.a[hello]
+[[ ${!nr} == "c.a[hello]" ]] || err_exit 'name reference nr to unset associative array instance does not expand ${!nr} correctly.'
+
+typeset +n nr
+compound -a c.b
+nameref nr=c.b[2]
+[[ ${!nr} == "c.b[2]" ]] || err_exit 'name reference nr to unset indexed array instance does not expand ${!nr} correctly.'
+
+typeset +n a b
+unset a b
+typeset -n a=ls[0] b=ls[1]
+read line << \!
+3 4
+!
+set -A ls -- $line
+[[ $a == 3 ]] || err_exit 'name reference to ls[0] when ls is not an array fails'
+
+$SHELL 2> /dev/null <<-\EOF || err_exit 'nameref to array element fails'
+ set -o errexit
+ function bf {
+ nameref treename=$1
+ nodepath="treename" ;
+ nameref x="$nodepath"
+ compound -A x.nodes
+ nameref node=treename.nodes[4]
+ node=()
+ typeset +p node.elements
+ }
+ compound c
+ bf c
+EOF
+
+function add_compound
+{
+ nameref arr=$1
+ arr[34]+=( float val=1.1 )
+}
+compound -a rootcpv
+nameref mycpv=rootcpv[4][8][16][32][64]
+compound -a mycpv.myindexedcompoundarray
+add_compound mycpv.myindexedcompoundarray
+(( mycpv.myindexedcompoundarray[34].val == 1.1 )) || err_exit 'nameref scoping error'
+
+function add_file_to_tree
+{
+ nameref node=$1
+ compound -A node.elements
+ node.elements[/]=(filepath=foobar)
+}
+function main
+{
+ compound filetree
+ add_file_to_tree filetree
+}
+main 2> /dev/null
+[[ $? == 0 ]] || err_exit 'nameref binding to calling function compound variable failed'
+
+unset l
+typeset -a -C l
+printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l[4][6]
+exp=$(print -v l)
+unset l
+typeset -a -C l
+nameref l4=l[4]
+printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4[6]
+[[ $(print -v l) == "$exp" ]] || err_exit 'nameref l4=l[4] not working'
+unset l
+typeset -a -C l
+nameref l46=l[4][6]
+printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l46
+[[ $(print -v l) == "$exp" ]] || err_exit 'nameref l46=l[4][6] not working'
+
+exp=$'(\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)'
+unset l
+typeset +n l4
+typeset -a -C l
+nameref l4=l[4]
+printf "( typeset -a ar=( 1\n2\n) b=1 )\n" | read -C l4
+[[ $(print -v l) == "$exp" ]] || err_exit 'nameref l4=l[4] not working with indexed array read'
+
+unset l
+typeset +n l4
+typeset -A -C l
+nameref l4=l[4]
+printf "( typeset -a ar=( 1\n2\n) b=1 )\n" | read -C l4
+[[ $(print -v l) == "$exp" ]] || err_exit 'nameref l4=l[4] not working with associative array read'
+
+exp=$'(\n\t[9]=(\n\t\tfish=4\n\t)\n)'
+function add_eval
+{
+ nameref pos=$1
+ source /dev/stdin <<<"$2"
+ typeset -m pos=addvar
+}
+function do_local_plain
+{
+ compound -A local_tree
+ add_eval local_tree[9].fish "typeset -i addvar=4"
+ [[ $(print -v local_tree) == "$exp" ]] || err_exit 'do_local_plain failed'
+}
+function do_global_throughnameref
+{
+ nameref tr=global_tree
+ add_eval tr[9].fish "typeset -i addvar=4"
+ [[ $(print -v tr) == "$exp" ]] || err_exit 'do_global_throughnameref failed'
+}
+function do_local_throughnameref
+{
+ compound -A local_tree
+ nameref tr=local_tree
+ add_eval tr[9].fish "typeset -i addvar=4"
+ [[ $(print -v tr) == "$exp" ]] || err_exit 'do_local_throughnameref failed'
+}
+compound -A global_tree
+do_global_throughnameref
+do_local_throughnameref
+do_local_plain
+
+unset ar
+compound -a ar
+function read_c
+{
+ nameref v=$1
+ read -C v
+}
+print "( typeset -i x=36 ) " | read_c ar[5][9][2]
+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)'
+[[ $(print -v ar) == "$exp" ]] || err_exit 'read into nameref of global array instance from within a function fails'
+
+function read_c
+{
+ nameref v=$1
+ read -C v
+}
+function main
+{
+ compound -a ar
+ nameref nar=ar
+ print "( typeset -i x=36 ) " | read_c nar[5][9][2]
+ 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)'
+ [[ $(print -v nar) == "$exp" ]] || err_exit 'read from a nameref variable from calling scope fails'
+}
+main
+
+function rf2
+{
+ nameref val=$1
+ read -C val
+}
+function rf
+{
+ nameref val=$1
+ rf2 val
+}
+function main
+{
+ compound c
+ typeset -A -C c.l
+ nameref l4=c.l[4]
+ printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | rf l4
+ 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)'
+ [[ $(print -v c) == "$exp" ]] || err_exit 'read -C with nameref to array element fails'
+}
+main
+
+# bug reported by ek
+cfg=( alarms=(type=3))
+function a
+{
+ typeset -n y=$1
+ print -- ${y.type}
+}
+function b
+{
+ a $1
+}
+[[ $(a cfg.alarms) == 3 ]] || err_exit "nameref scoping error in function"
+[[ $(b cfg.alarms) == 3 ]] || err_exit "nameref scoping error in nested function"
+
+exit $((Errors<125?Errors:125))