# Tests for named references %prep # Required in order to declare an unset hash for substitution test setopt TYPESET_TO_UNSET : ${ZTST_continue::=1} %test typeset -n ptr typeset -n 0:minimal declaration >ptr typeset -n ptr= typeset -n 0:nameref placeholder >ptr='' typeset -n ptr ptr=var typeset -n 0:assign nameref placeholder >ptr=var unset ptr typeset -n ptr typeset -n ptr=var typeset -n 0:assign placeholder with new typeset >ptr=var typeset -n ptr1 typeset -n ptr2=ptr1 typeset -n 0:chain ending in placeholder >ptr1 >ptr2=ptr1 typeset ptr=var typeset -n ptr typeset -n 0:convert scalar to nameref >ptr=var typeset -n ptr=var typeset +n ptr typeset -p ptr 0:remove nameref attribute >typeset ptr=var typeset -n ptr typeset -t ptr typeset -p ptr 0:change type of a placeholder F:Other type changes are fatal errors, should this also be? >typeset -n ptr='' *?*ptr: can't change type of a named reference typeset -n ptr=var typeset -t ptr typeset -p ptr var 0:change type of referenced var >typeset -n ptr=var >typeset -t var typeset -n ptr=var[2] typeset -t ptr 1:change type of referenced array element *?*var\[2\]: can't change type via subscript reference typeset -n ptr[1]=var 1:illegal nameref name *?*reference variable cannot be an array typeset var=value typeset -n ptr=var print $ptr 0:basic nameref expansion, no braces >value typeset var=value typeset -n ptr=var print ${ptr} 0:basic nameref expansion, braces >value typeset var=(val1 val2) typeset -n ptr=var print $ptr 0:nameref array expansion >val1 val2 typeset -A var=(val1 val2) typeset -n ptr=var print ${(kv)ptr} 0:nameref hash expansion >val1 val2 typeset -n ptr=var typeset var=value typeset -p ptr var ptr=newvalue typeset -p ptr var 0:assign existing scalar via nameref >typeset -n ptr=var >typeset var=value >typeset -n ptr=var >typeset var=newvalue typeset -n ptr=var typeset var=value unset ptr typeset -p var 0:unset via nameref typeset -n ptr=var typeset var=value unset -n ptr typeset -p var ptr 0:unset of the nameref itself F:If earlier tests change, might get "no such variable" here >typeset var=value typeset -n ptr=var typeset var=value typeset -p ptr var typeset ptr=newvalue typeset -p ptr var 0:typeset existing scalar via nameref >typeset -n ptr=var >typeset var=value >typeset -n ptr=var >typeset var=newvalue typeset -n ptr=var ptr=value typeset -p var ptr 0:assign new scalar via nameref >typeset -g var=value >typeset -n ptr=var unset var typeset -n ptr=var typeset var=(val1 val2) typeset -p ptr var ptr=(new1 new2) typeset -p ptr var 0:assign existing array via nameref >typeset -n ptr=var >typeset -a var=( val1 val2 ) >typeset -n ptr=var >typeset -a var=( new1 new2 ) typeset -p ptr ptr1 ptr2 var 1:check state of paramtab ONE F:unexpected side-effects of previous tests *?*no such variable: ptr *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: var typeset -n ptr=var ptr=(val1 val2) typeset -p var ptr 0:assign new array via nameref >typeset -g -a var=( val1 val2 ) >typeset -n ptr=var unset var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset var=value typeset -p ptr1 ptr2 var print $ptr1 0:indirect nameref expansion >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset var=value >value typeset -p ptr1 ptr2 var 1:check state of paramtab TWO F:unexpected side-effects of previous tests *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: var typeset var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset ptr1=newvalue typeset -p ptr1 ptr2 var 0:typeset existing parameter indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset var=newvalue typeset var=value typeset -n ptr2=var typeset -n ptr1=ptr2 unset ptr1 typeset -p ptr1 ptr2 var 0:unset parameter indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset ptr1=newvalue typeset -p ptr1 ptr2 var 0:typeset new parameter indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset var=newvalue unset var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset var=value typeset -p ptr1 ptr2 var ptr1=newvalue typeset -p ptr1 ptr2 var 0:assign new parameter indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset var=value >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset var=newvalue typeset -p ptr1 ptr2 var 1:check state of paramtab THREE F:unexpected side-effects of previous tests *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: var typeset -a var typeset -n ptr2=var typeset -n ptr1=ptr2 typeset ptr1=(val1 val2) typeset -p ptr1 ptr2 var 0:typeset existing array indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset -a var=( val1 val2 ) typeset -n ptr2=var typeset -n ptr1=ptr2 typeset ptr1=(val1 val2) typeset -p ptr1 ptr2 var 0:typeset new array indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset -a var=( val1 val2 ) typeset -p ptr1 ptr2 1:check state of paramtab FOUR F:unexpected side-effects of previous tests *?*no such variable: ptr1 *?*no such variable: ptr2 unset var typeset -n ptr2=var typeset -n ptr1=ptr2 ptr1=(val1 val2) typeset -p ptr1 ptr2 var 0:assign new array indirectly >typeset -n ptr1=ptr2 >typeset -n ptr2=var >typeset -g -a var=( val1 val2 ) typeset -n ptr1=ptr2 typeset -n ptr2=ptr1 1:direct nameref loop not allowed *?*invalid self reference unset var typeset -gn ptr1=var typeset -p ptr1 0:global reference to unset var >typeset -g -n ptr1=var unset -n ptr1 typeset -gn ptr1 typeset -p ptr1 ptr1=ptr1 1:global direct reference >typeset -g -n ptr1 *?*invalid self reference typeset -n ptr1=ptr2 typeset -n ptr2=ptr3 typeset -n ptr3=ptr1 1:indirect nameref loop not allowed *?*invalid self reference typeset -n ptr1 ptr2 ptr1=ptr2 ptr2=ptr1 1:looping assignment not allowed *?*invalid self reference unset -n ptr2 typeset -n ptr2='path[2]' print -r -- $ptr2 0q:nameref to array element, no braces >${path[2]} unset -n ptr2 typeset -n ptr2='path[2]' print -r -- ${ptr2} 0q:nameref to array element, with braces >${path[2]} unset -n ptr1 typeset -A hash=(x MISS y HIT) typeset -n ptr1='hash[y]' print -r -- $ptr1 0:nameref to hash element, no braces >HIT unset -n ptr1 typeset -A hash=(x MISS y HIT) typeset -n ptr1='hash[y]' print -r -- ${ptr1} 0:nameref to hash element, with braces >HIT unset -n ptr2 typeset -a ary=(1 2) typeset -n ptr2='ary[2]' ptr2=TWO typeset -p ary 0:assign array element by nameref >typeset -a ary=( 1 TWO ) unset -n ptr2 typeset -n ptr2='ary[2]' ptr2=TWO typeset -p ary 0f:create array element by nameref F:ksh93 does not implement this either >typeset -a ary=( '' TWO ) unset -n ptr1 typeset -A hash=(x MISS y MISS) typeset -n ptr1='hash[y]' ptr1=HIT typeset -p hash 0:assign to hash element by nameref >typeset -A hash=( [x]=MISS [y]=HIT ) unset -n ptr1 typeset -A hash typeset -n ptr1='hash[y]' ptr1=HIT typeset -p hash 0f:create hash by element nameref F:ksh93 does not implement this either >typeset -A hash=( [y]=HIT ) unset -n ptr1 typeset -n ptr1='not[2]good' 1:invalid nameref *?*invalid variable name: not\[2\]good unset -n ptr1 unset hash typeset -A hash typeset -n ptr1='hash[y]' print ${ptr1::=HIT} typeset -p ptr1 hash 0f:create hash by element substitution >HIT >typeset -n ptr1='hash[y]' >typeset -A hash=( [y]=HIT ) unset -n ptr unset gval typeset -n ptr=gval gval=global () { local gval=local; print $ptr; typeset -p ptr gval } 0:up-reference part 1 >global >typeset -g -n ptr=gval >typeset gval=local typeset -p ptr ptr1 ptr2 val 1:check state of paramtab FIVE F:unexpected side-effects of previous tests *?*no such variable: ptr *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: val unset gval typeset -n ptr1=gval typeset gval () { typeset gval=local; ptr1=global } typeset -p ptr1 gval 0:up-reference assignment part 1 F:All tests run inside a function, so "typeset gval" creates a local; F:if that were omitted, ptr1= assignment would create a true global F:and the output below would change to "typeset -g gval=global" >typeset -n ptr1=gval >typeset gval=global typeset -p ptr ptr1 ptr2 val gval 1:check state of paramtab SIX F:unexpected side-effects of previous tests *?*no such variable: ptr *?*no such variable: ptr1 *?*no such variable: ptr2 *?*no such variable: val *?*no such variable: gval typeset gval=global () { typeset -n ptr=gval local gval=local print $ptr } typeset -p ptr gval 1:up-reference part 2 >global *?*no such variable: ptr >typeset gval=global typeset -n ptr=gval () { local lval=local typeset -n ptr=lval ptr=LOCAL typeset -p lval gval ptr } typeset -p ptr 0:localized namerefs hide global namerefs *?*no such variable: gval >typeset lval=LOCAL >typeset -n ptr=lval >typeset -n ptr=gval typeset -A var=(myself outside) () { typeset -n myself=var[myself] local -h var print -r -- $myself typeset -p var } 0:up-reference part 3, hidden global >outside >typeset var () { typeset notdef unset notdef () { typeset -n ptr=notdef ptr=(DEFINED) } typeset -p notdef } 0:up-reference part 4, unset local and type change >typeset -a notdef=( DEFINED ) () { typeset -n ptr1=ptr2 typeset -n ptr2 typeset -p ptr1 ptr2 typeset val=LOCAL () { ptr1=val typeset -n printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" } typeset -p ptr1 ptr2 } typeset -p ptr2 1:up-reference part 5, stacked namerefs, end not in scope F:What is the correct behavior for the scope of ptr1? >typeset -n ptr1=ptr2 >typeset -n ptr2 >ptr1=ptr2 >ptr2=val >ptr1=LOCAL >ptr2=LOCAL >typeset -n ptr1=ptr2 >typeset -n ptr2=val *?*no such variable: ptr2 typeset ptr2 () { typeset -n ptr1=ptr2 typeset -n ptr2 typeset -p ptr1 ptr2 typeset val=LOCAL () { ptr1=val typeset -n printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2" } typeset -p ptr1 ptr2 } typeset -p ptr2 0:up-reference part 6, stacked namerefs, end is in scope F:Same test, should part 5 output look like this? >typeset -n ptr1=ptr2 >typeset -n ptr2 >ptr1=ptr2 >ptr2 >ptr1=val >ptr2= >typeset -n ptr1=ptr2 >typeset -n ptr2='' >typeset ptr2=val if zmodload zsh/parameter; then () { zmodload -u zsh/parameter typeset -n myself=parameters[myself] local -h parameters print -r -- $myself typeset -p parameters } else ZTST_skip='Cannot zmodload zsh/parameter, skipping autoload test' fi 0:up-reference part 3, autoloading with hidden special >nameref-local-nameref-local >typeset parameters typeset ptr2=var2 typeset var2=GLOBAL () { typeset -n ptr1=ptr2 typeset ptr2=var1 typeset var1=VAR1 typeset var2=VAR2 print -r -- ${(P)ptr1} } 0: >VAR2 ary=(one two three four) typeset -n ptr=ary print -r ${(j.:.)ptr//o/0} 0:expansion flags and string replacement >0ne:tw0:three:f0ur var=value typeset -n ptr=var myscalar=ptr echo ${(P)myscalar} 0:named references with (P), as ${(P)name_of_nameref} >value var=value myscalar=var typeset -n ptr=myscalar echo ${(P)ptr} 0:named references with (P), as ${(P)nameref} >value ary=( 'bry[1]' 'bry[2]' ) bry=( lorem ipsum ) typeset -n ptr='ary[2]' print -r -- ${ptr} print -r -- ${(P)ptr} 0:named references with (P), array element to array element >bry[2] >ipsum unset -n ref unset var typeset -n ref=var typeset var=GLOBAL () { typeset -n ref=$1 print -r $ref ref=RESET typeset -p ref var } ref typeset -p ref var 0:local reference points to same-name global reference, part 1 >GLOBAL >typeset -n ref=ref >typeset -g var=RESET >typeset -n ref=var >typeset var=RESET unset -n ref unset var typeset -n ref=var () { typeset -n ref=$1 print -r $ref ref=RESET typeset -p ref var } ref typeset -p ref var 0:local reference points to same-name global reference, part 2 > >typeset -n ref=ref >typeset -g var=RESET >typeset -n ref=var >typeset -g var=RESET unset -n ref unset one typeset -n ref typeset one=ONE for ref in one ref two; do print -r $ref; done 1:for-loop variable is a reference, part 1 >ONE *?*ref: invalid self reference unset -n ref unset one typeset -n ref () { typeset one=ONE for ref in one ref two; do print -r ${(t)ref}; done } 1:for-loop variable is a reference, part 2 >scalar-local *?*ref: invalid self reference unset -n ref unset one var typeset -n ref=var () { typeset one=ONE typeset -n ref=ref for ref in one ref two; do typeset -p ref print -r $ref done typeset -p ref } typeset -p ref 0:for-loop variable is a reference, part 3 >typeset -n ref=one >ONE >typeset -n ref=ref > >typeset -n ref=two > >typeset -n ref=two >typeset -n ref=var unset -n ref unset one typeset -n ref () { setopt localoptions warn_nested_var typeset one=ONE for ref in one two; do print -r ${(t)ref}; done typeset -n ref for ref in one two; do print -r ${(t)ref}; done } 0:for-loop variable is a reference, part 4, warnings >scalar-local > >scalar-local > *?*ref: global reference to local variable: one typeset -n ptr='ary[$(echo 2)]' typeset -a ary=(one two three) print $ptr 1:attempt deferred command substitution in subscript F:runs in `setopt noexec` so $(...) returns nothing *?*bad math expression: empty string %clean