mirror of
https://git.code.sf.net/p/zsh/code
synced 2026-01-26 11:14:28 +00:00
1616 lines
37 KiB
Plaintext
1616 lines
37 KiB
Plaintext
# Tests for named references
|
|
|
|
%prep
|
|
|
|
# Required in order to declare an unset hash for substitution test
|
|
setopt TYPESET_TO_UNSET
|
|
|
|
: ${ZTST_continue::=1}
|
|
|
|
# The following test allows to assess what different types of named
|
|
# references refer to during their lifetime depending on where they
|
|
# were initialized and whether they were defined with or without the
|
|
# "-u" flag.
|
|
#
|
|
# The first parameter determines whether the named references are
|
|
# defined with or without the flag "-u".
|
|
#
|
|
# The second parameter determines where the named references are
|
|
# initialized. In all cases the named references are defined at the
|
|
# start of function "g". With value "0" they are initialized at the
|
|
# same place (in the same statement). With the other values, the
|
|
# initialization is delayed until later, the greater the value and the
|
|
# later the initialization.
|
|
|
|
function e() {
|
|
local s=$0 a=($0);
|
|
f "$@";
|
|
}
|
|
|
|
function f() {
|
|
local s=$0 a=($0);
|
|
g "$@";
|
|
}
|
|
|
|
function g() {
|
|
if (($2)); then local -n $1 rs ra rs1 ra1;
|
|
else local -n $1 rs=s ra=a rs1="s[1]" ra1="a[1]"; fi;
|
|
if (($2 == 1)); then rs=s; ra=a; rs1="s[1]"; ra1="a[1]"; fi;
|
|
echo "$0:1: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
local s=$0 a=($0);
|
|
if (($2 == 2)); then rs=s; ra=a; rs1="s[1]"; ra1="a[1]"; fi;
|
|
echo "$0:2: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
h "$@";
|
|
echo "$0:3: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
}
|
|
|
|
function h() {
|
|
if (($2 == 3)); then rs=s; ra=a; rs1="s[1]"; ra1="a[1]"; fi;
|
|
echo "$0:1: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
local s=$0 a=($0);
|
|
if (($2 == 4)); then rs=s; ra=a; rs1="s[1]"; ra1="a[1]"; fi;
|
|
echo "$0:2: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
i "$@";
|
|
echo "$0:3: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
# Check that re-entering the same scope doesn't undo scope exit
|
|
k "$@"
|
|
}
|
|
|
|
function i() {
|
|
if (($2 == 5)); then rs=s; ra=a; rs1="s[1]"; ra1="a[1]"; fi;
|
|
echo "$0:1: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
local s=$0 a=($0);
|
|
if (($2 == 6)); then rs=s; ra=a; rs1="s[1]"; ra1="a[1]"; fi;
|
|
echo "$0:2: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
j "$@";
|
|
echo "$0:3: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
k "$@";
|
|
}
|
|
|
|
function j() {
|
|
echo "$0:1: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
local s=$0 a=($0);
|
|
echo "$0:2: rs=$rs - ra=$ra - rs1=$rs1 - ra1=$ra1";
|
|
}
|
|
|
|
functions -c j k
|
|
|
|
local s=T a=(T);
|
|
|
|
function f1() {
|
|
typeset var=$0;
|
|
typeset -n ref1 ref2; typeset -n ref3=ref2;
|
|
function f2() {
|
|
typeset ref2=XX;
|
|
function f3() {
|
|
typeset var=$0;
|
|
function f4() {
|
|
typeset var=$0;
|
|
ref1=var;
|
|
ref3=var; # Initializes ref2 to var
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
f4;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
function g4() {
|
|
typeset var=$0;
|
|
function g5() {
|
|
typeset var=$0;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
g5;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
g4;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
f3;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
f2;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
function h2() {
|
|
typeset var=$0;
|
|
function h3() {
|
|
typeset var=$0;
|
|
function h4() {
|
|
typeset var=$0;
|
|
function h5() {
|
|
typeset var=$0;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
h5;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
h4;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
h3;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
h2;
|
|
echo "$0: ref1=$ref1 ref2=$ref2 ref3=$ref3";
|
|
}
|
|
|
|
%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=gvar
|
|
() {
|
|
local ptr
|
|
typeset -p ptr
|
|
}
|
|
typeset -p ptr
|
|
0:Local non-reference hides outside reference
|
|
>typeset ptr
|
|
>typeset -n ptr=gvar
|
|
|
|
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 var
|
|
unset var
|
|
typeset -n ptr=var
|
|
typeset -t ptr
|
|
typeset -p ptr var
|
|
0:change type of unset referenced var
|
|
F:regression - at one time this incorrectly applied the tag to "ptr"
|
|
F:note this causes "var" to become set
|
|
>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
|
|
|
|
typeset ptr1=not-a-ref
|
|
() {
|
|
typeset -n ptr1=ptr1
|
|
() {
|
|
typeset -n ptr1=ptr1
|
|
echo $ptr1
|
|
}
|
|
}
|
|
0:regression: not a self reference (test 1)
|
|
>not-a-ref
|
|
|
|
typeset -n ptr1
|
|
typeset -n ptr2=ptr1
|
|
() {
|
|
typeset ptr2=no-a-ref
|
|
typeset -n ptr1=ptr2
|
|
}
|
|
0:regression: not a self reference (test 2)
|
|
|
|
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 name reference: 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 -h 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
|
|
>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
|
|
|
|
() {
|
|
() {
|
|
local var
|
|
typeset -nu ptr1=var
|
|
ptr1=outer && print -u2 assignment expected to fail
|
|
typeset -n ptr2=var
|
|
ptr2=inner
|
|
typeset -n
|
|
printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
|
|
}
|
|
typeset -p var
|
|
}
|
|
typeset -p var
|
|
1:up-reference part 7, upscope namerefs, end not in scope
|
|
>ptr1=var
|
|
>ptr2=var
|
|
>ptr1=
|
|
>ptr2=inner
|
|
*?*typeset*: no such variable: var
|
|
*?*typeset*: no such variable: var
|
|
|
|
typeset var
|
|
() {
|
|
() {
|
|
local var
|
|
typeset -nu ptr1=var
|
|
ptr1=outer || print -u2 assignment expected to succeed
|
|
typeset -n ptr2=var
|
|
ptr2=inner
|
|
typeset -n
|
|
printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
|
|
}
|
|
typeset -p var
|
|
}
|
|
typeset -p var
|
|
0:up-reference part 8, upscope namerefs, end in scope
|
|
>ptr1=var
|
|
>ptr2=var
|
|
>ptr1=outer
|
|
>ptr2=inner
|
|
>typeset -g var=outer
|
|
>typeset var=outer
|
|
|
|
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 9, autoloading with hidden special
|
|
>nameref-local-nameref-local
|
|
>typeset -h parameters
|
|
|
|
(
|
|
inner() { local -n var="${1:?}"; var=(alpha beta gamma); }
|
|
outer() { local -a foo=(outer); inner foo; typeset -p foo; }
|
|
foo=3 ; { outer foo } always { typeset -p foo }
|
|
)
|
|
0:up-reference part 10, assignment to enclosing scope, types match
|
|
>typeset -a foo=( alpha beta gamma )
|
|
>typeset -g foo=3
|
|
|
|
(
|
|
inner() { local -n var="${1:?}"; var=(alpha beta gamma); }
|
|
outer() { local foo=outer; inner foo; typeset -p foo; }
|
|
foo=3 ; { outer foo } always { typeset -p foo }
|
|
)
|
|
0:up-reference part 11, assignment to enclosing scope, type mismatch
|
|
>typeset -a foo=( alpha beta gamma )
|
|
>typeset -g foo=3
|
|
|
|
(
|
|
inner() { local -n var="${1:?}"; unset var; var=(alpha beta gamma); }
|
|
outer() { local foo=outer; inner foo; typeset -p foo; }
|
|
foo=3 ; { outer foo } always { typeset -p foo }
|
|
)
|
|
0:up-reference part 12, assignment to enclosing scope, unset by reference
|
|
>typeset -a foo=( alpha beta gamma )
|
|
>typeset -g foo=3
|
|
|
|
(
|
|
inner() { local "${1:?}"; local -nu var="$1"; var=(alpha beta gamma); }
|
|
outer() { local -a foo=(outer); inner foo; typeset -p foo; }
|
|
foo=3 ; { outer foo } always { typeset -p foo }
|
|
)
|
|
0:up-reference part 13, assignment to enclosing scope, skip local
|
|
>typeset -a foo=( alpha beta gamma )
|
|
>typeset -g foo=3
|
|
|
|
(
|
|
inner() { local "${1:?}"; local -nu var="$1";
|
|
typeset -g var=(alpha beta gamma); }
|
|
outer() { local -a foo=(outer); inner foo; typeset -p foo; }
|
|
foo=3 ; { outer foo } always { typeset -p foo }
|
|
)
|
|
0f:up-reference part 14, typeset -g to enclosing scope, skip local
|
|
F:typeset cannot bypass a name in the local scope, even via nameref
|
|
>typeset -a foo=( alpha beta gamma )
|
|
>typeset -g foo=3
|
|
|
|
() {
|
|
# scope with no parameters
|
|
() {
|
|
local -nu upref=$1
|
|
local var=at_upref
|
|
print -- $upref
|
|
} var
|
|
}
|
|
0:up-reference part 15, non-existent parameter in outer scope
|
|
# no output expected
|
|
>
|
|
|
|
if [[ $options[typesettounset] != on ]]; then
|
|
ZTST_skip='Ignoring zmodload bug that resets TYPESET_TO_UNSET'
|
|
setopt typesettounset
|
|
fi
|
|
0:options reloaded
|
|
F:Checking for a bug in zmodload that affects later tests
|
|
|
|
typeset ptr2=var2
|
|
typeset var2=GLOBAL
|
|
() {
|
|
typeset -n ptr1=ptr2
|
|
typeset ptr2=var1
|
|
typeset var1=VAR1
|
|
typeset var2=VAR2
|
|
print -r -- ${(P)ptr1}
|
|
}
|
|
0:Order of evaluation with ${(P)...}
|
|
>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 var1
|
|
typeset -n ref=var1
|
|
() {
|
|
typeset -n ref=var2
|
|
ref=RESET
|
|
typeset -p ref var2
|
|
}
|
|
typeset -p ref var2
|
|
0:local reference hides same-name global reference
|
|
>typeset -n ref=var2
|
|
>typeset -g var2=RESET
|
|
>typeset -n ref=var1
|
|
>typeset -g var2=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
|
|
|
|
typeset -g .K01.scalar='RW'
|
|
typeset -gA .K01.assoc=(x y)
|
|
typeset -ga .K01.array=(z)
|
|
typeset -gi .K01.integer=0
|
|
typeset -gE .K01.double=0.0
|
|
typeset -gF .K01.float=0.0
|
|
typeset -gr .K01.readonly='RO'
|
|
typeset -n gref
|
|
for gref in ARGC .K01.{scalar,assoc,array,integer,double,float,readonly}
|
|
do
|
|
{ unset gref } always { TRY_BLOCK_ERROR=0 }
|
|
done
|
|
typeset -p .K01.{scalar,assoc,array,integer,double,float,readonly}
|
|
unset .K01.{scalar,assoc,array,integer,double,float}
|
|
0:unset various types via nameref, including a readonly special
|
|
>typeset -g .K01.scalar
|
|
>typeset -g -A .K01.assoc
|
|
>typeset -g -a .K01.array
|
|
>typeset -g -i .K01.integer
|
|
>typeset -g -E .K01.double
|
|
>typeset -g -F .K01.float
|
|
>typeset -g -r .K01.readonly=RO
|
|
*?*read-only variable: ARGC
|
|
*?*read-only variable: .K01.readonly
|
|
|
|
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
|
|
>
|
|
*?*reference ref*to local variable one
|
|
|
|
unset -n ref
|
|
typeset -n ref
|
|
() {
|
|
setopt localoptions warn_nested_var
|
|
typeset inner
|
|
ref=inner
|
|
}
|
|
typeset -p ref
|
|
0:Global variable is a reference, warning
|
|
>typeset -n ref=inner
|
|
*?*reference ref*to local variable inner
|
|
|
|
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
|
|
|
|
unset -n ref
|
|
typeset -n ref=GLOBAL
|
|
() {
|
|
typeset -gn ref=RESET
|
|
}
|
|
typeset -p ref
|
|
0:reset global reference within function
|
|
>typeset -n ref=RESET
|
|
|
|
unset -n ref
|
|
typeset -rn ref=RO
|
|
typeset -p ref
|
|
(typeset -n ref=RW)
|
|
print status: $? expected: 1
|
|
typeset +r -n ref
|
|
typeset -p ref
|
|
typeset -r +n ref
|
|
typeset -p ref
|
|
(typeset -rn ref)
|
|
print status: $? expected: 1
|
|
typeset +r -n ref=RW # Assignment occurs after type change,
|
|
typeset -p ref RO # so RO=RW here. Potentially confusing.
|
|
typeset -r -n ref=RX # No type change, so referent changes ...
|
|
typeset -p ref RO # ... and previous refererent does not.
|
|
typeset +rn ref=RW # Here ref=RW, again type changed first.
|
|
typeset -p ref
|
|
0:add and remove readonly attribute with references
|
|
>typeset -rn ref=RO
|
|
*?*: ref: read-only reference
|
|
>status: 1 expected: 1
|
|
>typeset -n ref=RO
|
|
>typeset -r ref=RO
|
|
*?*: ref: read-only variable
|
|
>status: 1 expected: 1
|
|
>typeset -n ref=RO
|
|
>typeset -g RO=RW
|
|
>typeset -rn ref=RX
|
|
>typeset -g RO=RW
|
|
>typeset ref=RW
|
|
|
|
() {
|
|
typeset -n r1 r2=
|
|
typeset -p r1 r2
|
|
print -- ${(!)r1-unset}
|
|
print -- ${+r1}
|
|
typeset -p r1
|
|
}
|
|
0:unset nameref remains unset when resolved
|
|
F:relies on global TYPESET_TO_UNSET in %prep
|
|
>typeset -n r1
|
|
>typeset -n r2=''
|
|
>unset
|
|
>0
|
|
>typeset -n r1
|
|
|
|
bar=xx
|
|
typeset -n foo=bar
|
|
() {
|
|
typeset -n foo; foo=zz
|
|
foo=zz || print -u2 foo: assignment failed
|
|
typeset -p bar zz
|
|
}
|
|
# prior to workers/53676 the assignment failed
|
|
unset zz
|
|
() { typeset -n foo; foo=zz; local zz; foo=zz; typeset -p bar zz }
|
|
0:regression: local nameref may not in-scope a global parameter
|
|
F:previously this could create an infinite recursion and crash
|
|
>typeset -g bar=xx
|
|
>typeset -g zz=zz
|
|
>typeset -g bar=xx
|
|
>typeset zz=zz
|
|
|
|
typeset -nm foo=bar
|
|
1:create nameref by pattern match not allowed
|
|
*?*typeset:1: -m not allowed with -n
|
|
|
|
e -u 0
|
|
0:assignment at different scope than declaration, -u 0
|
|
>g:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>g:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>g:3: rs=f - ra=f - rs1=f - ra1=f
|
|
|
|
e '' 0
|
|
0:assignment at different scope than declaration, '' 0
|
|
>g:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>g:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>g:3: rs=f - ra=f - rs1=f - ra1=f
|
|
|
|
e -u 2
|
|
0:assignment at different scope than declaration, -u 2
|
|
>g:1: rs= - ra= - rs1= - ra1=
|
|
>g:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>g:3: rs=f - ra=f - rs1=f - ra1=f
|
|
|
|
e -u 6
|
|
0:assignment at different scope than declaration, -u 6
|
|
>g:1: rs= - ra= - rs1= - ra1=
|
|
>g:2: rs= - ra= - rs1= - ra1=
|
|
>h:1: rs= - ra= - rs1= - ra1=
|
|
>h:2: rs= - ra= - rs1= - ra1=
|
|
>i:1: rs= - ra= - rs1= - ra1=
|
|
>i:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>j:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>i:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>h:3: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:1: rs=f - ra=f - rs1=f - ra1=f
|
|
>k:2: rs=f - ra=f - rs1=f - ra1=f
|
|
>g:3: rs=f - ra=f - rs1=f - ra1=f
|
|
|
|
e '' 6
|
|
0:assignment at different scope than declaration, '' 6
|
|
>g:1: rs= - ra= - rs1= - ra1=
|
|
>g:2: rs= - ra= - rs1= - ra1=
|
|
>h:1: rs= - ra= - rs1= - ra1=
|
|
>h:2: rs= - ra= - rs1= - ra1=
|
|
>i:1: rs= - ra= - rs1= - ra1=
|
|
>i:2: rs=i - ra=i - rs1=i - ra1=i
|
|
>j:1: rs=i - ra=i - rs1=i - ra1=i
|
|
>j:2: rs=i - ra=i - rs1=i - ra1=i
|
|
>i:3: rs=i - ra=i - rs1=i - ra1=i
|
|
>k:1: rs=i - ra=i - rs1=i - ra1=i
|
|
>k:2: rs=i - ra=i - rs1=i - ra1=i
|
|
>h:3: rs=h - ra=h - rs1=h - ra1=h
|
|
>k:1: rs=h - ra=h - rs1=h - ra1=h
|
|
>k:2: rs=h - ra=h - rs1=h - ra1=h
|
|
>g:3: rs=g - ra=g - rs1=g - ra1=g
|
|
|
|
f1
|
|
0:Transitive references with scoping changes
|
|
>f4: ref1=f4 ref2=XX ref3=f4
|
|
>f3: ref1=f3 ref2=XX ref3=f3
|
|
>g5: ref1=f3 ref2=XX ref3=g4
|
|
>g4: ref1=f3 ref2=XX ref3=g4
|
|
>f3: ref1=f3 ref2=XX ref3=f3
|
|
>f2: ref1=f1 ref2=XX ref3=f1
|
|
>f1: ref1=f1 ref2=f1 ref3=f1
|
|
>h5: ref1=f1 ref2=f1 ref3=f1
|
|
>h4: ref1=f1 ref2=f1 ref3=f1
|
|
>h3: ref1=f1 ref2=f1 ref3=f1
|
|
>h2: ref1=f1 ref2=f1 ref3=f1
|
|
>f1: ref1=f1 ref2=f1 ref3=f1
|
|
|
|
#
|
|
# The following two tests are linked, do not separate
|
|
#
|
|
|
|
edgelocal() ( local -n x=$1; typeset -p x; print -r $x )
|
|
edgeupper() ( local -nu x=$1; typeset -p x; print -r $x )
|
|
for edge in argv ARGC \@ \* \# 0 1 01 \! \? - _
|
|
do
|
|
edgelocal $edge
|
|
edgelocal "$edge""[1]"
|
|
edgeupper $edge
|
|
done
|
|
0:references to builtin specials
|
|
F:Subscripting on 1 01 ! ? - should print first character but do not
|
|
>typeset -n x=argv
|
|
>argv
|
|
>typeset -n x='argv[1]'
|
|
>argv[1]
|
|
>typeset -n x=ARGC
|
|
>1
|
|
>typeset -n x='ARGC[1]'
|
|
>1
|
|
>typeset -n x=0
|
|
>edgelocal
|
|
>typeset -n x='0[1]'
|
|
>e
|
|
>typeset -n x=1
|
|
>
|
|
>typeset -n x='1[1]'
|
|
>
|
|
>typeset -n x=01
|
|
>
|
|
>typeset -n x='01[1]'
|
|
>
|
|
>typeset -n x=!
|
|
>0
|
|
>typeset -n x='![1]'
|
|
>
|
|
>typeset -un x=!
|
|
>0
|
|
>typeset -n x='?'
|
|
>0
|
|
>typeset -n x='?[1]'
|
|
>
|
|
>typeset -un x='?'
|
|
>0
|
|
>typeset -n x=-
|
|
>569X
|
|
>typeset -n x='-[1]'
|
|
>
|
|
>typeset -un x=-
|
|
>569X
|
|
>typeset -n x=_
|
|
>x
|
|
>typeset -n x='_[1]'
|
|
>x
|
|
>typeset -un x=_
|
|
>x
|
|
?edgeupper: invalid name reference: argv
|
|
?edgeupper: invalid name reference: ARGC
|
|
?edgelocal: invalid name reference: @
|
|
?edgelocal: invalid name reference: @[1]
|
|
?edgeupper: invalid name reference: @
|
|
?edgelocal: invalid name reference: *
|
|
?edgelocal: invalid name reference: *[1]
|
|
?edgeupper: invalid name reference: *
|
|
?edgelocal: invalid name reference: #
|
|
?edgelocal: invalid name reference: #[1]
|
|
?edgeupper: invalid name reference: #
|
|
?edgeupper: invalid name reference: 0
|
|
?edgeupper: invalid name reference: 1
|
|
?edgeupper: invalid name reference: 01
|
|
|
|
edgelocal \$
|
|
edgelocal '$[1]'
|
|
edgeupper \$
|
|
unfunction edgelocal edgeupper
|
|
0qf:references to $$
|
|
F:$$[1] reference should print the first digit of $$ but prints nothing
|
|
>typeset -n x='$'
|
|
>$$
|
|
>typeset -n x='\$[1]'
|
|
>$$[1]
|
|
>$$
|
|
|
|
#
|
|
# The following tests are run in interactive mode, using PS1 as an
|
|
# assignable special with side-effects. This crashed at one time.
|
|
#
|
|
|
|
# Note bypassing TYPESET_TO_UNSET here
|
|
$ZTST_testdir/../Src/zsh -fis <<<$'
|
|
typeset -n p=PS1
|
|
() {
|
|
typeset -p p
|
|
local p
|
|
typeset -p p
|
|
p=xx
|
|
typeset -p p
|
|
}
|
|
'
|
|
0:regression: assign to local that shadows global named reference
|
|
>typeset -g -n p=PS1
|
|
>typeset p=''
|
|
>typeset p=xx
|
|
*?*
|
|
|
|
# Note bypassing TYPESET_TO_UNSET here
|
|
$ZTST_testdir/../Src/zsh -fis <<<$'
|
|
() {
|
|
typeset p=PS1
|
|
typeset -n p
|
|
p=zz
|
|
}
|
|
typeset -p PS1
|
|
'
|
|
0:regression - converting a string into a named reference
|
|
>typeset PS1=zz
|
|
*?*
|
|
|
|
unset var1 var2
|
|
typeset -n ref1=var1
|
|
() {
|
|
typeset -n ref2=ref1
|
|
typeset -n ref1=var2
|
|
typeset -i ref2=42
|
|
typeset -p ref1 ref2 var1 var2
|
|
}
|
|
1:typeset reference chain to not-yet-defined variable including a hidden reference
|
|
?(anon):typeset:4: no such variable: var2
|
|
>typeset -n ref1=var2
|
|
>typeset -n ref2=ref1
|
|
>typeset -i var1=42
|
|
|
|
typeset -n ref1
|
|
typeset -n ref2=ref1
|
|
() {
|
|
typeset -n ref3=ref2
|
|
typeset ref2=foo
|
|
ref1=ref3
|
|
}
|
|
1:self reference chain including a hidden reference
|
|
?(anon):3: ref3: invalid self reference
|
|
|
|
zmodload -u zsh/random
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
typeset -n ref=SRANDOM
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
echo v=${ref/<->/integer}
|
|
zmodload -u zsh/random
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
echo v=${ref/<->/integer}
|
|
0:Referring and dereferring an autoload variable loads it (direct)
|
|
>z=SRANDOM (zsh/random)
|
|
>z=
|
|
>v=integer
|
|
>z=SRANDOM (zsh/random)
|
|
>v=integer
|
|
|
|
zmodload -u zsh/random
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
typeset -n ref=SRANDOM[1,20]
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
echo v=${ref/<->/integer}
|
|
zmodload -u zsh/random
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
echo v=${ref/<->/integer}
|
|
0:Referring and dereferring an autoload variable loads it (subscript)
|
|
>z=SRANDOM (zsh/random)
|
|
>z=
|
|
>v=integer
|
|
>z=SRANDOM (zsh/random)
|
|
>v=integer
|
|
|
|
typeset -n ref=SRANDOM
|
|
echo v=${ref/<->/integer}
|
|
zmodload -u zsh/random
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
typeset -h SRANDOM=local-variable
|
|
echo v=${ref/<->/integer}
|
|
echo NOT REACHED
|
|
1:Dereferring an autoload variable fails to load it if its hidden (direct)
|
|
>v=integer
|
|
>z=SRANDOM (zsh/random)
|
|
?(eval):6: Can't add module parameter `SRANDOM': local parameter exists
|
|
?(eval):zsh/random:6: error when adding parameter `SRANDOM'
|
|
?(eval):6: autoloading module zsh/random failed to define parameter: SRANDOM
|
|
|
|
typeset -n ref=SRANDOM[1,20]
|
|
echo v=${ref/<->/integer}
|
|
zmodload -u zsh/random
|
|
echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
|
|
typeset -h SRANDOM=local-variable
|
|
echo v=${ref/<->/integer}
|
|
echo NOT REACHED
|
|
1:Dereferring an autoload variable fails to load it if its hidden (subscript)
|
|
>v=integer
|
|
>z=SRANDOM (zsh/random)
|
|
?(eval):6: Can't add module parameter `SRANDOM': local parameter exists
|
|
?(eval):zsh/random:6: error when adding parameter `SRANDOM'
|
|
?(eval):6: autoloading module zsh/random failed to define parameter: SRANDOM
|
|
|
|
() {
|
|
typeset var1=var1
|
|
typeset var2=var2
|
|
typeset -n ref1=var1
|
|
echo "ref1=$ref1";
|
|
() {
|
|
typeset -n ref1=var2
|
|
typeset -n ref2=ref1
|
|
echo "ref1=$ref1";
|
|
echo "ref2=$ref2";
|
|
}
|
|
}
|
|
0:regression: don't follow references when computing base scope - part 1
|
|
>ref1=var1
|
|
>ref1=var2
|
|
>ref2=var2
|
|
|
|
() {
|
|
typeset var1=var1
|
|
typeset -n ref1=var1
|
|
echo ref1=$ref1;
|
|
() {
|
|
typeset var2=var2
|
|
typeset -n ref1
|
|
typeset -n ref2=ref1
|
|
ref1=var2
|
|
echo ref1=$ref1;
|
|
echo ref2=$ref2;
|
|
}
|
|
}
|
|
0:regression: don't follow references when computing base scope - part 2
|
|
>ref1=var1
|
|
>ref1=var2
|
|
>ref2=var2
|
|
|
|
typeset -n ref1
|
|
typeset -n ref2=ref1;
|
|
() {
|
|
typeset ref2=foo
|
|
ref1=ref2
|
|
}
|
|
echo reached
|
|
echo $ref1
|
|
echo NOT REACHED
|
|
1:expansion of incidental reference loop triggers error
|
|
>reached
|
|
*?*: ref1: invalid self reference
|
|
|
|
typeset -n ref1
|
|
typeset -n ref2=ref1;
|
|
() {
|
|
typeset ref2=foo
|
|
ref1=ref2
|
|
}
|
|
echo reached
|
|
ref1=foo
|
|
echo NOT REACHED
|
|
1:assignment to incidental reference loop triggers error
|
|
>reached
|
|
*?*: ref1: invalid self reference
|
|
|
|
typeset -n ref1
|
|
typeset -n ref2=ref1;
|
|
() {
|
|
typeset ref2=foo
|
|
ref1=ref2
|
|
}
|
|
echo reached
|
|
typeset -n ref3=ref1
|
|
echo NOT REACHED
|
|
1:reference to incidental reference loop triggers error
|
|
>reached
|
|
*?*: ref1: invalid self reference
|
|
|
|
typeset -A -g VAR0=(aa AA)
|
|
typeset -n -g REF0=VAR0
|
|
typeset -A -g var0=(aa AA)
|
|
typeset -A var1=(aa AA)
|
|
() {
|
|
typeset -A var2=(aa AA)
|
|
typeset -n ref0=var0 ref1=var1 ref2=var2
|
|
# Test initial association
|
|
typeset -pm VAR0 var\?
|
|
REF0=(zz ZZ); ref0=(zz ZZ); ref1=(zz ZZ); ref2=(zz ZZ);
|
|
typeset -pm VAR0 var\?
|
|
# Test change from association to string
|
|
REF0=foo; ref0=foo; ref1=foo; ref2=foo;
|
|
typeset -pm VAR0 var\?
|
|
REF0=bar; ref0=bar; ref1=bar; ref2=bar;
|
|
typeset -pm VAR0 var\?
|
|
# Test change from string to array
|
|
REF0=(aa AA); ref0=(aa AA); ref1=(aa AA); ref2=(aa AA);
|
|
typeset -pm VAR0 var\?
|
|
REF0=(zz ZZ); ref0=(zz ZZ); ref1=(zz ZZ); ref2=(zz ZZ);
|
|
typeset -pm VAR0 var\?
|
|
# Test change from array to string
|
|
REF0=foo; ref0=foo; ref1=foo; ref2=foo;
|
|
typeset -pm VAR0 var\?
|
|
}
|
|
0:type changes via assignments to references
|
|
>typeset -g -A VAR0=( [aa]=AA )
|
|
>typeset -g -A var0=( [aa]=AA )
|
|
>typeset -g -A var1=( [aa]=AA )
|
|
>typeset -A var2=( [aa]=AA )
|
|
>typeset -g -A VAR0=( [zz]=ZZ )
|
|
>typeset -g -A var0=( [zz]=ZZ )
|
|
>typeset -g -A var1=( [zz]=ZZ )
|
|
>typeset -A var2=( [zz]=ZZ )
|
|
>typeset -g VAR0=foo
|
|
>typeset -g var0=foo
|
|
>typeset -g var1=foo
|
|
>typeset var2=foo
|
|
>typeset -g VAR0=bar
|
|
>typeset -g var0=bar
|
|
>typeset -g var1=bar
|
|
>typeset var2=bar
|
|
>typeset -g -a VAR0=( aa AA )
|
|
>typeset -g -a var0=( aa AA )
|
|
>typeset -g -a var1=( aa AA )
|
|
>typeset -a var2=( aa AA )
|
|
>typeset -g -a VAR0=( zz ZZ )
|
|
>typeset -g -a var0=( zz ZZ )
|
|
>typeset -g -a var1=( zz ZZ )
|
|
>typeset -a var2=( zz ZZ )
|
|
>typeset -g VAR0=foo
|
|
>typeset -g var0=foo
|
|
>typeset -g var1=foo
|
|
>typeset var2=foo
|
|
|
|
typeset -A -g ass0=(aa AA)
|
|
typeset -A ass1=(aa AA)
|
|
typeset -a -g arr0=(aa AA)
|
|
typeset -a arr1=(aa AA)
|
|
typeset -g str0=foo
|
|
typeset str1=foo
|
|
() {
|
|
typeset -n Ass0=ass0 Ass1=ass1 Arr0=arr0 Arr1=arr1 Str0=str0 Str1=str1
|
|
typeset ass0 ass1 arr0 arr1 str0 str1
|
|
{ Ass0=foo } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ Ass1=foo } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ Arr0=foo } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ Arr1=foo } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ Str0=(x) } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ Str1=(x) } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
}
|
|
typeset -p ass0 ass1 arr0 arr1 str0 str1
|
|
0:can't change type of hidden variables via assignments to references
|
|
>1
|
|
>1
|
|
>1
|
|
>1
|
|
>1
|
|
>1
|
|
>typeset -g -A ass0=( [aa]=AA )
|
|
>typeset -A ass1=( [aa]=AA )
|
|
>typeset -g -a arr0=( aa AA )
|
|
>typeset -a arr1=( aa AA )
|
|
>typeset -g str0=foo
|
|
>typeset str1=foo
|
|
?(anon):3: can't change type of hidden variable: ass0
|
|
?(anon):4: can't change type of hidden variable: ass1
|
|
?(anon):5: can't change type of hidden variable: arr0
|
|
?(anon):6: can't change type of hidden variable: arr1
|
|
?(anon):7: can't change type of hidden variable: str0
|
|
?(anon):8: can't change type of hidden variable: str1
|
|
|
|
typeset -A ass=(aa AA)
|
|
typeset -a arr=(aa AA)
|
|
typeset -i int=42
|
|
typeset str=foo
|
|
typeset -n Ass=ass Arr=arr Int=int Str=str
|
|
{ typeset Ass=foo } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ typeset Arr=foo } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ typeset Int=(aa AA) } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
{ typeset Str=(aa AA) } always { TRY_BLOCK_ERROR=0 }; echo $?
|
|
typeset -p ass arr int str
|
|
0:type changes via plain typeset to references
|
|
F:converting from association/array to string should work here too
|
|
>1
|
|
>1
|
|
>0
|
|
>0
|
|
>typeset -A ass=( [aa]=AA )
|
|
>typeset -a arr=( aa AA )
|
|
>typeset -a int=( aa AA )
|
|
>typeset -a str=( aa AA )
|
|
?(eval):typeset:6: ass: inconsistent type for assignment
|
|
?(eval):typeset:7: arr: inconsistent type for assignment
|
|
|
|
typeset var
|
|
typeset -n ref=var
|
|
# Change type to string
|
|
unset var; typeset var=fubar; typeset ref=barfu; typeset -p var
|
|
unset var; typeset -i var=12345; typeset +i ref=barfu; typeset -p var
|
|
unset var; typeset -a var=(a A); typeset +a ref=barfu; typeset -p var
|
|
unset var; typeset -A var=(a A); typeset +A ref=barfu; typeset -p var
|
|
# Change type to integer
|
|
unset var; typeset var=fubar; typeset -i ref=56789; typeset -p var
|
|
unset var; typeset -i var=12345; typeset -i ref=56789; typeset -p var
|
|
unset var; typeset -a var=(a A); typeset -i ref=56789; typeset -p var
|
|
unset var; typeset -A var=(a A); typeset -i ref=56789; typeset -p var
|
|
# Change type to array
|
|
unset var; typeset var=fubar; typeset -a ref=(z Z); typeset -p var
|
|
unset var; typeset -i var=12345; typeset -a ref=(z Z); typeset -p var
|
|
unset var; typeset -a var=(a A); typeset -a ref=(z Z); typeset -p var
|
|
unset var; typeset -A var=(a A); typeset -a ref=(z Z); typeset -p var
|
|
# Change type to association
|
|
unset var; typeset var=fubar; typeset -A ref=(z Z); typeset -p var
|
|
unset var; typeset -i var=12345; typeset -A ref=(z Z); typeset -p var
|
|
unset var; typeset -a var=(a A); typeset -A ref=(z Z); typeset -p var
|
|
unset var; typeset -A var=(a A); typeset -A ref=(z Z); typeset -p var
|
|
0:type changes via typed typeset to references
|
|
>typeset var=barfu
|
|
>typeset var=barfu
|
|
>typeset var=barfu
|
|
>typeset var=barfu
|
|
>typeset -i var=56789
|
|
>typeset -i var=56789
|
|
>typeset -i var=56789
|
|
>typeset -i var=56789
|
|
>typeset -a var=( z Z )
|
|
>typeset -a var=( z Z )
|
|
>typeset -a var=( z Z )
|
|
>typeset -a var=( z Z )
|
|
>typeset -A var=( [z]=Z )
|
|
>typeset -A var=( [z]=Z )
|
|
>typeset -A var=( [z]=Z )
|
|
>typeset -A var=( [z]=Z )
|
|
|
|
%clean
|