1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-04-30 05:45:16 +02:00
zsh/Test/K01nameref.ztst

894 lines
18 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
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
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 -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
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 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
print $bar $zz
}
() { typeset -n foo; foo=zz; local zz; foo=zz; print $bar $zz }
0:regression: local nameref may not in-scope a global parameter
F:previously this could create an infinite recursion and crash
>xx
>xx zz
*?*foo: assignment failed
typeset -nm foo=bar
1:create nameref by pattern match not allowed
*?*typeset:1: invalid reference
#
# 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
*?*
%clean