Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] Drop some reference specific code from typeset
- X-seq: zsh-workers 55046
- From: Philippe Altherr <philippe.altherr@xxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: [PATCH] Drop some reference specific code from typeset
- Date: Tue, 28 Jul 2026 02:37:09 +0200
- Arc-authentication-results: i=1; mx.google.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=iYUT8yIkeOJruAknr2aentOy/AAuRC3R1O43ZxoeRoU=; fh=BgAYDYpL6Ne/A5nWEMVJiHiBtrz8Imz3uf26RDwgQX4=; b=OuNMlKEp4JDmYf1AmS9N6Yru1OSbIgD36Nw1Nu+r+Pf8XydIQbNJsk7hAHaUlTBehT 7Mem7kkjyXZvpV+uGW1seJy/1Y292fxeeTETelAMV+5l5SA6/Ww0Dn/MknFe6W9r4zfD ZrAYohdXrFkKNevHqAuZL0DFlxX8BfPc77TX+gwAsHYeXT7FTUA6XVmdRmNVAGOltSVL rsx85Lz+sbzwva6RSNwG1Yny+4skBIKbPzAk9bbcmxUhcfYCHrj7kU2SLb0HAV9Yykrj 6DNUEY2ar7tzPuYl4HZ/MbsuNGjFT2aSAQN77H0q/TmC3m4vTzi9JXiC/CXzhn8itnNy lDqA==; darn=zsh.org
- Arc-seal: i=1; a=rsa-sha256; t=1785199041; cv=none; d=google.com; s=arc-20260327; b=I2mGfRoV0zUhaq2dhq1r56ukH5ebzgWkOKzDDfFThUsFW9JZIJSAGw60XCVZSQHz8E wsmx/w3+JoXEgJTCz0dDmctYC6N0nRNee7M93b3SdE3i/4nYCtDcLSlULyasXr5aOXqT BciOPg1Ov2UPiCT8UpgzVS5hT/BjFFk7TLpzimmTDQwaXfQbBdkOdKYkD9C7ixmohVhm gUc6ylbt4AVc17cEIihNFL8OVB6qJmEDcvO224XD0Xi8rRrtzSPwseFYQddyfmT0NBt8 Kh5pXBc4i2W7I1Lea8jnmcoMDvdi+La4oJUVJjLKJrQAq0WWTIQJFtR1E5HqG/ru43mz Yn7Q==
- Archived-at: <https://zsh.org/workers/55046>
- In-reply-to: <CAGdYchtY0byEXj87v68+7ajMR5oBTEnTy5FLq97E44qrDioCYg@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CAGdYchtY0byEXj87v68+7ajMR5oBTEnTy5FLq97E44qrDioCYg@mail.gmail.com>
Synced and updated patch:
diff --git a/Src/builtin.c b/Src/builtin.c
index e35d7fe2c..14ae9364c 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2104,22 +2104,22 @@ typeset_single(char *cname, char *pname, Param pm, int func,
}
tc = 1;
if (OPT_MINUS(ops,'p'))
- usepm = (on & pm->node.flags);
+ usepm = !!(on & pm->node.flags);
else if (OPT_PLUS(ops,'p'))
- usepm = (off & pm->node.flags);
+ usepm = !!(off & pm->node.flags);
else
usepm = 0;
}
else if (usepm || newspecial != NS_NONE) {
int chflags = ((off & pm->node.flags) | (on & ~pm->node.flags)) &
(PM_INTEGER|PM_EFLOAT|PM_FFLOAT|PM_HASHED|
- PM_ARRAY|PM_TIED|PM_AUTOLOAD);
+ PM_ARRAY|PM_NAMEREF|PM_TIED|PM_AUTOLOAD);
/* keep the parameter if just switching between floating types */
if ((tc = chflags && chflags != (PM_EFLOAT|PM_FFLOAT))) {
if (OPT_MINUS(ops,'p'))
- usepm = (on & pm->node.flags);
+ usepm = !!(on & pm->node.flags);
else if (OPT_PLUS(ops,'p'))
- usepm = (off & pm->node.flags);
+ usepm = !!(off & pm->node.flags);
else
usepm = 0;
}
@@ -2231,6 +2231,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
* ii. we are creating a new local parameter
*/
if (usepm) {
+ int flags = (on & PM_NAMEREF) ? ASSPM_NONAMEREF : 0;
if (OPT_MINUS(ops,'p') && on &&
!((on & pm->node.flags) || ((on & PM_LOCAL) && pm->level)))
return NULL;
@@ -2324,10 +2325,10 @@ typeset_single(char *cname, char *pname, Param pm, int func,
DPUTS(!tdp, "BUG: no join character to update");
}
if (asg->value.scalar &&
- !(pm = assignsparam(pname, ztrdup(asg->value.scalar), 0)))
+ !(pm = assignsparam(pname, ztrdup(asg->value.scalar), flags)))
return NULL;
} else if (asg->flags & ASG_ARRAY) {
- int flags = (asg->flags & ASG_KEY_VALUE) ? ASSPM_KEY_VALUE : 0;
+ flags |= (asg->flags & ASG_KEY_VALUE) ? ASSPM_KEY_VALUE : 0;
if (!(pm = assignaparam(pname, asg->value.array ?
zlinklist2array(asg->value.array, 1) :
mkarray(NULL), flags)))
@@ -2358,6 +2359,9 @@ typeset_single(char *cname, char *pname, Param pm, int func,
on |= ~off & (PM_READONLY|PM_EXPORTED) & pm->node.flags;
/* ...but turn off existing readonly so we can delete it */
pm->node.flags &= ~PM_READONLY;
+ /* Hack to force getsparam below to use the reference's own value */
+ if (off & PM_NAMEREF)
+ pm->node.flags &= ~PM_NAMEREF;
/*
* If we're just changing the type, we should keep the
* variable at the current level of localness.
@@ -2371,6 +2375,12 @@ typeset_single(char *cname, char *pname, Param pm, int func,
* implications.)
*/
if (!ASG_VALUEP(asg) && !((pm->node.flags|on) & (PM_ARRAY|PM_HASHED))) {
+ /*
+ * Relying on pname is fundamentally wrong. If the original pm was
+ * a reference, the resolved pname may refer to a hidden parameter.
+ * In that case, getsparam wrongly returns the value of the hiding
+ * parameter.
+ */
asg->value.scalar = dupstring(getsparam(pname));
asg->flags = 0;
}
@@ -3115,42 +3125,6 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
continue;
}
- if (on & PM_NAMEREF) {
- if (asg->value.scalar &&
- ((pm = (Param)paramtab->getnode(paramtab, asg->value.scalar)) &&
- (pm->node.flags & PM_NAMEREF))) {
- if (pm->node.flags & PM_SPECIAL) {
- zwarnnam(name, "%s: invalid reference", pm->node.nam);
- returnval = 1;
- continue;
- }
- }
- if (hn) {
- /* namerefs always start over fresh */
- if (((Param)hn)->level >= locallevel ||
- (!(on & PM_LOCAL) && ((Param)hn)->level < locallevel)) {
- Param oldpm = (Param)hn;
- if (!asg->value.scalar &&
- PM_TYPE(oldpm->node.flags) == PM_SCALAR &&
- oldpm->u.str)
- asg->value.scalar = dupstring(oldpm->u.str);
- /* Defer read-only error to typeset_single() */
- if (!(hn->flags & PM_READONLY)) {
- unsetparam_pm(oldpm, 0, 1);
- hn = NULL;
- }
- }
- /* Passing a NULL pm to typeset_single() makes the
- * nameref read-only before assignment, which breaks
- * typeset -rn ref=var
- * so this is special-cased to permit that action
- * like assign-at-create for other parameter types.
- */
- if (hn && !(hn->flags & PM_READONLY))
- hn = NULL;
- }
- }
-
if (!typeset_single(name, asg->name, (Param)hn,
func, on, off, roff, asg, NULL,
ops, 0))
diff --git a/Src/params.c b/Src/params.c
index 716dd66c3..1a4638b69 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3143,6 +3143,7 @@ assignsparam(char *s, char *val, int flags)
size_t lvar;
mnumber lhs, rhs;
int sstart, created = 0;
+ int scanflags = flags & ASSPM_NONAMEREF ? SCANPM_NONAMEREF : 0;
if (!isident(s)) {
zerr("not an identifier: %s", s);
@@ -3153,7 +3154,7 @@ assignsparam(char *s, char *val, int flags)
queue_signals();
if ((ss = strchr(s, '['))) {
*ss = '\0';
- if (!(v = getvalue(&vbuf, &s, 1))) {
+ if (!(v = fetchvalue(&vbuf, &s, 1, scanflags))) {
createparam(t, PM_ARRAY);
created = 1;
} else {
@@ -3174,7 +3175,7 @@ assignsparam(char *s, char *val, int flags)
*ss = '[';
v = NULL;
} else {
- if (!(v = getvalue(&vbuf, &s, 1))) {
+ if (!(v = fetchvalue(&vbuf, &s, 1, scanflags))) {
createparam(t, PM_SCALAR);
created = 1;
} else if ((((v->pm->node.flags & PM_ARRAY) &&
@@ -3192,7 +3193,7 @@ assignsparam(char *s, char *val, int flags)
v = NULL;
}
}
- if (!v && !(v = getvalue(&vbuf, &t, 1))) {
+ if (!v && !(v = fetchvalue(&vbuf, &t, 1, scanflags))) {
zsfree(val);
unqueue_signals();
/* errflag |= ERRFLAG_ERROR; */
@@ -3305,6 +3306,7 @@ assignaparam(char *s, char **val, int flags)
char *ss;
int created = 0;
int may_warn_about_nested_vars = 1;
+ int scanflags = flags & ASSPM_NONAMEREF ? SCANPM_NONAMEREF : 0;
if (!isident(s)) {
zerr("not an identifier: %s", s);
@@ -3315,7 +3317,7 @@ assignaparam(char *s, char **val, int flags)
queue_signals();
if ((ss = strchr(s, '['))) {
*ss = '\0';
- if (!(v = getvalue(&vbuf, &s, 1))) {
+ if (!(v = fetchvalue(&vbuf, &s, 1, scanflags))) {
createparam(t, PM_ARRAY);
created = 1;
} else {
@@ -3332,7 +3334,7 @@ assignaparam(char *s, char **val, int flags)
}
v = NULL;
} else {
- if (!(v = fetchvalue(&vbuf, &s, 1, SCANPM_ASSIGNING))) {
+ if (!(v = fetchvalue(&vbuf, &s, 1, scanflags | SCANPM_ASSIGNING))) {
createparam(t, PM_ARRAY);
created = 1;
} else if (v->pm->node.flags & PM_NAMEREF) {
@@ -3363,7 +3365,7 @@ assignaparam(char *s, char **val, int flags)
}
}
if (!v)
- if (!(v = fetchvalue(&vbuf, &t, 1, SCANPM_ASSIGNING))) {
+ if (!(v = fetchvalue(&vbuf, &t, 1, scanflags | SCANPM_ASSIGNING))) {
unqueue_signals();
freearray(val);
/* errflag |= ERRFLAG_ERROR; */
diff --git a/Src/zsh.h b/Src/zsh.h
index 5a989ff47..d45403e0b 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2141,7 +2141,9 @@ enum {
* This is normal for associative arrays but variant behaviour for
* normal arrays.
*/
- ASSPM_KEY_VALUE = 1 << 4
+ ASSPM_KEY_VALUE = 1 << 4,
+ /* Named references are not followed */
+ ASSPM_NONAMEREF = 1 << 5
};
/* node for named directory hash table (nameddirtab) */
diff --git a/Test/B02typeset.ztst b/Test/B02typeset.ztst
index 8b66c184f..d6e9c9d75 100644
--- a/Test/B02typeset.ztst
+++ b/Test/B02typeset.ztst
@@ -1212,6 +1212,97 @@ F:This is a bug, the non -h variable should not hide the autoload variable
>z=
>v=
+ zmodload -u zsh/random
+ () { { typeset -g -i SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -g -a SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -g -n SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
+0:Global parameter can't change type of autoloaded parameter
+>(anon):typeset: SRANDOM: can't change type of autoloaded parameter
+>(anon):typeset: SRANDOM: can't change type of autoloaded parameter
+>(anon):typeset: SRANDOM: can't change type of autoloaded parameter
+>z=SRANDOM (zsh/random)
+
+ zmodload -u zsh/random
+ () { { typeset SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -i SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -a SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -n SRANDOM 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ echo z=${(M)${(f)${ zmodload -ap}}:#*SRANDOM*}
+0:Local non -h parameter can hide autoloaded parameter
+>z=SRANDOM (zsh/random)
+
+ () { { typeset -g +i EUID 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -g -i HOME 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -g -a HOME 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ ( () { { typeset -g -n HOME 2>&1 } always { TRY_BLOCK_ERROR=0 } } )
+ typeset -p EUID HOME
+0q:Global parameter can't change type of special parameter
+>(anon):typeset: EUID: can't change type of a special parameter
+>(anon):typeset: HOME: can't change type of a special parameter
+>(anon):typeset: HOME: can't change type of a special parameter
+>(anon):typeset: HOME: can't change type of a special parameter
+>typeset -g -i10 EUID=$EUID
+>export HOME=$HOME
+
+ () { { typeset +i EUID 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -i HOME 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -a HOME 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ () { { typeset -n HOME 2>&1 } always { TRY_BLOCK_ERROR=0 } }
+ typeset -p EUID HOME
+0q:Local non -h parameter can't hide special parameter
+>(anon):typeset: EUID: can't change type of a special parameter
+>(anon):typeset: HOME: can't change type of a special parameter
+>(anon):typeset: HOME: can't change type of a special parameter
+>(anon):typeset: HOME: can't change type of a special parameter
+>typeset -g -i10 EUID=$EUID
+>export HOME=$HOME
+
+ () { typeset -h +i EUID 2>&1; typeset -p EUID }
+ () { typeset -h -i HOME 2>&1; typeset -p HOME }
+ () { typeset -h -a HOME 2>&1; typeset -p HOME }
+ () { typeset -h -n HOME 2>&1; typeset -p HOME }
+ typeset -p EUID HOME
+0q:Local -h parameter can hide special parameter
+>typeset -h EUID=''
+>typeset -ih HOME=0
+>typeset -ah HOME=( )
+>typeset -hn HOME=''
+>typeset -g -i10 EUID=$EUID
+>export HOME=$HOME
+
+ check() {
+ echo "Testing \"local $1 $2=${3}<N>\""
+ { local $1 -r $2=${3}1 2>&1 && typeset -p $2 } always { TRY_BLOCK_ERROR=0 }
+ { local -r $2=${3}2 2>&1 && typeset -p $2 } always { TRY_BLOCK_ERROR=0 }
+ { local $1 $2=${3}3 2>&1 && typeset -p $2 } always { TRY_BLOCK_ERROR=0 }
+ { local $1 -r $2=${3}4 2>&1 && typeset -p $2 } always { TRY_BLOCK_ERROR=0 }
+ { local $1 +r $2=${3}5 2>&1 && typeset -p $2 } always { TRY_BLOCK_ERROR=0 }
+ }
+ check "" str s
+ check -i int 1
+ check -n ref v
+0:Non +r parameter definition can't change/replace readonly parameter
+>Testing "local str=s<N>"
+>typeset -r str=s1
+>check:3: read-only variable: str
+>check:4: read-only variable: str
+>check:5: read-only variable: str
+>typeset str=s5
+>Testing "local -i int=1<N>"
+>typeset -ir int=11
+>check:3: read-only variable: int
+>check:4: read-only variable: int
+>check:5: read-only variable: int
+>typeset -i int=15
+>Testing "local -n ref=v<N>"
+>typeset -rn ref=v1
+>typeset -rn ref=v1
+F:"typeset -r ref=v2" succeeds because it dereferences "ref" and assigns "v1" with "v2"
+>check:local:4: ref: read-only reference
+>check:local:5: ref: read-only reference
+>typeset -n ref=v5
+
() {
typeset -F f1=nan f2=inf f3=-inf
typeset -p f1 f2 f3
diff --git a/Test/K01nameref.ztst b/Test/K01nameref.ztst
index 0e1cc9e4e..e85640e6e 100644
--- a/Test/K01nameref.ztst
+++ b/Test/K01nameref.ztst
@@ -1107,32 +1107,30 @@ F:Checking for a bug in zmodload that affects later tests
unset -n ref
typeset -rn ref=RO
typeset -p ref
- (typeset -n ref=RW)
+ (typeset -n ref=RW 2>&1 && typeset -p ref)
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 -rn ref 2>&1 && typeset -p ref)
+ print status: $? expected: 0
+ typeset +r -n ref=RW
+ typeset -p ref
+ typeset -r -n ref=RX
+ typeset -p ref
+ typeset +rn ref=RW
typeset -p ref
0:add and remove readonly attribute with references
>typeset -rn ref=RO
-*?*: ref: read-only reference
+>(eval):typeset:4: 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=RO
+>status: 0 expected: 0
+>typeset -n ref=RW
>typeset -rn ref=RX
->typeset -g RO=RW
>typeset ref=RW
() {
diff --git a/Test/V10private.ztst b/Test/V10private.ztst
index 256844be1..f3ad7b6b9 100644
--- a/Test/V10private.ztst
+++ b/Test/V10private.ztst
@@ -304,39 +304,44 @@ F:future revision will create a global with this assignment
typeset top=TOP
() {
local -P -n test=top
- print $top
+ print $test
+ test=top
+ print $test
() { print UP: $test }
}
+ print $top
0:nameref can be declared private
>TOP
+>top
>UP:
+>top
() {
typeset -a ary
local -P -n ref=ary
{
- (){
- ref=XX # Should be an error
- typeset -p ary ref
+ () {
+ ref=XX 2>&1 # Should be an error
+ echo NOT REACHED
}
} always {
TRY_BLOCK_ERROR=0
typeset -p ary ref
}
}
- typeset -p ary
+ typeset -p ary 2>&1
1:assignment to private nameref in wrong scope, part 1
+>(anon):1: ref: can't modify read-only parameter
>typeset -a ary
>typeset -hn ref=ary
-*?*ref: can't modify read-only parameter
-*?*no such variable: ary
+>(eval):typeset:14: no such variable: ary
() {
typeset -a ary
local -P -n ref=ary
{
(){
- typeset ref=XX # Should create a local
+ typeset ref=XX 2>&1 # Should create a local
typeset -p ary ref
}
} always {
@@ -344,53 +349,89 @@ F:future revision will create a global with this assignment
typeset -p ary ref
}
}
- typeset -p ary
+ typeset -p ary 2>&1
1:assignment to private nameref in wrong scope, part 2
>typeset -g -a ary
>typeset ref=XX
>typeset -a ary
>typeset -hn ref=ary
-*?*no such variable: ary
+>(eval):typeset:14: no such variable: ary
() {
+ typeset val=LOCAL
typeset -n ptr1=ptr2
private -n ptr2 # TYPESET_TO_UNSET makes this not a "placeholder"
typeset -p ptr1 ptr2
- typeset val=LOCAL
() {
- ptr1=val # Test dies here as ptr2 is private and unset
- typeset -n
- printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
+ ptr1=val 2>&1 # Test dies here as ptr2 is private
+ echo NOT REACHED
}
- typeset -p ptr1 ptr2
+ echo NOT REACHED
}
- typeset -p ptr2
+ echo NOT REACHED
1:up-reference for private namerefs, end unset and not in scope
F:See K01nameref.ztst up-reference part 5
F:Here ptr1 finds private ptr2 by scope mismatch
>typeset -n ptr1=ptr2
>typeset -hn ptr2
-?(anon):1: read-only variable: ptr2
+>(anon):1: read-only variable: ptr2
() {
+ typeset val=LOCAL
typeset -n ptr1=ptr2
private -n ptr2= # Assignment makes this a placeholder, not unset
typeset -p ptr1 ptr2
+ () {
+ ptr1=val 2>&1 # Test dies here as ptr2 is private
+ echo NOT REACHED
+ }
+ echo NOT REACHED
+ }
+ echo NOT REACHED
+1:up-reference for private namerefs, end is placeholder and not in scope
+F:See K01nameref.ztst up-reference part 5
+F:Here ptr1 finds private ptr2 by scope mismatch
+>typeset -n ptr1=ptr2
+>typeset -hn ptr2=''
+>(anon):1: ptr1: can't modify read-only parameter
+
+ () {
typeset val=LOCAL
+ typeset -n ptr1=ptr2
+ private -n ptr2=val # Assignment makes this a reference to existing val
+ typeset -p ptr1 ptr2
() {
- ptr1=val # Test dies here as ptr2 is private and uninitialized
- typeset -n
- printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
+ ptr1=val 2>&1 # Test dies here as ptr2 is private
+ echo NOT REACHED
}
+ echo NOT REACHED
+ }
+ echo NOT REACHED
+1:up-reference for private namerefs, end refers existing variable and not in scope
+F:See K01nameref.ztst up-reference part 5
+F:Here ptr1 finds private ptr2 by scope mismatch
+>typeset -n ptr1=ptr2
+>typeset -hn ptr2=val
+>(anon):1: ptr1: can't modify read-only parameter
+
+ () {
+ typeset val=LOCAL
+ typeset -n ptr1=ptr2
+ private -n ptr2=foo # Assignment makes this a reference to not-yet-defined foo
typeset -p ptr1 ptr2
+ () {
+ ptr1=val 2>&1 # Test dies here as ptr2 is private
+ echo NOT REACHED
+ }
+ echo NOT REACHED
}
- typeset -p ptr2
-1:up-reference for private namerefs, end not in scope
+ echo NOT REACHED
+1:up-reference for private namerefs, end refers not-yet-defined variable and not in scope
F:See K01nameref.ztst up-reference part 5
F:Here ptr1 finds private ptr2 by scope mismatch
>typeset -n ptr1=ptr2
->typeset -hn ptr2=''
-?(anon):1: ptr1: can't modify read-only parameter
+>typeset -hn ptr2=foo
+>(anon):1: ptr1: can't modify read-only parameter
typeset ptr2
() {
@@ -401,7 +442,7 @@ F:Here ptr1 finds private ptr2 by scope mismatch
() {
ptr1=val
typeset -n
- printf "%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
+ printf "print:%s=%s\n" ptr1 "$ptr1" ptr2 "$ptr2"
}
typeset -p ptr1 ptr2
}
@@ -413,24 +454,38 @@ F:Here ptr1 points to global ptr2 so assignment succeeds
>typeset -hn ptr2
>ptr1=ptr2
>ptr2=val
->ptr1=val
->ptr2=val
+>print:ptr1=val
+>print:ptr2=val
>typeset -n ptr1=ptr2
>typeset -hn ptr2
>typeset ptr2=val
+ () {
+ setopt localoptions errreturn
+ private -n ptr2=val
+ typeset -n ptr1=ptr2 2>&1
+ ptr1=foo
+ typeset -p ptr1 ptr2 val
+ }
+ unset val
+0:up-reference for private namerefs, end is set and in scope but private
+>typeset -n ptr1=ptr2
+>typeset -hn ptr2=val
+>typeset -g val=foo
+
() {
setopt localoptions errreturn
private -n ptr2
- typeset -n ptr1=ptr2
- echo NOT REACHED
+ typeset -n ptr1=ptr2 2>&1
+ ptr1=val
+ ptr1=foo
+ typeset -p ptr1 ptr2 val
}
- typeset -p ptr1 ptr2
-1:up-reference for private namerefs, end is in scope but private
-F:Should we allow "public" namerefs to private parameters?
-*?*ptr2: invalid reference
-*?*no such variable: ptr1
-*?*no such variable: ptr2
+ unset val
+0:up-reference for private namerefs, end is unset and in scope but private
+>typeset -n ptr1=ptr2
+>typeset -hn ptr2=val
+>typeset -g val=foo
() {
typeset ptr2=foo
@@ -438,13 +493,13 @@ F:Should we allow "public" namerefs to private parameters?
() {
setopt localoptions errreturn
private -n ptr2
- typeset -n ptr1=ptr2
- echo NOT REACHED
+ typeset -n ptr1=ptr2 2>&1
+ typeset -p ptr1 ptr2
}
}
-1:regression test for invalid reference detection
-F:Should we allow "public" namerefs to private parameters?
-*?*ptr2: invalid reference
+0:regression test for invalid reference detection
+>typeset -n ptr1=ptr2
+>typeset -hn ptr2
() {
private x=1
Messages sorted by:
Reverse Date,
Date,
Thread,
Author