mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-06-03 05:46:03 +02:00
665 lines
13 KiB
Plaintext
665 lines
13 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}
|
|
|
|
%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
|
|
|
|
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
|