Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCHv2: the ::= fix in 54674 was incomplete
% foo=xxx; () { echo ${2::=$foo} } yyy
yyy
We get the argv parameter returned when asking for "2" so use getvalue()
to get a vbuf with the proper start/end set instead of making up bogus
values.
Also fixes the case where name has a subscript (range), in that case the
given subscript range will be re-evaluated after the assignment is done,
which may give values that weren't part of the assignment.
---
> The final typeset -u arr test was to check if the bracks argument should be 0 or 1,
> and it should definitely be 0.
This was me ending up very confused because arr wasn't declared with
typeset in the test, so the typeset -u arr test declared a new (non-array)
parameter which caused me to think everything was going wrong. In fact
bracks needs to be 1, or parameter flags aren't applied when there's a
subscript. That said,
it's a little unclear to me what you would expect in this case
% typeset -a normalarray=( a b c d e )
% print ${(A)normalarray[2,4]::=o}
o e
vs what you'd expect in the this one
% typeset -a duplicates=(1 2 1 1 2 3)
% print ${(A)uniquearr::=$duplicates}
1 2 3
% print ${(A)uniquearr[1,2]::=$duplicates}
1 2
But I don't think there's anything that's more reasonable than what happens
now, eg that we do the assignment with the given subscripts, and then stuff
happens, then we reinterpret the subscripts and print whatever we get from
that.
Any strong opinions?
(I assume in practice nobody will be using this syntax to change the length
of an array and expect something sensible to come out of it). I'll also
note that as long as you use a subscript that gives you a scalar and you
assign that scalar, everything still works as expected:
% foo='bar[2]'
% bar=(one two three)
% echo ${(P)foo::=hi}
hi
% echo $bar
one hi three
but if bar is a scalar (I also expect this, but maybe others would not?):
% foo='bar[2]'
% bar="abcde"
% echo ${(P)foo::=hi}
h
% echo $bar
ahicde
Src/subst.c | 26 +++++++++++++++++++-------
Test/D04parameter.ztst | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/Src/subst.c b/Src/subst.c
index f7e7a835ef..9e846afa5c 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3311,8 +3311,14 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
aval = paramvalarr(pm->gsu.h->getfn(pm), hkeys|hvals);
} else {
Param pm = setaparam(idbeg, a);
- if (pm)
- aval = pm->gsu.a->getfn(pm);
+ if (pm) {
+ struct value vbuf = { 0 };
+ char *p = idbeg;
+ Value v = getvalue(&vbuf, &p, 1);
+ if (v) {
+ aval = getarrvalue(v);
+ }
+ }
}
isarr = 1;
arrasg = 0;
@@ -3320,11 +3326,17 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
untokenize(val);
Param pm = setsparam(idbeg, ztrdup(val));
if (pm) {
- struct value vbuf = { 0 };
- vbuf.pm = pm;
- vbuf.end = -1;
- vbuf.valflags = VALFLAG_SUBST;
- val = getstrvalue(&vbuf);
+ /* this check isn't needed for correctness, but array values
+ * aren't affected by SUBST flags anyway */
+ if ((PM_TYPE(pm->node.flags) & (PM_HASHED|PM_ARRAY)) == 0) {
+ struct value vbuf = { 0 };
+ char *p = idbeg;
+ Value v = getvalue(&vbuf, &p, 1);
+ if (v) {
+ v->valflags = VALFLAG_SUBST;
+ val = ztrdup(getstrvalue(v));
+ }
+ }
}
}
*idend = sav;
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 97577fd4ee..d6e0044eff 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -84,16 +84,55 @@
typeset -Z3 zerothree
print ${zerothree::=15}
+ zerothree=
+ print ${zerothree[1]::=2} $zerothree[1] $zerothree
+ zerothree=
+ print ${zerothree[1,2]::=34} $zerothree[1,2] $zerothree
+ zerothree=
+ print ${zerothree[2,3]::=7} $zerothree[2,3] $zerothree
typeset -E3 ethree
five=5
print ${ethree::=five}
typeset -a -U uniquearr
typeset -a duplicates=(1 2 1 1 2 3)
print ${(A)uniquearr::=$duplicates}
+ print ${(A)uniquearr[1,2]::=$duplicates}
+ typeset -a normalarray=( a b c d e )
+ print ${(A)normalarray[2,4]::=o}
+ typeset -u upper=aaaaa
+ print ${upper[2,3]::=hi} $upper $upper[2,3]
+ print ${(A)upper::=big} $upper ${(t)upper}
0:::= respects expansion flags
>015
+>0 0 002
+>03 03 034
+>07 07 007
>5.00e+00
>1 2 3
+>1 2
+>o e
+>HI AHIAA HI
+>big big array-local
+
+ local foo=xxx
+ () { echo ${2::=$foo} ${3::=$foo} ${4::=$foo}; echo $2 } yyy
+ () { echo ${11::=$foo}; echo $11 } yyy blah
+0:::= doesn't do weird things with positional arguments
+>xxx xxx xxx
+>xxx
+>xxx
+>xxx
+
+ local five=5 arr=( a b )
+ print -rl - ${arr[2]::=$five}
+ () { print -rl - ${1::=$2} } x y
+ () { print -rl - ${1::=$five} ${2::=$five} ${9::=$five} } x y
+0:regression: ::= with multiple assignments
+>5
+>y
+>5
+>5
+>5
unset array
print ${#${(A)=array=word}}
--
2.38.1
Messages sorted by:
Reverse Date,
Date,
Thread,
Author