Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: Cleanup isarr fields and variables
- X-seq: zsh-workers 54093
- From: Philippe Altherr <philippe.altherr@xxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: PATCH: Cleanup isarr fields and variables
- Date: Wed, 19 Nov 2025 15:25:29 +0100
- Archived-at: <https://zsh.org/workers/54093>
- List-id: <zsh-workers.zsh.org>
Here is something that took me quite some time to analyze and understand the affected code. The proposed changes are simple but their correctness is not necessarily easy to understand. Hence the long explanations below.
When Oliver suggested in
workers/54053 to replace my new field
isrefslice field with a new flag in the
flags field, I thought that I could maybe do the same with the
isarr field since its name suggests that it's a plain boolean. However, a quick look at the code showed that it's more than a boolean; it's also a set of
SCANPM flags. Confusingly, there exist
isarr variables
here and
here that are NOT sets of
SCANPM flags. Even worse, there are places where such
isarr variables are assigned to and from
isarr fields. Furthermore there are places where
isarr fields and variables are initialized with values that don't seem to match their specifications.
After much head scratching, I came to the conclusion that some code should be changed such that the various isarr fields and variables can benefit from simpler specifications. Here is how I think they should be specified and what code should be changed:
- Specification: set of SCANPM flags that also plays the role of a boolean; a non-zero value signals that the value struct designates an array or an associative array.
- Rewrite v.isarr = (PM_TYPE(v.pm->node.flags) & (PM_ARRAY|PM_HASHED))
This code is nonsensical; it assigns a PM flag to a field containing SCANPM flags. Assigning SCANPM_WANTVALS in case PM_ARRAY or PM_HASHED are set would be more correct. However, since the code is part of scanparamvals, which is only ever called with elements of associative arrays, which can only ever be scalars, the current code is in practice equivalent to v.isarr = 0.
- Rewrite v.isarr = 1
Nothing fundamentally wrong here but an equivalent and cleaner version is v.isarr = SCANPM_WANTVALS. Even cleaner is (PM_TYPE(v.pm->node.flags) & PM_HASHED) ? SCANPM_WANTVALS : SCANPM_ARRONLY. where SCANPM_ARRONLY is a SCANPM flag dedicated to signal plain arrays.
- Patch: fix-isarr-1-value-field.txt
- Specification: an output "is-array" boolean that can be set to 0 or 1 as specified here.
- Fix *isarr = SCANPM_MATCHMANY
This code signals that the result is an array. For some reason it uses a SCANPM constant while it should simply use 1 to conform to the specification of the isarr parameter.
- Patch: fix-isarr-2-multsub-parameter.txt
- Specification: an extended "is-array" boolean that can be set to one of -1, 0, 1, or 2 as specified here.
- Fix v->isarr = isarr
This code is nonsensical; it assigns the extended boolean isarr to the set of SCANPM flags v->isarr. Instead, the code should assign v->isarr with one or more SCANPM flags if isarr is non-zero and with zero otherwise. But which flags? The variable v is only passed to getindex and to getarrvalue and we know that v->pm points to an array if isarr is non-zero. If v->pm is an array then getarrvalue doesn't read v->isarr and getindex (almost) only cares about the boolean aspect of v->isarr. Given this, the best flag to initialize v->isarr seems to be SCANPM_ARRONLY whose purpose is to signal that v->pm is an array.
I say that getindex almost only cares about the boolean aspect of v->isarr because it's possible to initialize v->isarr with a non-zero value that triggers a different behavior. For example, if v->isarr is initialized with (SCANPM_MATCHKEY | SCANPM_MATCHMANY) then array=(aaa bbb); echo ${array[1,2][1][1]} prints aaa instead of just a because then this condition fails to trigger for the second subscript of ${array[1,2][1][1]}. The fact that in this case.v->isarr isn't a pure boolean looks more like a bug than a feature to me. I suspect, but I haven't tried, that it would be possible to build an example where the current code produces a bogus result because a bad set of SCANPM flags (coming from the assignment discussed below) are assigned (in the assignment discussed here) to v->isarr.
- Fix isarr = v->isarr
This code is nonsensical; it assigns the set of SCANPM flags v->isarr to the extended boolean isarr. An analysis of the code seems to indicate that the only cases that matter are whether v->isarr is non-zero and whether it includes the flag SCANPM_ISVAR_AT. If it includes that flag isarr must be set to -1. Otherwise, if v->isarr is non-zero, isarr must be set to 1 and if v->isarr is zero, isarr must be set to 0. Fixing this also removes the necessity for the constant SCANPM_ISVAR_AT to be negative. Instead, it can be defined using the next available bit.
- Patch: fix-isarr-3-paramsubst-variable.txt
I also noticed that some code doesn't initialize all the fields of the value struct. Patch: fix-isarr-5-init-all-value-fields.txt.
Finally, in order to avoid future confusion between plain/extended boolean isarr variables and the set of SCANPM flags in the isarr field of the value struct, I think that it would make sense to rename the isarr field into scanflags. However, if we do so, then we should also rename the already existing field flags into valflags, to avoid any confusion between the two flags fields. Patches: fix-isarr-6-rename-flags-field.txt and fix-isarr-7-rename-isarr-field.txt.
In case you agree with everything, you can use the patch fix-isarr-all-in-one.txt, which includes the 7 patches listed above.
Philippe
diff --git a/Src/subst.c b/Src/subst.c
index 8d730163e..1d8b1f439 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -640,7 +640,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
* our caller (if they provided for that result). */
if (a && (l > 1 || foo.list.flags & LF_ARRAY)) {
*a = r;
- *isarr = SCANPM_MATCHMANY;
+ *isarr = 1;
return 0;
}
*s = sepjoin(r, sep, 1);
diff --git a/Src/params.c b/Src/params.c
index b76fb8a6b..8e60605ef 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -649,7 +649,7 @@ scanparamvals(HashNode hn, int flags)
if (!(flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)))
return;
}
- v.isarr = (PM_TYPE(v.pm->node.flags) & (PM_ARRAY|PM_HASHED));
+ v.isarr = 0;
v.flags = 0;
v.start = 0;
v.end = -1;
@@ -2640,7 +2640,8 @@ export_param(Param pm)
#if 0 /* Requires changes elsewhere in params.c and builtin.c */
if (EMULATION(EMULATE_KSH) /* isset(KSHARRAYS) */) {
struct value v;
- v.isarr = 1;
+ v.isarr = (PM_TYPE(v.pm->node.flags) & PM_HASHED) ?
+ SCANPM_WANTVALS : SCANPM_ARRONLY;
v.flags = 0;
v.start = 0;
v.end = -1;
diff --git a/Src/zsh.h b/Src/zsh.h
index b82c35aea..7195e1535 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -744,7 +744,11 @@ struct multio {
struct value {
Param pm; /* parameter node */
char **arr; /* cache for hash turned into array */
- int isarr;
+ int isarr; /* set of SCANPM flags as well as an is-array
+ * marker. The field must be non-zero iff the
+ * value struct represents an array or an
+ * associative array. For plain arrays, use
+ * SCANPM_ARRONLY. */
int flags; /* flags defined below */
int start; /* first element of array slice, or -1 */
int end; /* 1-rel last element of array slice, or -1 */
diff --git a/Src/subst.c b/Src/subst.c
index 1d8b1f439..308a717a9 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1649,7 +1649,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* (I mean the one explicitly marked as such). The value 2
* indicates an array has come from splitting a scalar. We use
* that to override the usual rule that in double quotes we don't
- * remove empty elements (so "${(s.:):-foo::bar}" produces two
+ * remove empty elements (so "${(s.:.):-foo::bar}" produces two
* words). This seems to me to be quite the wrong thing to do,
* but it looks like code may be relying on it. So we require (@)
* as well before we keep the empty fields (look for assignments
@@ -2893,7 +2893,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
else
pm->u.str = val;
v = (Value) hcalloc(sizeof *v);
- v->isarr = isarr;
+ v->isarr = isarr ? SCANPM_ARRONLY : 0;
v->pm = pm;
v->end = -1;
if (getindex(&s, v, qt ? SCANPM_DQUOTED : 0) || s == os)
@@ -2912,7 +2912,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* here because it's already been taken account of, either
* in the subexp stuff or immediately above.
*/
- if ((isarr = v->isarr)) {
+ if ((isarr = (v->isarr & SCANPM_ISVAR_AT) ? -1 : v->isarr ? 1 : 0)) {
/*
* No way to get here with v->flags & VALFLAG_INV, so
* getvaluearr() is called by getarrvalue(); needn't test
@@ -3011,7 +3011,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* we may be OK by now --- all potential `@'s and subexpressions
* have been handled, including any [@] index which comes up
* by virtue of v->isarr being set to SCANPM_ISVAR_AT which
- * is now in isarr.
+ * is now in isarr being set to -1.
*
* However, if we are replacing multsub() with something that
* doesn't mangle arrays, we may need to delay this step until after
diff --git a/Src/zsh.h b/Src/zsh.h
index 7195e1535..cfd07d0e9 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1969,11 +1969,7 @@ struct tieddata {
#define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */
#define SCANPM_NONAMESPC (1<<12) /* namespace syntax not allowed */
#define SCANPM_NONAMEREF (1<<13) /* named references are not followed */
-
-/* "$foo[@]"-style substitution
- * Only sign bit is significant
- */
-#define SCANPM_ISVAR_AT ((int)(((unsigned int)-1)<<15))
+#define SCANPM_ISVAR_AT (1<<14) /* "$foo[@]"-style substitution */
/*
* Flags for doing matches inside parameter substitutions, i.e.
diff --git a/Src/params.c b/Src/params.c
index 8e60605ef..149c81d5a 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1968,7 +1968,8 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
* v: In/Out parameter. Its .start and .end members (at least) will be updated
* with the parsed indices.
*
- * flags: can be either SCANPM_DQUOTED or zero. Other bits are not used.
+ * flags: can be a combination of SCANPM_DQUOTED, SCANPM_NOEXEC, and
+ * SCANPM_CHECKING. Other bits are not used.
*/
/**/
diff --git a/Src/glob.c b/Src/glob.c
index 3e34f708e..17f4acd35 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1725,8 +1725,10 @@ zglob(LinkList list, LinkNode np, int nountok)
v.isarr = SCANPM_WANTVALS;
v.pm = NULL;
+ v.start = 0;
v.end = -1;
v.flags = 0;
+ v.arr = NULL;
if (getindex(&s, &v, 0) || s == os) {
zerr("invalid subscript");
restore_globstate(saved);
diff --git a/Src/params.c b/Src/params.c
index 149c81d5a..301634da4 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -653,6 +653,7 @@ scanparamvals(HashNode hn, int flags)
v.flags = 0;
v.start = 0;
v.end = -1;
+ v.arr = NULL;
paramvals[numparamvals] = getstrvalue(&v);
if (flags & SCANPM_MATCHVAL) {
if (pattry(scanprog, paramvals[numparamvals])) {
@@ -2196,9 +2197,11 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
else
v = (Value) hcalloc(sizeof *v);
v->pm = argvparam;
+ v->isarr = 0;
v->flags = 0;
v->start = ppar - 1;
v->end = ppar;
+ v->arr = NULL;
if (sav)
*s = sav;
} else {
@@ -2257,6 +2260,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
s = *pptr;
}
}
+ v->isarr = 0;
if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) {
/* Overload v->isarr as the flag bits for hashed arrays. */
v->isarr = flags | (isvarat ? SCANPM_ISVAR_AT : 0);
@@ -2270,6 +2274,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
v->flags = isrefslice ? VALFLAG_REFSLICE : 0;
v->start = 0;
v->end = -1;
+ v->arr = NULL;
if (bracks > 0 && (*s == '[' || *s == Inbrack)) {
if (getindex(&s, v, flags)) {
*pptr = s;
@@ -2641,11 +2646,13 @@ export_param(Param pm)
#if 0 /* Requires changes elsewhere in params.c and builtin.c */
if (EMULATION(EMULATE_KSH) /* isset(KSHARRAYS) */) {
struct value v;
+ v.pm = NULL;
v.isarr = (PM_TYPE(v.pm->node.flags) & PM_HASHED) ?
SCANPM_WANTVALS : SCANPM_ARRONLY;
v.flags = 0;
v.start = 0;
v.end = -1;
+ v.arr = NULL;
val = getstrvalue(&v);
} else
#endif
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index 3fefd412b..b0daf5942 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -517,7 +517,7 @@ gdbmhashsetfn(Param pm, HashTable ht)
int umlen = 0;
char *umkey, *umval;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
index 84cdfea18..7e5793592 100644
--- a/Src/Modules/mapfile.c
+++ b/Src/Modules/mapfile.c
@@ -151,7 +151,7 @@ setpmmapfiles(Param pm, HashTable ht)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 7441c30b8..2e25a914f 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -189,7 +189,7 @@ setpmcommands(Param pm, HashTable ht)
Cmdnam cn = zshcalloc(sizeof(*cn));
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -359,7 +359,7 @@ setfunctions(Param pm, HashTable ht, int dis)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -969,7 +969,7 @@ setpmoptions(Param pm, HashTable ht)
struct value v;
char *val;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1568,7 +1568,7 @@ setpmnameddirs(Param pm, HashTable ht)
struct value v;
char *val;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1799,7 +1799,7 @@ setaliases(HashTable alht, Param pm, HashTable ht, int flags)
struct value v;
char *val;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 3e1c8b8d2..aadcca639 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -1377,7 +1377,7 @@ set_compstate(Param pm, HashTable ht)
for (cp = compkparams,
pp = compkpms; cp->name; cp++, pp++)
if (!strcmp(hn->nam, cp->name)) {
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index 9f4fb5ac2..c704b7c8e 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -840,7 +840,7 @@ set_registers(Param pm, HashTable ht)
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.isarr = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/builtin.c b/Src/builtin.c
index 9ddaad93e..9635fd301 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3931,7 +3931,7 @@ bin_unset(char *name, char **argv, Options ops, int func)
vbuf.isarr = (PM_TYPE(pm->node.flags) == PM_ARRAY ?
SCANPM_ARRONLY : 0);
vbuf.pm = pm;
- vbuf.flags = 0;
+ vbuf.valflags = 0;
vbuf.start = 0;
vbuf.end = -1;
vbuf.arr = 0;
@@ -3942,7 +3942,8 @@ bin_unset(char *name, char **argv, Options ops, int func)
setstrvalue(&vbuf, ztrdup(""));
} else {
/* start is after the element for reverse index */
- int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV);
+ int start =
+ vbuf.start - !!(vbuf.valflags & VALFLAG_INV);
if (arrlen_gt(vbuf.pm->u.arr, start)) {
char *arr[2];
arr[0] = "";
diff --git a/Src/glob.c b/Src/glob.c
index 17f4acd35..4e1a43c34 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1727,7 +1727,7 @@ zglob(LinkList list, LinkNode np, int nountok)
v.pm = NULL;
v.start = 0;
v.end = -1;
- v.flags = 0;
+ v.valflags = 0;
v.arr = NULL;
if (getindex(&s, &v, 0) || s == os) {
zerr("invalid subscript");
diff --git a/Src/params.c b/Src/params.c
index 301634da4..ad00d1792 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -650,7 +650,7 @@ scanparamvals(HashNode hn, int flags)
return;
}
v.isarr = 0;
- v.flags = 0;
+ v.valflags = 0;
v.start = 0;
v.end = -1;
v.arr = NULL;
@@ -1704,7 +1704,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
(*ta || ((v->isarr & SCANPM_MATCHMANY) &&
(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
SCANPM_KEYMATCH))))) {
- *inv = (v->flags & VALFLAG_INV) ? 1 : 0;
+ *inv = (v->valflags & VALFLAG_INV) ? 1 : 0;
*w = v->end;
scanprog = NULL;
return 1;
@@ -2068,7 +2068,7 @@ getindex(char **pptr, Value v, int flags)
if (start > 0 && (isset(KSHARRAYS) || (v->pm->node.flags & PM_HASHED)))
start--;
if (v->isarr != SCANPM_WANTINDEX) {
- v->flags |= VALFLAG_INV;
+ v->valflags |= VALFLAG_INV;
v->isarr = 0;
v->start = start;
v->end = start + 1;
@@ -2121,7 +2121,7 @@ getindex(char **pptr, Value v, int flags)
* for setting elements. Set the indexes
* to a range that returns empty for other accesses.
*/
- v->flags |= VALFLAG_EMPTY;
+ v->valflags |= VALFLAG_EMPTY;
start = -1;
com = 1;
}
@@ -2198,7 +2198,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
v = (Value) hcalloc(sizeof *v);
v->pm = argvparam;
v->isarr = 0;
- v->flags = 0;
+ v->valflags = 0;
v->start = ppar - 1;
v->end = ppar;
v->arr = NULL;
@@ -2271,7 +2271,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
v->isarr = SCANPM_ARRONLY;
}
v->pm = pm;
- v->flags = isrefslice ? VALFLAG_REFSLICE : 0;
+ v->valflags = isrefslice ? VALFLAG_REFSLICE : 0;
v->start = 0;
v->end = -1;
v->arr = NULL;
@@ -2330,7 +2330,7 @@ getstrvalue(Value v)
if (!v)
return hcalloc(1);
- if ((v->flags & VALFLAG_INV) && !(v->pm->node.flags & PM_HASHED)) {
+ if ((v->valflags & VALFLAG_INV) && !(v->pm->node.flags & PM_HASHED)) {
sprintf(buf, "%d", v->start);
s = dupstring(buf);
return s;
@@ -2374,7 +2374,7 @@ getstrvalue(Value v)
break;
}
- if (v->flags & VALFLAG_SUBST) {
+ if (v->valflags & VALFLAG_SUBST) {
if (v->pm->node.flags & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z)) {
size_t fwidth = v->pm->width ? (unsigned int)v->pm->width : MB_METASTRLEN(s);
switch (v->pm->node.flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
@@ -2541,7 +2541,7 @@ getarrvalue(Value v)
return arrdup(nular);
else if (IS_UNSET_VALUE(v))
return arrdup(&nular[1]);
- if (v->flags & VALFLAG_INV) {
+ if (v->valflags & VALFLAG_INV) {
char buf[DIGBUFSIZE];
s = arrdup(nular);
@@ -2590,7 +2590,7 @@ getintvalue(Value v)
{
if (!v)
return 0;
- if (v->flags & VALFLAG_INV)
+ if (v->valflags & VALFLAG_INV)
return v->start;
if (v->isarr) {
char **arr = getarrvalue(v);
@@ -2617,7 +2617,7 @@ getnumvalue(Value v)
if (!v) {
mn.u.l = 0;
- } else if (v->flags & VALFLAG_INV) {
+ } else if (v->valflags & VALFLAG_INV) {
mn.u.l = v->start;
} else if (v->isarr) {
char **arr = getarrvalue(v);
@@ -2649,7 +2649,7 @@ export_param(Param pm)
v.pm = NULL;
v.isarr = (PM_TYPE(v.pm->node.flags) & PM_HASHED) ?
SCANPM_WANTVALS : SCANPM_ARRONLY;
- v.flags = 0;
+ v.valflags = 0;
v.start = 0;
v.end = -1;
v.arr = NULL;
@@ -2697,7 +2697,7 @@ assignstrvalue(Value v, char *val, int flags)
zsfree(val);
return;
}
- if (v->flags & VALFLAG_EMPTY) {
+ if (v->valflags & VALFLAG_EMPTY) {
zerr("%s: assignment to invalid subscript range", v->pm->node.nam);
zsfree(val);
return;
@@ -2717,7 +2717,7 @@ assignstrvalue(Value v, char *val, int flags)
z = v->pm->gsu.s->getfn(v->pm);
zlen = strlen(z);
- if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS))
+ if ((v->valflags & VALFLAG_INV) && unset(KSHARRAYS))
v->start--, v->end--;
if (v->start < 0) {
v->start += zlen;
@@ -2907,7 +2907,7 @@ setarrvalue(Value v, char **val)
v->pm->node.nam);
return;
}
- if (v->flags & VALFLAG_EMPTY) {
+ if (v->valflags & VALFLAG_EMPTY) {
zerr("%s: assignment to invalid subscript range", v->pm->node.nam);
freearray(val);
return;
@@ -2936,7 +2936,7 @@ setarrvalue(Value v, char **val)
q = old;
- if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS)) {
+ if ((v->valflags & VALFLAG_INV) && unset(KSHARRAYS)) {
if (v->start > 0)
v->start--;
v->end--;
@@ -3234,7 +3234,7 @@ assignsparam(char *s, char *val, int flags)
createparam(t, PM_SCALAR);
created = 1;
} else if ((((v->pm->node.flags & PM_ARRAY) &&
- !(v->flags & VALFLAG_REFSLICE) &&
+ !(v->valflags & VALFLAG_REFSLICE) &&
!(flags & ASSPM_AUGMENT)) ||
(v->pm->node.flags & PM_HASHED)) &&
!(v->pm->node.flags & (PM_SPECIAL|PM_TIED)) &&
@@ -3395,7 +3395,7 @@ assignaparam(char *s, char **val, int flags)
createparam(t, PM_ARRAY);
created = 1;
} else if (!(PM_TYPE(v->pm->node.flags) & (PM_ARRAY|PM_HASHED)) &&
- !(v->flags & VALFLAG_REFSLICE) &&
+ !(v->valflags & VALFLAG_REFSLICE) &&
!(v->pm->node.flags & (PM_SPECIAL|PM_TIED))) {
int uniq = v->pm->node.flags & PM_UNIQUE;
if ((flags & ASSPM_AUGMENT) && !(v->pm->node.flags & PM_UNSET)) {
@@ -3623,7 +3623,7 @@ sethparam(char *s, char **val)
createparam(t, PM_HASHED);
checkcreate = 1;
} else if (!(PM_TYPE(v->pm->node.flags) & PM_HASHED) &&
- !(v->flags & VALFLAG_REFSLICE)) {
+ !(v->valflags & VALFLAG_REFSLICE)) {
if (!(v->pm->node.flags & PM_SPECIAL)) {
if (resetparam(v->pm, PM_HASHED)) {
unqueue_signals();
diff --git a/Src/subst.c b/Src/subst.c
index 308a717a9..17291009f 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2802,7 +2802,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
((unset(KSHARRAYS) || inbrace) ? 1 : -1)),
scanflags)) ||
(v->pm && (v->pm->node.flags & PM_UNSET)) ||
- (v->flags & VALFLAG_EMPTY)))
+ (v->valflags & VALFLAG_EMPTY)))
vunset = 1;
if (wantt) {
/*
@@ -2914,7 +2914,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
*/
if ((isarr = (v->isarr & SCANPM_ISVAR_AT) ? -1 : v->isarr ? 1 : 0)) {
/*
- * No way to get here with v->flags & VALFLAG_INV, so
+ * No way to get here with v->valflags & VALFLAG_INV, so
* getvaluearr() is called by getarrvalue(); needn't test
* PM_HASHED.
*/
@@ -2942,9 +2942,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
if (v->start < 0) {
tmplen = arrlen(v->pm->gsu.a->getfn(v->pm));
- v->start += tmplen + ((v->flags & VALFLAG_INV) ? 1 : 0);
+ v->start += tmplen + ((v->valflags & VALFLAG_INV) ? 1 : 0);
}
- if (!(v->flags & VALFLAG_INV))
+ if (!(v->valflags & VALFLAG_INV))
if (v->start < 0 ||
(tmplen != -1
? v->start >= tmplen
@@ -2960,7 +2960,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* if we allow them to applied on every call, so
* set the flag that allows them to be substituted.
*/
- v->flags |= VALFLAG_SUBST;
+ v->valflags |= VALFLAG_SUBST;
val = getstrvalue(v);
}
}
diff --git a/Src/zsh.h b/Src/zsh.h
index cfd07d0e9..de855d845 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -749,7 +749,7 @@ struct value {
* value struct represents an array or an
* associative array. For plain arrays, use
* SCANPM_ARRONLY. */
- int flags; /* flags defined below */
+ int valflags; /* flags defined below */
int start; /* first element of array slice, or -1 */
int end; /* 1-rel last element of array slice, or -1 */
};
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index b0daf5942..7d1720de5 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -517,7 +517,7 @@ gdbmhashsetfn(Param pm, HashTable ht)
int umlen = 0;
char *umkey, *umval;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
index 7e5793592..78f728385 100644
--- a/Src/Modules/mapfile.c
+++ b/Src/Modules/mapfile.c
@@ -151,7 +151,7 @@ setpmmapfiles(Param pm, HashTable ht)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 2e25a914f..10e4ffc5c 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -189,7 +189,7 @@ setpmcommands(Param pm, HashTable ht)
Cmdnam cn = zshcalloc(sizeof(*cn));
struct value v;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -359,7 +359,7 @@ setfunctions(Param pm, HashTable ht, int dis)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -969,7 +969,7 @@ setpmoptions(Param pm, HashTable ht)
struct value v;
char *val;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1568,7 +1568,7 @@ setpmnameddirs(Param pm, HashTable ht)
struct value v;
char *val;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1799,7 +1799,7 @@ setaliases(HashTable alht, Param pm, HashTable ht, int flags)
struct value v;
char *val;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index a129cc5fe..511436564 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1716,7 +1716,7 @@ zalloc_default_array(char ***aval, char *assoc, int keep, int num)
struct value vbuf;
Value v = fetchvalue(&vbuf, &assoc, 0,
SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
- if (v && v->isarr) {
+ if (v && v->scanflags) {
char **dp, **dval = getarrvalue(v);
int dnum = (dval ? arrlen(dval) : 0) + 1;
*aval = (char **) zalloc(((num * 2) + dnum) * sizeof(char *));
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index aadcca639..647316c1a 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -1377,7 +1377,7 @@ set_compstate(Param pm, HashTable ht)
for (cp = compkparams,
pp = compkpms; cp->name; cp++, pp++)
if (!strcmp(hn->nam, cp->name)) {
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index d7b2ca21c..d82a21781 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1735,7 +1735,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
zwarnnam(name, "not an identifier: `%s'", args[0]);
return 1;
}
- if (v->isarr) {
+ if (v->scanflags) {
/* Array: check for separators and quote them. */
char **arr = getarrvalue(v), **aptr, **tmparr, **tptr;
tptr = tmparr = (char **)zhalloc(sizeof(char *)*(arrlen(arr)+1));
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index c704b7c8e..ec53ea4ef 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -840,7 +840,7 @@ set_registers(Param pm, HashTable ht)
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.valflags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/builtin.c b/Src/builtin.c
index 9635fd301..c27f9cfb2 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3928,8 +3928,8 @@ bin_unset(char *name, char **argv, Options ops, int func)
} else if (PM_TYPE(pm->node.flags) == PM_SCALAR ||
PM_TYPE(pm->node.flags) == PM_ARRAY) {
struct value vbuf;
- vbuf.isarr = (PM_TYPE(pm->node.flags) == PM_ARRAY ?
- SCANPM_ARRONLY : 0);
+ vbuf.scanflags =
+ (PM_TYPE(pm->node.flags) == PM_ARRAY ? SCANPM_ARRONLY : 0);
vbuf.pm = pm;
vbuf.valflags = 0;
vbuf.start = 0;
diff --git a/Src/glob.c b/Src/glob.c
index 4e1a43c34..9bfb0f895 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1723,7 +1723,7 @@ zglob(LinkList list, LinkNode np, int nountok)
char *os = --s;
struct value v;
- v.isarr = SCANPM_WANTVALS;
+ v.scanflags = SCANPM_WANTVALS;
v.pm = NULL;
v.start = 0;
v.end = -1;
diff --git a/Src/params.c b/Src/params.c
index ad00d1792..39c3f0c2e 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -649,7 +649,7 @@ scanparamvals(HashNode hn, int flags)
if (!(flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)))
return;
}
- v.isarr = 0;
+ v.scanflags = 0;
v.valflags = 0;
v.start = 0;
v.end = -1;
@@ -696,7 +696,7 @@ getvaluearr(Value v)
else if (PM_TYPE(v->pm->node.flags) == PM_ARRAY)
return v->arr = v->pm->gsu.a->getfn(v->pm);
else if (PM_TYPE(v->pm->node.flags) == PM_HASHED) {
- v->arr = paramvalarr(v->pm->gsu.h->getfn(v->pm), v->isarr);
+ v->arr = paramvalarr(v->pm->gsu.h->getfn(v->pm), v->scanflags);
/* Can't take numeric slices of associative arrays */
v->start = 0;
v->end = numparamvals + 1;
@@ -720,7 +720,7 @@ issetvar(char *name)
if (!(v = getvalue(&vbuf, &name, 1)) || *name)
return 0; /* no value or more chars after the variable name */
- if (v->isarr & ~SCANPM_ARRONLY)
+ if (v->scanflags & ~SCANPM_ARRONLY)
return v->end > 1; /* for extracted elements, end gives us a count */
slice = v->start != 0 || v->end != -1;
@@ -1320,7 +1320,7 @@ isident(char *s)
*
* *inv is set to indicate if the subscript is reversed (output)
* v is the Value for the parameter being accessed (input; note
- * v->isarr may be modified, and if v is a hash the parameter will
+ * v->scanflags may be modified, and if v is a hash the parameter will
* be updated to the element of the hash)
* a2 is 1 if this is the second subscript of a range (input)
* *w is only set if we need to find the end of a word (input; should
@@ -1342,7 +1342,7 @@ isident(char *s)
/**/
static zlong
getarg(char **str, int *inv, Value v, int a2, zlong *w,
- int *prevcharlen, int *nextcharlen, int flags)
+ int *prevcharlen, int *nextcharlen, int scanflags)
{
int hasbeg = 0, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
int keymatch = 0, needtok = 0, arglen, len, inpar = 0;
@@ -1466,23 +1466,23 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
down = !down;
num = -num;
}
- if (v->isarr & SCANPM_WANTKEYS)
- *inv = (ind || !(v->isarr & SCANPM_WANTVALS));
- else if (v->isarr & SCANPM_WANTVALS)
+ if (v->scanflags & SCANPM_WANTKEYS)
+ *inv = (ind || !(v->scanflags & SCANPM_WANTVALS));
+ else if (v->scanflags & SCANPM_WANTVALS)
*inv = 0;
else {
- if (v->isarr) {
+ if (v->scanflags) {
if (ind) {
- v->isarr |= SCANPM_WANTKEYS;
- v->isarr &= ~SCANPM_WANTVALS;
+ v->scanflags |= SCANPM_WANTKEYS;
+ v->scanflags &= ~SCANPM_WANTVALS;
} else if (rev)
- v->isarr |= SCANPM_WANTVALS;
+ v->scanflags |= SCANPM_WANTVALS;
/*
* This catches the case where we are using "k" (rather
* than "K") on a hash.
*/
if (!down && keymatch && ishash)
- v->isarr &= ~SCANPM_MATCHMANY;
+ v->scanflags &= ~SCANPM_MATCHMANY;
}
*inv = ind;
}
@@ -1543,7 +1543,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
s = dupstring(s);
if (parsestr(&s))
return 0;
- if (flags & SCANPM_NOEXEC)
+ if (scanflags & SCANPM_NOEXEC)
opts[EXECOPT] = 0;
singsub(&s);
opts[EXECOPT] = exe;
@@ -1553,7 +1553,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (ishash) {
HashTable ht = v->pm->gsu.h->getfn(v->pm);
if (!ht) {
- if (flags & SCANPM_CHECKING)
+ if (scanflags & SCANPM_CHECKING)
return 0;
ht = newparamtable(17, v->pm->node.nam);
v->pm->gsu.h->setfn(v->pm, ht);
@@ -1565,7 +1565,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
v->pm = createparam(s, PM_SCALAR|PM_UNSET);
paramtab = tht;
}
- v->isarr = (*inv ? SCANPM_WANTINDEX : 0);
+ v->scanflags = (*inv ? SCANPM_WANTINDEX : 0);
v->start = 0;
*inv = 0; /* We've already obtained the "index" (key) */
*w = v->end = -1;
@@ -1575,7 +1575,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (isset(KSHARRAYS) && r >= 0)
r++;
}
- if (word && !v->isarr) {
+ if (word && !v->scanflags) {
s = t = getstrvalue(v);
i = wordcount(s, sep, 0);
if (r < 0)
@@ -1594,7 +1594,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
*w = (zlong)(s - t);
return (a2 ? s : d + 1) - t;
- } else if (!v->isarr && !word) {
+ } else if (!v->scanflags && !word) {
int lastcharlen = 1;
s = getstrvalue(v);
/*
@@ -1642,7 +1642,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
}
}
} else {
- if (!v->isarr && !word && !quote_arg) {
+ if (!v->scanflags && !word && !quote_arg) {
l = strlen(s);
if (a2) {
if (!l || *s != '*') {
@@ -1664,7 +1664,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (quote_arg) {
untokenize(s);
/* Scalar (e) needs implicit asterisk tokens */
- if (!v->isarr && !word) {
+ if (!v->scanflags && !word) {
l = strlen(s);
d = (char *) hcalloc(l + 2);
if (a2) {
@@ -1684,26 +1684,26 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
} else
pprog = NULL;
- if (v->isarr) {
+ if (v->scanflags) {
if (ishash) {
scanprog = pprog;
scanstr = s;
if (keymatch)
- v->isarr |= SCANPM_KEYMATCH;
+ v->scanflags |= SCANPM_KEYMATCH;
else {
if (!pprog)
return 1;
if (ind)
- v->isarr |= SCANPM_MATCHKEY;
+ v->scanflags |= SCANPM_MATCHKEY;
else
- v->isarr |= SCANPM_MATCHVAL;
+ v->scanflags |= SCANPM_MATCHVAL;
}
if (down)
- v->isarr |= SCANPM_MATCHMANY;
+ v->scanflags |= SCANPM_MATCHMANY;
if ((ta = getvaluearr(v)) &&
- (*ta || ((v->isarr & SCANPM_MATCHMANY) &&
- (v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
- SCANPM_KEYMATCH))))) {
+ (*ta || ((v->scanflags & SCANPM_MATCHMANY) &&
+ (v->scanflags & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
+ SCANPM_KEYMATCH))))) {
*inv = (v->valflags & VALFLAG_INV) ? 1 : 0;
*w = v->end;
scanprog = NULL;
@@ -1969,20 +1969,20 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
* v: In/Out parameter. Its .start and .end members (at least) will be updated
* with the parsed indices.
*
- * flags: can be a combination of SCANPM_DQUOTED, SCANPM_NOEXEC, and
+ * scanflags: can be a combination of SCANPM_DQUOTED, SCANPM_NOEXEC, and
* SCANPM_CHECKING. Other bits are not used.
*/
/**/
int
-getindex(char **pptr, Value v, int flags)
+getindex(char **pptr, Value v, int scanflags)
{
int start, end, inv = 0;
char *s = *pptr, *tbrack;
*s++ = '[';
/* Error handled after untokenizing */
- s = parse_subscript(s, flags & SCANPM_DQUOTED, ']');
+ s = parse_subscript(s, scanflags & SCANPM_DQUOTED, ']');
/* Now we untokenize everything except inull() markers so we can check *
* for the '*' and '@' special subscripts. The inull()s are removed *
* in getarg() after we know whether we're doing reverse indexing. */
@@ -2002,8 +2002,8 @@ getindex(char **pptr, Value v, int flags)
}
s = *pptr + 1;
if ((s[0] == '*' || s[0] == '@') && s + 1 == tbrack) {
- if ((v->isarr || IS_UNSET_VALUE(v)) && s[0] == '@')
- v->isarr |= SCANPM_ISVAR_AT;
+ if ((v->scanflags || IS_UNSET_VALUE(v)) && s[0] == '@')
+ v->scanflags |= SCANPM_ISVAR_AT;
v->start = 0;
v->end = -1;
s += 2;
@@ -2012,10 +2012,10 @@ getindex(char **pptr, Value v, int flags)
int startprevlen, startnextlen;
start = getarg(&s, &inv, v, 0, &we, &startprevlen, &startnextlen,
- flags);
+ scanflags);
if (inv) {
- if (!v->isarr && start != 0) {
+ if (!v->scanflags && start != 0) {
char *t, *p;
t = getstrvalue(v);
/*
@@ -2067,9 +2067,9 @@ getindex(char **pptr, Value v, int flags)
}
if (start > 0 && (isset(KSHARRAYS) || (v->pm->node.flags & PM_HASHED)))
start--;
- if (v->isarr != SCANPM_WANTINDEX) {
+ if (v->scanflags != SCANPM_WANTINDEX) {
v->valflags |= VALFLAG_INV;
- v->isarr = 0;
+ v->scanflags = 0;
v->start = start;
v->end = start + 1;
}
@@ -2086,7 +2086,7 @@ getindex(char **pptr, Value v, int flags)
if ((com = (*s == ','))) {
s++;
- end = getarg(&s, &inv, v, 1, &dummy, NULL, NULL, flags);
+ end = getarg(&s, &inv, v, 1, &dummy, NULL, NULL, scanflags);
} else {
end = we ? we : start;
}
@@ -2128,11 +2128,11 @@ getindex(char **pptr, Value v, int flags)
}
if (s == tbrack) {
s++;
- if (v->isarr && !com &&
- (!(v->isarr & SCANPM_MATCHMANY) ||
- !(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
- SCANPM_KEYMATCH))))
- v->isarr = 0;
+ if (v->scanflags && !com &&
+ (!(v->scanflags & SCANPM_MATCHMANY) ||
+ !(v->scanflags & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
+ SCANPM_KEYMATCH))))
+ v->scanflags = 0;
v->start = start;
v->end = end;
} else
@@ -2154,12 +2154,12 @@ getvalue(Value v, char **pptr, int bracks)
/**/
mod_export Value
-fetchvalue(Value v, char **pptr, int bracks, int flags)
+fetchvalue(Value v, char **pptr, int bracks, int scanflags)
{
char *s, *t, *ie;
char sav, c;
int ppar = 0;
- int itype = (flags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC;
+ int itype = (scanflags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC;
s = t = *pptr;
@@ -2197,7 +2197,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
else
v = (Value) hcalloc(sizeof *v);
v->pm = argvparam;
- v->isarr = 0;
+ v->scanflags = 0;
v->valflags = 0;
v->start = ppar - 1;
v->end = ppar;
@@ -2210,7 +2210,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
int isrefslice = 0;
isvarat = (t[0] == '@' && !t[1]);
- if (flags & SCANPM_NONAMEREF)
+ if (scanflags & SCANPM_NONAMEREF)
pm = (Param) paramtab->getnode2(paramtab, *t == '0' ? "0" : t);
else
pm = (Param) paramtab->getnode(paramtab, *t == '0' ? "0" : t);
@@ -2229,7 +2229,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
memset(v, 0, sizeof(*v));
else
v = (Value) hcalloc(sizeof *v);
- if ((pm->node.flags & PM_NAMEREF) && !(flags & SCANPM_NONAMEREF)) {
+ if ((pm->node.flags & PM_NAMEREF) && !(scanflags & SCANPM_NONAMEREF)) {
char *refname = GETREFNAME(pm);
if (refname && *refname) {
/* only happens for namerefs pointing to array elements */
@@ -2252,7 +2252,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
!(pm->node.flags & PM_DECLARED)))
return NULL;
if (ss) {
- flags |= SCANPM_NOEXEC;
+ scanflags |= SCANPM_NOEXEC;
*ss = sav;
s = dyncat(ss,*pptr);
isrefslice = 1;
@@ -2260,15 +2260,15 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
s = *pptr;
}
}
- v->isarr = 0;
+ v->scanflags = 0;
if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) {
- /* Overload v->isarr as the flag bits for hashed arrays. */
- v->isarr = flags | (isvarat ? SCANPM_ISVAR_AT : 0);
+ /* Overload v->scanflags as the flag bits for hashed arrays. */
+ v->scanflags = scanflags | (isvarat ? SCANPM_ISVAR_AT : 0);
/* If no flags were passed, we need something to represent *
* `true' yet differ from an explicit WANTVALS. Use a *
* special flag for this case. */
- if (!v->isarr)
- v->isarr = SCANPM_ARRONLY;
+ if (!v->scanflags)
+ v->scanflags = SCANPM_ARRONLY;
}
v->pm = pm;
v->valflags = isrefslice ? VALFLAG_REFSLICE : 0;
@@ -2276,13 +2276,13 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
v->end = -1;
v->arr = NULL;
if (bracks > 0 && (*s == '[' || *s == Inbrack)) {
- if (getindex(&s, v, flags)) {
+ if (getindex(&s, v, scanflags)) {
*pptr = s;
return v;
}
- } else if (!(flags & SCANPM_ASSIGNING) && v->isarr &&
+ } else if (!(scanflags & SCANPM_ASSIGNING) && v->scanflags &&
itype_end(t, INAMESPC, 1) != t && isset(KSHARRAYS))
- v->end = 1, v->isarr = 0;
+ v->end = 1, v->scanflags = 0;
}
if (!bracks && *s)
return NULL;
@@ -2338,8 +2338,8 @@ getstrvalue(Value v)
switch(PM_TYPE(v->pm->node.flags)) {
case PM_HASHED:
- /* (!v->isarr) should be impossible unless emulating ksh */
- if (!v->isarr && EMULATION(EMULATE_KSH)) {
+ /* (!v->scanflags) should be impossible unless emulating ksh */
+ if (!v->scanflags && EMULATION(EMULATE_KSH)) {
s = dupstring("[0]");
if (getindex(&s, v, 0) == 0)
s = getstrvalue(v);
@@ -2347,7 +2347,7 @@ getstrvalue(Value v)
} /* else fall through */
case PM_ARRAY:
ss = getvaluearr(v);
- if (v->isarr)
+ if (v->scanflags)
s = sepjoin(ss, NULL, 1);
else {
if (v->start < 0)
@@ -2592,7 +2592,7 @@ getintvalue(Value v)
return 0;
if (v->valflags & VALFLAG_INV)
return v->start;
- if (v->isarr) {
+ if (v->scanflags) {
char **arr = getarrvalue(v);
if (arr) {
char *scal = sepjoin(arr, NULL, 1);
@@ -2619,7 +2619,7 @@ getnumvalue(Value v)
mn.u.l = 0;
} else if (v->valflags & VALFLAG_INV) {
mn.u.l = v->start;
- } else if (v->isarr) {
+ } else if (v->scanflags) {
char **arr = getarrvalue(v);
if (arr) {
char *scal = sepjoin(arr, NULL, 1);
@@ -2647,7 +2647,7 @@ export_param(Param pm)
if (EMULATION(EMULATE_KSH) /* isset(KSHARRAYS) */) {
struct value v;
v.pm = NULL;
- v.isarr = (PM_TYPE(v.pm->node.flags) & PM_HASHED) ?
+ v.scanflags = (PM_TYPE(v.pm->node.flags) & PM_HASHED) ?
SCANPM_WANTVALS : SCANPM_ARRONLY;
v.valflags = 0;
v.start = 0;
@@ -2692,7 +2692,7 @@ assignstrvalue(Value v, char *val, int flags)
return;
}
if ((v->pm->node.flags & PM_HASHED) &&
- (v->isarr & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
+ (v->scanflags & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
zerr("%s: attempt to set slice of associative array", v->pm->node.nam);
zsfree(val);
return;
@@ -3324,7 +3324,7 @@ assignsparam(char *s, char *val, int flags)
kshappend:
/* treat slice as the end element */
v->start = sstart = v->end > 0 ? v->end - 1 : v->end;
- v->isarr = 0;
+ v->scanflags = 0;
var = getstrvalue(v);
v->start = sstart;
copy = val;
diff --git a/Src/subst.c b/Src/subst.c
index 17291009f..9f0eccd16 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2893,7 +2893,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
else
pm->u.str = val;
v = (Value) hcalloc(sizeof *v);
- v->isarr = isarr ? SCANPM_ARRONLY : 0;
+ v->scanflags = isarr ? SCANPM_ARRONLY : 0;
v->pm = pm;
v->end = -1;
if (getindex(&s, v, qt ? SCANPM_DQUOTED : 0) || s == os)
@@ -2905,21 +2905,22 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* array (aval) value. TODO: move val and aval into
* a structure with a discriminator. Hope we can make
* more things array values at this point and dearrayify later.
- * v->isarr tells us whether the stuff from down below looks
+ * v->scanflags tells us whether the stuff from down below looks
* like an array.
*
* I think we get to discard the existing value of isarr
* here because it's already been taken account of, either
* in the subexp stuff or immediately above.
*/
- if ((isarr = (v->isarr & SCANPM_ISVAR_AT) ? -1 : v->isarr ? 1 : 0)) {
+ if ((isarr =
+ (v->scanflags & SCANPM_ISVAR_AT) ? -1 : v->scanflags ? 1 : 0)) {
/*
* No way to get here with v->valflags & VALFLAG_INV, so
* getvaluearr() is called by getarrvalue(); needn't test
* PM_HASHED.
*/
- if (v->isarr == SCANPM_WANTINDEX) {
- isarr = v->isarr = 0;
+ if (v->scanflags == SCANPM_WANTINDEX) {
+ isarr = v->scanflags = 0;
val = dupstring(v->pm->node.nam);
} else
aval = getarrvalue(v);
@@ -3010,7 +3011,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* substitution is in quotes) always good enough? Potentially
* we may be OK by now --- all potential `@'s and subexpressions
* have been handled, including any [@] index which comes up
- * by virtue of v->isarr being set to SCANPM_ISVAR_AT which
+ * by virtue of v->scanflags being set to SCANPM_ISVAR_AT which
* is now in isarr being set to -1.
*
* However, if we are replacing multsub() with something that
diff --git a/Src/zsh.h b/Src/zsh.h
index de855d845..ef69e97ab 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -744,7 +744,7 @@ struct multio {
struct value {
Param pm; /* parameter node */
char **arr; /* cache for hash turned into array */
- int isarr; /* set of SCANPM flags as well as an is-array
+ int scanflags; /* set of SCANPM flags as well as an is-array
* marker. The field must be non-zero iff the
* value struct represents an array or an
* associative array. For plain arrays, use
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
index 3fefd412b..7d1720de5 100644
--- a/Src/Modules/db_gdbm.c
+++ b/Src/Modules/db_gdbm.c
@@ -517,7 +517,7 @@ gdbmhashsetfn(Param pm, HashTable ht)
int umlen = 0;
char *umkey, *umval;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/mapfile.c b/Src/Modules/mapfile.c
index 84cdfea18..78f728385 100644
--- a/Src/Modules/mapfile.c
+++ b/Src/Modules/mapfile.c
@@ -151,7 +151,7 @@ setpmmapfiles(Param pm, HashTable ht)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/parameter.c b/Src/Modules/parameter.c
index 7441c30b8..10e4ffc5c 100644
--- a/Src/Modules/parameter.c
+++ b/Src/Modules/parameter.c
@@ -189,7 +189,7 @@ setpmcommands(Param pm, HashTable ht)
Cmdnam cn = zshcalloc(sizeof(*cn));
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -359,7 +359,7 @@ setfunctions(Param pm, HashTable ht, int dis)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -969,7 +969,7 @@ setpmoptions(Param pm, HashTable ht)
struct value v;
char *val;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1568,7 +1568,7 @@ setpmnameddirs(Param pm, HashTable ht)
struct value v;
char *val;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1799,7 +1799,7 @@ setaliases(HashTable alht, Param pm, HashTable ht, int flags)
struct value v;
char *val;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index a129cc5fe..511436564 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -1716,7 +1716,7 @@ zalloc_default_array(char ***aval, char *assoc, int keep, int num)
struct value vbuf;
Value v = fetchvalue(&vbuf, &assoc, 0,
SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
- if (v && v->isarr) {
+ if (v && v->scanflags) {
char **dp, **dval = getarrvalue(v);
int dnum = (dval ? arrlen(dval) : 0) + 1;
*aval = (char **) zalloc(((num * 2) + dnum) * sizeof(char *));
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 3e1c8b8d2..647316c1a 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -1377,7 +1377,7 @@ set_compstate(Param pm, HashTable ht)
for (cp = compkparams,
pp = compkpms; cp->name; cp++, pp++)
if (!strcmp(hn->nam, cp->name)) {
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index d7b2ca21c..d82a21781 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1735,7 +1735,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
zwarnnam(name, "not an identifier: `%s'", args[0]);
return 1;
}
- if (v->isarr) {
+ if (v->scanflags) {
/* Array: check for separators and quote them. */
char **arr = getarrvalue(v), **aptr, **tmparr, **tptr;
tptr = tmparr = (char **)zhalloc(sizeof(char *)*(arrlen(arr)+1));
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index 9f4fb5ac2..ec53ea4ef 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -840,7 +840,7 @@ set_registers(Param pm, HashTable ht)
for (i = 0; i < ht->hsize; i++)
for (hn = ht->nodes[i]; hn; hn = hn->next) {
struct value v;
- v.isarr = v.flags = v.start = 0;
+ v.scanflags = v.valflags = v.start = 0;
v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
diff --git a/Src/builtin.c b/Src/builtin.c
index 9ddaad93e..c27f9cfb2 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3928,10 +3928,10 @@ bin_unset(char *name, char **argv, Options ops, int func)
} else if (PM_TYPE(pm->node.flags) == PM_SCALAR ||
PM_TYPE(pm->node.flags) == PM_ARRAY) {
struct value vbuf;
- vbuf.isarr = (PM_TYPE(pm->node.flags) == PM_ARRAY ?
- SCANPM_ARRONLY : 0);
+ vbuf.scanflags =
+ (PM_TYPE(pm->node.flags) == PM_ARRAY ? SCANPM_ARRONLY : 0);
vbuf.pm = pm;
- vbuf.flags = 0;
+ vbuf.valflags = 0;
vbuf.start = 0;
vbuf.end = -1;
vbuf.arr = 0;
@@ -3942,7 +3942,8 @@ bin_unset(char *name, char **argv, Options ops, int func)
setstrvalue(&vbuf, ztrdup(""));
} else {
/* start is after the element for reverse index */
- int start = vbuf.start - !!(vbuf.flags & VALFLAG_INV);
+ int start =
+ vbuf.start - !!(vbuf.valflags & VALFLAG_INV);
if (arrlen_gt(vbuf.pm->u.arr, start)) {
char *arr[2];
arr[0] = "";
diff --git a/Src/glob.c b/Src/glob.c
index 3e34f708e..9bfb0f895 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1723,10 +1723,12 @@ zglob(LinkList list, LinkNode np, int nountok)
char *os = --s;
struct value v;
- v.isarr = SCANPM_WANTVALS;
+ v.scanflags = SCANPM_WANTVALS;
v.pm = NULL;
+ v.start = 0;
v.end = -1;
- v.flags = 0;
+ v.valflags = 0;
+ v.arr = NULL;
if (getindex(&s, &v, 0) || s == os) {
zerr("invalid subscript");
restore_globstate(saved);
diff --git a/Src/params.c b/Src/params.c
index b76fb8a6b..39c3f0c2e 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -649,10 +649,11 @@ scanparamvals(HashNode hn, int flags)
if (!(flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)))
return;
}
- v.isarr = (PM_TYPE(v.pm->node.flags) & (PM_ARRAY|PM_HASHED));
- v.flags = 0;
+ v.scanflags = 0;
+ v.valflags = 0;
v.start = 0;
v.end = -1;
+ v.arr = NULL;
paramvals[numparamvals] = getstrvalue(&v);
if (flags & SCANPM_MATCHVAL) {
if (pattry(scanprog, paramvals[numparamvals])) {
@@ -695,7 +696,7 @@ getvaluearr(Value v)
else if (PM_TYPE(v->pm->node.flags) == PM_ARRAY)
return v->arr = v->pm->gsu.a->getfn(v->pm);
else if (PM_TYPE(v->pm->node.flags) == PM_HASHED) {
- v->arr = paramvalarr(v->pm->gsu.h->getfn(v->pm), v->isarr);
+ v->arr = paramvalarr(v->pm->gsu.h->getfn(v->pm), v->scanflags);
/* Can't take numeric slices of associative arrays */
v->start = 0;
v->end = numparamvals + 1;
@@ -719,7 +720,7 @@ issetvar(char *name)
if (!(v = getvalue(&vbuf, &name, 1)) || *name)
return 0; /* no value or more chars after the variable name */
- if (v->isarr & ~SCANPM_ARRONLY)
+ if (v->scanflags & ~SCANPM_ARRONLY)
return v->end > 1; /* for extracted elements, end gives us a count */
slice = v->start != 0 || v->end != -1;
@@ -1319,7 +1320,7 @@ isident(char *s)
*
* *inv is set to indicate if the subscript is reversed (output)
* v is the Value for the parameter being accessed (input; note
- * v->isarr may be modified, and if v is a hash the parameter will
+ * v->scanflags may be modified, and if v is a hash the parameter will
* be updated to the element of the hash)
* a2 is 1 if this is the second subscript of a range (input)
* *w is only set if we need to find the end of a word (input; should
@@ -1341,7 +1342,7 @@ isident(char *s)
/**/
static zlong
getarg(char **str, int *inv, Value v, int a2, zlong *w,
- int *prevcharlen, int *nextcharlen, int flags)
+ int *prevcharlen, int *nextcharlen, int scanflags)
{
int hasbeg = 0, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
int keymatch = 0, needtok = 0, arglen, len, inpar = 0;
@@ -1465,23 +1466,23 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
down = !down;
num = -num;
}
- if (v->isarr & SCANPM_WANTKEYS)
- *inv = (ind || !(v->isarr & SCANPM_WANTVALS));
- else if (v->isarr & SCANPM_WANTVALS)
+ if (v->scanflags & SCANPM_WANTKEYS)
+ *inv = (ind || !(v->scanflags & SCANPM_WANTVALS));
+ else if (v->scanflags & SCANPM_WANTVALS)
*inv = 0;
else {
- if (v->isarr) {
+ if (v->scanflags) {
if (ind) {
- v->isarr |= SCANPM_WANTKEYS;
- v->isarr &= ~SCANPM_WANTVALS;
+ v->scanflags |= SCANPM_WANTKEYS;
+ v->scanflags &= ~SCANPM_WANTVALS;
} else if (rev)
- v->isarr |= SCANPM_WANTVALS;
+ v->scanflags |= SCANPM_WANTVALS;
/*
* This catches the case where we are using "k" (rather
* than "K") on a hash.
*/
if (!down && keymatch && ishash)
- v->isarr &= ~SCANPM_MATCHMANY;
+ v->scanflags &= ~SCANPM_MATCHMANY;
}
*inv = ind;
}
@@ -1542,7 +1543,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
s = dupstring(s);
if (parsestr(&s))
return 0;
- if (flags & SCANPM_NOEXEC)
+ if (scanflags & SCANPM_NOEXEC)
opts[EXECOPT] = 0;
singsub(&s);
opts[EXECOPT] = exe;
@@ -1552,7 +1553,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (ishash) {
HashTable ht = v->pm->gsu.h->getfn(v->pm);
if (!ht) {
- if (flags & SCANPM_CHECKING)
+ if (scanflags & SCANPM_CHECKING)
return 0;
ht = newparamtable(17, v->pm->node.nam);
v->pm->gsu.h->setfn(v->pm, ht);
@@ -1564,7 +1565,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
v->pm = createparam(s, PM_SCALAR|PM_UNSET);
paramtab = tht;
}
- v->isarr = (*inv ? SCANPM_WANTINDEX : 0);
+ v->scanflags = (*inv ? SCANPM_WANTINDEX : 0);
v->start = 0;
*inv = 0; /* We've already obtained the "index" (key) */
*w = v->end = -1;
@@ -1574,7 +1575,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (isset(KSHARRAYS) && r >= 0)
r++;
}
- if (word && !v->isarr) {
+ if (word && !v->scanflags) {
s = t = getstrvalue(v);
i = wordcount(s, sep, 0);
if (r < 0)
@@ -1593,7 +1594,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
*w = (zlong)(s - t);
return (a2 ? s : d + 1) - t;
- } else if (!v->isarr && !word) {
+ } else if (!v->scanflags && !word) {
int lastcharlen = 1;
s = getstrvalue(v);
/*
@@ -1641,7 +1642,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
}
}
} else {
- if (!v->isarr && !word && !quote_arg) {
+ if (!v->scanflags && !word && !quote_arg) {
l = strlen(s);
if (a2) {
if (!l || *s != '*') {
@@ -1663,7 +1664,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (quote_arg) {
untokenize(s);
/* Scalar (e) needs implicit asterisk tokens */
- if (!v->isarr && !word) {
+ if (!v->scanflags && !word) {
l = strlen(s);
d = (char *) hcalloc(l + 2);
if (a2) {
@@ -1683,27 +1684,27 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
} else
pprog = NULL;
- if (v->isarr) {
+ if (v->scanflags) {
if (ishash) {
scanprog = pprog;
scanstr = s;
if (keymatch)
- v->isarr |= SCANPM_KEYMATCH;
+ v->scanflags |= SCANPM_KEYMATCH;
else {
if (!pprog)
return 1;
if (ind)
- v->isarr |= SCANPM_MATCHKEY;
+ v->scanflags |= SCANPM_MATCHKEY;
else
- v->isarr |= SCANPM_MATCHVAL;
+ v->scanflags |= SCANPM_MATCHVAL;
}
if (down)
- v->isarr |= SCANPM_MATCHMANY;
+ v->scanflags |= SCANPM_MATCHMANY;
if ((ta = getvaluearr(v)) &&
- (*ta || ((v->isarr & SCANPM_MATCHMANY) &&
- (v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
- SCANPM_KEYMATCH))))) {
- *inv = (v->flags & VALFLAG_INV) ? 1 : 0;
+ (*ta || ((v->scanflags & SCANPM_MATCHMANY) &&
+ (v->scanflags & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
+ SCANPM_KEYMATCH))))) {
+ *inv = (v->valflags & VALFLAG_INV) ? 1 : 0;
*w = v->end;
scanprog = NULL;
return 1;
@@ -1968,19 +1969,20 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
* v: In/Out parameter. Its .start and .end members (at least) will be updated
* with the parsed indices.
*
- * flags: can be either SCANPM_DQUOTED or zero. Other bits are not used.
+ * scanflags: can be a combination of SCANPM_DQUOTED, SCANPM_NOEXEC, and
+ * SCANPM_CHECKING. Other bits are not used.
*/
/**/
int
-getindex(char **pptr, Value v, int flags)
+getindex(char **pptr, Value v, int scanflags)
{
int start, end, inv = 0;
char *s = *pptr, *tbrack;
*s++ = '[';
/* Error handled after untokenizing */
- s = parse_subscript(s, flags & SCANPM_DQUOTED, ']');
+ s = parse_subscript(s, scanflags & SCANPM_DQUOTED, ']');
/* Now we untokenize everything except inull() markers so we can check *
* for the '*' and '@' special subscripts. The inull()s are removed *
* in getarg() after we know whether we're doing reverse indexing. */
@@ -2000,8 +2002,8 @@ getindex(char **pptr, Value v, int flags)
}
s = *pptr + 1;
if ((s[0] == '*' || s[0] == '@') && s + 1 == tbrack) {
- if ((v->isarr || IS_UNSET_VALUE(v)) && s[0] == '@')
- v->isarr |= SCANPM_ISVAR_AT;
+ if ((v->scanflags || IS_UNSET_VALUE(v)) && s[0] == '@')
+ v->scanflags |= SCANPM_ISVAR_AT;
v->start = 0;
v->end = -1;
s += 2;
@@ -2010,10 +2012,10 @@ getindex(char **pptr, Value v, int flags)
int startprevlen, startnextlen;
start = getarg(&s, &inv, v, 0, &we, &startprevlen, &startnextlen,
- flags);
+ scanflags);
if (inv) {
- if (!v->isarr && start != 0) {
+ if (!v->scanflags && start != 0) {
char *t, *p;
t = getstrvalue(v);
/*
@@ -2065,9 +2067,9 @@ getindex(char **pptr, Value v, int flags)
}
if (start > 0 && (isset(KSHARRAYS) || (v->pm->node.flags & PM_HASHED)))
start--;
- if (v->isarr != SCANPM_WANTINDEX) {
- v->flags |= VALFLAG_INV;
- v->isarr = 0;
+ if (v->scanflags != SCANPM_WANTINDEX) {
+ v->valflags |= VALFLAG_INV;
+ v->scanflags = 0;
v->start = start;
v->end = start + 1;
}
@@ -2084,7 +2086,7 @@ getindex(char **pptr, Value v, int flags)
if ((com = (*s == ','))) {
s++;
- end = getarg(&s, &inv, v, 1, &dummy, NULL, NULL, flags);
+ end = getarg(&s, &inv, v, 1, &dummy, NULL, NULL, scanflags);
} else {
end = we ? we : start;
}
@@ -2119,18 +2121,18 @@ getindex(char **pptr, Value v, int flags)
* for setting elements. Set the indexes
* to a range that returns empty for other accesses.
*/
- v->flags |= VALFLAG_EMPTY;
+ v->valflags |= VALFLAG_EMPTY;
start = -1;
com = 1;
}
}
if (s == tbrack) {
s++;
- if (v->isarr && !com &&
- (!(v->isarr & SCANPM_MATCHMANY) ||
- !(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
- SCANPM_KEYMATCH))))
- v->isarr = 0;
+ if (v->scanflags && !com &&
+ (!(v->scanflags & SCANPM_MATCHMANY) ||
+ !(v->scanflags & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
+ SCANPM_KEYMATCH))))
+ v->scanflags = 0;
v->start = start;
v->end = end;
} else
@@ -2152,12 +2154,12 @@ getvalue(Value v, char **pptr, int bracks)
/**/
mod_export Value
-fetchvalue(Value v, char **pptr, int bracks, int flags)
+fetchvalue(Value v, char **pptr, int bracks, int scanflags)
{
char *s, *t, *ie;
char sav, c;
int ppar = 0;
- int itype = (flags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC;
+ int itype = (scanflags & SCANPM_NONAMESPC) ? IIDENT : INAMESPC;
s = t = *pptr;
@@ -2195,9 +2197,11 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
else
v = (Value) hcalloc(sizeof *v);
v->pm = argvparam;
- v->flags = 0;
+ v->scanflags = 0;
+ v->valflags = 0;
v->start = ppar - 1;
v->end = ppar;
+ v->arr = NULL;
if (sav)
*s = sav;
} else {
@@ -2206,7 +2210,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
int isrefslice = 0;
isvarat = (t[0] == '@' && !t[1]);
- if (flags & SCANPM_NONAMEREF)
+ if (scanflags & SCANPM_NONAMEREF)
pm = (Param) paramtab->getnode2(paramtab, *t == '0' ? "0" : t);
else
pm = (Param) paramtab->getnode(paramtab, *t == '0' ? "0" : t);
@@ -2225,7 +2229,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
memset(v, 0, sizeof(*v));
else
v = (Value) hcalloc(sizeof *v);
- if ((pm->node.flags & PM_NAMEREF) && !(flags & SCANPM_NONAMEREF)) {
+ if ((pm->node.flags & PM_NAMEREF) && !(scanflags & SCANPM_NONAMEREF)) {
char *refname = GETREFNAME(pm);
if (refname && *refname) {
/* only happens for namerefs pointing to array elements */
@@ -2248,7 +2252,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
!(pm->node.flags & PM_DECLARED)))
return NULL;
if (ss) {
- flags |= SCANPM_NOEXEC;
+ scanflags |= SCANPM_NOEXEC;
*ss = sav;
s = dyncat(ss,*pptr);
isrefslice = 1;
@@ -2256,27 +2260,29 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
s = *pptr;
}
}
+ v->scanflags = 0;
if (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)) {
- /* Overload v->isarr as the flag bits for hashed arrays. */
- v->isarr = flags | (isvarat ? SCANPM_ISVAR_AT : 0);
+ /* Overload v->scanflags as the flag bits for hashed arrays. */
+ v->scanflags = scanflags | (isvarat ? SCANPM_ISVAR_AT : 0);
/* If no flags were passed, we need something to represent *
* `true' yet differ from an explicit WANTVALS. Use a *
* special flag for this case. */
- if (!v->isarr)
- v->isarr = SCANPM_ARRONLY;
+ if (!v->scanflags)
+ v->scanflags = SCANPM_ARRONLY;
}
v->pm = pm;
- v->flags = isrefslice ? VALFLAG_REFSLICE : 0;
+ v->valflags = isrefslice ? VALFLAG_REFSLICE : 0;
v->start = 0;
v->end = -1;
+ v->arr = NULL;
if (bracks > 0 && (*s == '[' || *s == Inbrack)) {
- if (getindex(&s, v, flags)) {
+ if (getindex(&s, v, scanflags)) {
*pptr = s;
return v;
}
- } else if (!(flags & SCANPM_ASSIGNING) && v->isarr &&
+ } else if (!(scanflags & SCANPM_ASSIGNING) && v->scanflags &&
itype_end(t, INAMESPC, 1) != t && isset(KSHARRAYS))
- v->end = 1, v->isarr = 0;
+ v->end = 1, v->scanflags = 0;
}
if (!bracks && *s)
return NULL;
@@ -2324,7 +2330,7 @@ getstrvalue(Value v)
if (!v)
return hcalloc(1);
- if ((v->flags & VALFLAG_INV) && !(v->pm->node.flags & PM_HASHED)) {
+ if ((v->valflags & VALFLAG_INV) && !(v->pm->node.flags & PM_HASHED)) {
sprintf(buf, "%d", v->start);
s = dupstring(buf);
return s;
@@ -2332,8 +2338,8 @@ getstrvalue(Value v)
switch(PM_TYPE(v->pm->node.flags)) {
case PM_HASHED:
- /* (!v->isarr) should be impossible unless emulating ksh */
- if (!v->isarr && EMULATION(EMULATE_KSH)) {
+ /* (!v->scanflags) should be impossible unless emulating ksh */
+ if (!v->scanflags && EMULATION(EMULATE_KSH)) {
s = dupstring("[0]");
if (getindex(&s, v, 0) == 0)
s = getstrvalue(v);
@@ -2341,7 +2347,7 @@ getstrvalue(Value v)
} /* else fall through */
case PM_ARRAY:
ss = getvaluearr(v);
- if (v->isarr)
+ if (v->scanflags)
s = sepjoin(ss, NULL, 1);
else {
if (v->start < 0)
@@ -2368,7 +2374,7 @@ getstrvalue(Value v)
break;
}
- if (v->flags & VALFLAG_SUBST) {
+ if (v->valflags & VALFLAG_SUBST) {
if (v->pm->node.flags & (PM_LEFT|PM_RIGHT_B|PM_RIGHT_Z)) {
size_t fwidth = v->pm->width ? (unsigned int)v->pm->width : MB_METASTRLEN(s);
switch (v->pm->node.flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
@@ -2535,7 +2541,7 @@ getarrvalue(Value v)
return arrdup(nular);
else if (IS_UNSET_VALUE(v))
return arrdup(&nular[1]);
- if (v->flags & VALFLAG_INV) {
+ if (v->valflags & VALFLAG_INV) {
char buf[DIGBUFSIZE];
s = arrdup(nular);
@@ -2584,9 +2590,9 @@ getintvalue(Value v)
{
if (!v)
return 0;
- if (v->flags & VALFLAG_INV)
+ if (v->valflags & VALFLAG_INV)
return v->start;
- if (v->isarr) {
+ if (v->scanflags) {
char **arr = getarrvalue(v);
if (arr) {
char *scal = sepjoin(arr, NULL, 1);
@@ -2611,9 +2617,9 @@ getnumvalue(Value v)
if (!v) {
mn.u.l = 0;
- } else if (v->flags & VALFLAG_INV) {
+ } else if (v->valflags & VALFLAG_INV) {
mn.u.l = v->start;
- } else if (v->isarr) {
+ } else if (v->scanflags) {
char **arr = getarrvalue(v);
if (arr) {
char *scal = sepjoin(arr, NULL, 1);
@@ -2640,10 +2646,13 @@ export_param(Param pm)
#if 0 /* Requires changes elsewhere in params.c and builtin.c */
if (EMULATION(EMULATE_KSH) /* isset(KSHARRAYS) */) {
struct value v;
- v.isarr = 1;
- v.flags = 0;
+ v.pm = NULL;
+ v.scanflags = (PM_TYPE(v.pm->node.flags) & PM_HASHED) ?
+ SCANPM_WANTVALS : SCANPM_ARRONLY;
+ v.valflags = 0;
v.start = 0;
v.end = -1;
+ v.arr = NULL;
val = getstrvalue(&v);
} else
#endif
@@ -2683,12 +2692,12 @@ assignstrvalue(Value v, char *val, int flags)
return;
}
if ((v->pm->node.flags & PM_HASHED) &&
- (v->isarr & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
+ (v->scanflags & (SCANPM_MATCHMANY|SCANPM_ARRONLY))) {
zerr("%s: attempt to set slice of associative array", v->pm->node.nam);
zsfree(val);
return;
}
- if (v->flags & VALFLAG_EMPTY) {
+ if (v->valflags & VALFLAG_EMPTY) {
zerr("%s: assignment to invalid subscript range", v->pm->node.nam);
zsfree(val);
return;
@@ -2708,7 +2717,7 @@ assignstrvalue(Value v, char *val, int flags)
z = v->pm->gsu.s->getfn(v->pm);
zlen = strlen(z);
- if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS))
+ if ((v->valflags & VALFLAG_INV) && unset(KSHARRAYS))
v->start--, v->end--;
if (v->start < 0) {
v->start += zlen;
@@ -2898,7 +2907,7 @@ setarrvalue(Value v, char **val)
v->pm->node.nam);
return;
}
- if (v->flags & VALFLAG_EMPTY) {
+ if (v->valflags & VALFLAG_EMPTY) {
zerr("%s: assignment to invalid subscript range", v->pm->node.nam);
freearray(val);
return;
@@ -2927,7 +2936,7 @@ setarrvalue(Value v, char **val)
q = old;
- if ((v->flags & VALFLAG_INV) && unset(KSHARRAYS)) {
+ if ((v->valflags & VALFLAG_INV) && unset(KSHARRAYS)) {
if (v->start > 0)
v->start--;
v->end--;
@@ -3225,7 +3234,7 @@ assignsparam(char *s, char *val, int flags)
createparam(t, PM_SCALAR);
created = 1;
} else if ((((v->pm->node.flags & PM_ARRAY) &&
- !(v->flags & VALFLAG_REFSLICE) &&
+ !(v->valflags & VALFLAG_REFSLICE) &&
!(flags & ASSPM_AUGMENT)) ||
(v->pm->node.flags & PM_HASHED)) &&
!(v->pm->node.flags & (PM_SPECIAL|PM_TIED)) &&
@@ -3315,7 +3324,7 @@ assignsparam(char *s, char *val, int flags)
kshappend:
/* treat slice as the end element */
v->start = sstart = v->end > 0 ? v->end - 1 : v->end;
- v->isarr = 0;
+ v->scanflags = 0;
var = getstrvalue(v);
v->start = sstart;
copy = val;
@@ -3386,7 +3395,7 @@ assignaparam(char *s, char **val, int flags)
createparam(t, PM_ARRAY);
created = 1;
} else if (!(PM_TYPE(v->pm->node.flags) & (PM_ARRAY|PM_HASHED)) &&
- !(v->flags & VALFLAG_REFSLICE) &&
+ !(v->valflags & VALFLAG_REFSLICE) &&
!(v->pm->node.flags & (PM_SPECIAL|PM_TIED))) {
int uniq = v->pm->node.flags & PM_UNIQUE;
if ((flags & ASSPM_AUGMENT) && !(v->pm->node.flags & PM_UNSET)) {
@@ -3614,7 +3623,7 @@ sethparam(char *s, char **val)
createparam(t, PM_HASHED);
checkcreate = 1;
} else if (!(PM_TYPE(v->pm->node.flags) & PM_HASHED) &&
- !(v->flags & VALFLAG_REFSLICE)) {
+ !(v->valflags & VALFLAG_REFSLICE)) {
if (!(v->pm->node.flags & PM_SPECIAL)) {
if (resetparam(v->pm, PM_HASHED)) {
unqueue_signals();
diff --git a/Src/subst.c b/Src/subst.c
index 8d730163e..9f0eccd16 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -640,7 +640,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
* our caller (if they provided for that result). */
if (a && (l > 1 || foo.list.flags & LF_ARRAY)) {
*a = r;
- *isarr = SCANPM_MATCHMANY;
+ *isarr = 1;
return 0;
}
*s = sepjoin(r, sep, 1);
@@ -1649,7 +1649,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* (I mean the one explicitly marked as such). The value 2
* indicates an array has come from splitting a scalar. We use
* that to override the usual rule that in double quotes we don't
- * remove empty elements (so "${(s.:):-foo::bar}" produces two
+ * remove empty elements (so "${(s.:.):-foo::bar}" produces two
* words). This seems to me to be quite the wrong thing to do,
* but it looks like code may be relying on it. So we require (@)
* as well before we keep the empty fields (look for assignments
@@ -2802,7 +2802,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
((unset(KSHARRAYS) || inbrace) ? 1 : -1)),
scanflags)) ||
(v->pm && (v->pm->node.flags & PM_UNSET)) ||
- (v->flags & VALFLAG_EMPTY)))
+ (v->valflags & VALFLAG_EMPTY)))
vunset = 1;
if (wantt) {
/*
@@ -2893,7 +2893,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
else
pm->u.str = val;
v = (Value) hcalloc(sizeof *v);
- v->isarr = isarr;
+ v->scanflags = isarr ? SCANPM_ARRONLY : 0;
v->pm = pm;
v->end = -1;
if (getindex(&s, v, qt ? SCANPM_DQUOTED : 0) || s == os)
@@ -2905,21 +2905,22 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* array (aval) value. TODO: move val and aval into
* a structure with a discriminator. Hope we can make
* more things array values at this point and dearrayify later.
- * v->isarr tells us whether the stuff from down below looks
+ * v->scanflags tells us whether the stuff from down below looks
* like an array.
*
* I think we get to discard the existing value of isarr
* here because it's already been taken account of, either
* in the subexp stuff or immediately above.
*/
- if ((isarr = v->isarr)) {
+ if ((isarr =
+ (v->scanflags & SCANPM_ISVAR_AT) ? -1 : v->scanflags ? 1 : 0)) {
/*
- * No way to get here with v->flags & VALFLAG_INV, so
+ * No way to get here with v->valflags & VALFLAG_INV, so
* getvaluearr() is called by getarrvalue(); needn't test
* PM_HASHED.
*/
- if (v->isarr == SCANPM_WANTINDEX) {
- isarr = v->isarr = 0;
+ if (v->scanflags == SCANPM_WANTINDEX) {
+ isarr = v->scanflags = 0;
val = dupstring(v->pm->node.nam);
} else
aval = getarrvalue(v);
@@ -2942,9 +2943,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
if (v->start < 0) {
tmplen = arrlen(v->pm->gsu.a->getfn(v->pm));
- v->start += tmplen + ((v->flags & VALFLAG_INV) ? 1 : 0);
+ v->start += tmplen + ((v->valflags & VALFLAG_INV) ? 1 : 0);
}
- if (!(v->flags & VALFLAG_INV))
+ if (!(v->valflags & VALFLAG_INV))
if (v->start < 0 ||
(tmplen != -1
? v->start >= tmplen
@@ -2960,7 +2961,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* if we allow them to applied on every call, so
* set the flag that allows them to be substituted.
*/
- v->flags |= VALFLAG_SUBST;
+ v->valflags |= VALFLAG_SUBST;
val = getstrvalue(v);
}
}
@@ -3010,8 +3011,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* substitution is in quotes) always good enough? Potentially
* we may be OK by now --- all potential `@'s and subexpressions
* have been handled, including any [@] index which comes up
- * by virtue of v->isarr being set to SCANPM_ISVAR_AT which
- * is now in isarr.
+ * by virtue of v->scanflags being set to SCANPM_ISVAR_AT which
+ * is now in isarr being set to -1.
*
* However, if we are replacing multsub() with something that
* doesn't mangle arrays, we may need to delay this step until after
diff --git a/Src/zsh.h b/Src/zsh.h
index b82c35aea..ef69e97ab 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -744,8 +744,12 @@ struct multio {
struct value {
Param pm; /* parameter node */
char **arr; /* cache for hash turned into array */
- int isarr;
- int flags; /* flags defined below */
+ int scanflags; /* set of SCANPM flags as well as an is-array
+ * marker. The field must be non-zero iff the
+ * value struct represents an array or an
+ * associative array. For plain arrays, use
+ * SCANPM_ARRONLY. */
+ int valflags; /* flags defined below */
int start; /* first element of array slice, or -1 */
int end; /* 1-rel last element of array slice, or -1 */
};
@@ -1965,11 +1969,7 @@ struct tieddata {
#define SCANPM_NOEXEC (1<<11) /* No command substitutions, etc. */
#define SCANPM_NONAMESPC (1<<12) /* namespace syntax not allowed */
#define SCANPM_NONAMEREF (1<<13) /* named references are not followed */
-
-/* "$foo[@]"-style substitution
- * Only sign bit is significant
- */
-#define SCANPM_ISVAR_AT ((int)(((unsigned int)-1)<<15))
+#define SCANPM_ISVAR_AT (1<<14) /* "$foo[@]"-style substitution */
/*
* Flags for doing matches inside parameter substitutions, i.e.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author