mirror of
https://git.code.sf.net/p/zsh/code
synced 2026-04-18 06:53:35 -04:00
54093 (tweaked per 54101): Cleanup isarr fields and variables
This commit is contained in:
committed by
Oliver Kiddle
parent
735afc8e8a
commit
8a3ee5a802
@@ -1,5 +1,11 @@
|
||||
2025-11-24 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* Philippe: 54093 (tweaked per 54101): Src/Modules/db_gdbm.c,
|
||||
Src/Modules/mapfile.c, Src/Modules/parameter.c,
|
||||
Src/Modules/zutil.c, Src/Zle/complete.c, Src/Zle/zle_main.c,
|
||||
Src/Zle/zle_params.c, Src/builtin.c, Src/glob.c, Src/params.c,
|
||||
Src/subst.c, Src/zsh.h: Cleanup isarr fields and variables
|
||||
|
||||
* 54104: Src/parse.c, Src/zsh.h: fix bug with packing strings
|
||||
into wordcode
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 *));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3927,10 +3927,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;
|
||||
@@ -3941,7 +3941,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] = "";
|
||||
|
||||
@@ -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);
|
||||
|
||||
184
Src/params.c
184
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;
|
||||
@@ -1318,7 +1319,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
|
||||
@@ -1340,7 +1341,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;
|
||||
@@ -1464,23 +1465,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;
|
||||
}
|
||||
@@ -1541,7 +1542,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;
|
||||
@@ -1551,7 +1552,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);
|
||||
@@ -1563,7 +1564,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;
|
||||
@@ -1573,7 +1574,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)
|
||||
@@ -1592,7 +1593,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);
|
||||
/*
|
||||
@@ -1640,7 +1641,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 != '*') {
|
||||
@@ -1662,7 +1663,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) {
|
||||
@@ -1682,27 +1683,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;
|
||||
@@ -1967,19 +1968,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. */
|
||||
@@ -1999,8 +2001,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;
|
||||
@@ -2009,10 +2011,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);
|
||||
/*
|
||||
@@ -2064,9 +2066,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;
|
||||
}
|
||||
@@ -2083,7 +2085,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;
|
||||
}
|
||||
@@ -2118,18 +2120,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
|
||||
@@ -2151,12 +2153,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;
|
||||
|
||||
@@ -2189,12 +2191,10 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
|
||||
if ((sav = *s))
|
||||
*s = '\0';
|
||||
if (ppar) {
|
||||
if (v)
|
||||
memset(v, 0, sizeof(*v));
|
||||
else
|
||||
v = (Value) hcalloc(sizeof *v);
|
||||
if (!v)
|
||||
v = (Value) zhalloc(sizeof *v);
|
||||
memset(v, 0, sizeof(*v));
|
||||
v->pm = argvparam;
|
||||
v->flags = 0;
|
||||
v->start = ppar - 1;
|
||||
v->end = ppar;
|
||||
if (sav)
|
||||
@@ -2205,7 +2205,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);
|
||||
@@ -2220,11 +2220,7 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
|
||||
if (!pm || ((pm->node.flags & PM_UNSET) &&
|
||||
!(pm->node.flags & PM_DECLARED)))
|
||||
return NULL;
|
||||
if (v)
|
||||
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 */
|
||||
@@ -2247,7 +2243,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;
|
||||
@@ -2255,27 +2251,30 @@ fetchvalue(Value v, char **pptr, int bracks, int flags)
|
||||
s = *pptr;
|
||||
}
|
||||
}
|
||||
if (!v)
|
||||
v = (Value) zhalloc(sizeof *v);
|
||||
memset(v, 0, sizeof(*v));
|
||||
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->start = 0;
|
||||
if (isrefslice)
|
||||
v->valflags = VALFLAG_REFSLICE;
|
||||
v->end = -1;
|
||||
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;
|
||||
@@ -2323,7 +2322,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;
|
||||
@@ -2331,8 +2330,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);
|
||||
@@ -2340,7 +2339,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)
|
||||
@@ -2367,7 +2366,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)) {
|
||||
@@ -2534,7 +2533,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);
|
||||
@@ -2583,9 +2582,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);
|
||||
@@ -2610,9 +2609,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);
|
||||
@@ -2639,10 +2638,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
|
||||
@@ -2682,12 +2684,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;
|
||||
@@ -2707,7 +2709,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;
|
||||
@@ -2897,7 +2899,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;
|
||||
@@ -2926,7 +2928,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--;
|
||||
@@ -3224,7 +3226,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)) &&
|
||||
@@ -3314,7 +3316,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;
|
||||
@@ -3385,7 +3387,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)) {
|
||||
@@ -3613,7 +3615,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();
|
||||
|
||||
29
Src/subst.c
29
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
|
||||
|
||||
14
Src/zsh.h
14
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.
|
||||
|
||||
Reference in New Issue
Block a user