From: Wayne Davison <wayned@users.sourceforge.net>
To: Zsh Workers <zsh-workers@sunsite.auc.dk>
Subject: Re: Array slices (PWS's unposted Etc/NEWS change)
Date: Thu, 1 Jun 2000 19:08:57 -0700 (PDT) [thread overview]
Message-ID: <Pine.LNX.4.21.0006011856170.24307-100000@phong.blorf.net> (raw)
In-Reply-To: <1000601155002.ZM3182@candle.brasslantern.com>
OK, I went ahead and changed the array code to use "end" instead of
"len". The "end" value is a 1--relative index of the last item (or
you can think of it as pointing one past the last item). This fixes
the case where the starting offset is negative (relative to the end of
the array) but the end value is positive (relative to the start of the
array).
I also checked in a set of array-indexing tests in the "Test" dir.
The new code I just committed now passes all these tests.
..wayne..
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: Src/glob.c
@@ -921,8 +921,8 @@
Complist q; /* pattern after parsing */
char *ostr = (char *)getdata(np); /* the pattern before the parser */
/* chops it up */
- int first = 0, count = -1; /* index of first match to return */
- /* plus number of items */
+ int first = 0, end = -1; /* index of first match to return */
+ /* and index+1 of the last match */
struct globdata saved; /* saved glob state */
if (unset(GLOBOPT) || !haswilds(ostr)) {
@@ -1334,7 +1334,7 @@
v.isarr = SCANPM_WANTVALS;
v.pm = NULL;
- v.len = -1;
+ v.end = -1;
v.inv = 0;
if (getindex(&s, &v) || s == os) {
zerr("invalid subscript", NULL, 0);
@@ -1342,7 +1342,7 @@
return;
}
first = v.start;
- count = v.len;
+ end = v.end;
break;
}
default:
@@ -1426,17 +1426,18 @@
qsort((void *) & matchbuf[0], matchct, sizeof(struct gmatch),
(int (*) _((const void *, const void *)))gmatchcmp);
- if (first < 0)
+ if (first < 0) {
first += matchct;
- if (count < 0)
- count += matchct + 1;
- if (first < 0)
- first = 0;
- if (count > matchct - first)
- count = matchct - first;
- if (count > 0) {
- matchptr = matchbuf + matchct - first - count;
- while (count-- > 0) { /* insert matches in the arg list */
+ if (first < 0)
+ first = 0;
+ }
+ if (end < 0)
+ end += matchct + 1;
+ else if (end > matchct)
+ end = matchct;
+ if (end -= first > 0) {
+ matchptr = matchbuf + matchct - first - end;
+ while (end-- > 0) { /* insert matches in the arg list */
insertlinknode(list, node, matchptr->name);
matchptr++;
}
Index: Src/params.c
@@ -398,7 +398,7 @@
v.isarr = (PM_TYPE(v.pm->flags) & (PM_ARRAY|PM_HASHED));
v.inv = 0;
v.start = 0;
- v.len = -1;
+ v.end = -1;
paramvals[numparamvals] = getstrvalue(&v);
if (flags & SCANPM_MATCHVAL) {
if (pattry(scanprog, paramvals[numparamvals])) {
@@ -441,7 +441,7 @@
v->arr = paramvalarr(v->pm->gets.hfn(v->pm), v->isarr);
/* Can't take numeric slices of associative arrays */
v->start = 0;
- v->len = numparamvals + 1;
+ v->end = numparamvals + 1;
return v->arr;
} else
return NULL;
@@ -937,7 +937,7 @@
v->isarr = (*inv ? SCANPM_WANTINDEX : 0);
v->start = 0;
*inv = 0; /* We've already obtained the "index" (key) */
- *w = v->len = -1;
+ *w = v->end = -1;
r = isset(KSHARRAYS) ? 1 : 0;
} else {
r = mathevalarg(s, &s);
@@ -960,7 +960,7 @@
return 0;
if (!a2 && *tt != ',')
- *w = (zlong)(s - d) - 1;
+ *w = (zlong)(s - t);
return (a2 ? s : d + 1) - t;
} else if (!v->isarr && !word) {
@@ -1019,7 +1019,7 @@
(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
SCANPM_KEYMATCH))))) {
*inv = v->inv;
- *w = v->len;
+ *w = v->end;
return 1;
}
} else
@@ -1070,7 +1070,7 @@
if (!--r) {
r = (zlong)(t - s + (a2 ? -1 : 1));
if (!a2 && *tt != ',')
- *w = strlen(ta[i]) - 1;
+ *w = r + strlen(ta[i]) - 1;
return r;
}
return a2 ? -1 : 0;
@@ -1134,7 +1134,7 @@
int
getindex(char **pptr, Value v)
{
- int start, len, inv = 0;
+ int start, end, inv = 0;
char *s = *pptr, *tbrack;
*s++ = '[';
@@ -1147,12 +1147,12 @@
if ((v->isarr || IS_UNSET_VALUE(v)) && s[0] == '@')
v->isarr |= SCANPM_ISVAR_AT;
v->start = 0;
- v->len = -1;
+ v->end = -1;
s += 2;
} else {
- zlong wlen = 0, dummy;
+ zlong we = 0, dummy;
- start = getarg(&s, &inv, v, 0, &wlen);
+ start = getarg(&s, &inv, v, 0, &we);
if (inv) {
if (!v->isarr && start != 0) {
@@ -1171,7 +1171,7 @@
v->inv = 1;
v->isarr = 0;
v->start = start;
- v->len = 1;
+ v->end = start + 1;
}
if (*s == ',') {
zerr("invalid subscript", NULL, 0);
@@ -1187,26 +1187,23 @@
if ((com = (*s == ','))) {
s++;
- len = getarg(&s, &inv, v, 1, &dummy);
- if (len >= 0) {
- len -= start - 1;
- if (len < 0)
- len = 0;
- }
+ end = getarg(&s, &inv, v, 1, &dummy);
} else {
- len = wlen ? wlen : 1;
+ end = we ? we : start;
}
if (start > 0)
start--;
+ else if (start == 0 && end == 0)
+ end++;
if (*s == ']' || *s == Outbrack) {
s++;
- if (v->isarr && len == 1 && !com &&
+ if (v->isarr && start == end-1 && !com &&
(!(v->isarr & SCANPM_MATCHMANY) ||
!(v->isarr & (SCANPM_MATCHKEY | SCANPM_MATCHVAL |
SCANPM_KEYMATCH))))
v->isarr = 0;
v->start = start;
- v->len = len;
+ v->end = end;
} else
s = *pptr;
}
@@ -1268,7 +1265,7 @@
v->pm = argvparam;
v->inv = 0;
v->start = ppar - 1;
- v->len = 1;
+ v->end = ppar;
if (sav)
*s = sav;
} else {
@@ -1299,7 +1296,7 @@
v->pm = pm;
v->inv = 0;
v->start = 0;
- v->len = -1;
+ v->end = -1;
if (bracks > 0 && (*s == '[' || *s == Inbrack)) {
if (getindex(&s, v)) {
*pptr = s;
@@ -1307,21 +1304,25 @@
}
} else if (!(flags & SCANPM_ASSIGNING) && v->isarr &&
iident(*t) && isset(KSHARRAYS))
- v->len = 1, v->isarr = 0;
+ v->end = 1, v->isarr = 0;
}
if (!bracks && *s)
return NULL;
*pptr = s;
- if (v->start > MAX_ARRLEN ||
- v->start < -MAX_ARRLEN) {
- zerr("subscript too %s: %d", (v->start < 0) ? "small" : "big",
- v->start + !isset(KSHARRAYS));
+ if (v->start > MAX_ARRLEN) {
+ zerr("subscript too %s: %d", "big", v->start + !isset(KSHARRAYS));
+ return NULL;
+ }
+ if (v->start < -MAX_ARRLEN) {
+ zerr("%s: subscript too %s: %d", "small", v->start);
+ return NULL;
+ }
+ if (v->end > MAX_ARRLEN+1) {
+ zerr("%s: subscript too %s: %d", "big", v->end - !!isset(KSHARRAYS));
return NULL;
}
- if (v->start + v->len > MAX_ARRLEN ||
- v->start + v->len < -MAX_ARRLEN) {
- zerr("subscript too %s: %d", (v->len < 0) ? "small" : "big",
- v->start + v->len - !!isset(KSHARRAYS));
+ if (v->end < -MAX_ARRLEN) {
+ zerr("%s: subscript too %s: %d", "small", v->end);
return NULL;
}
return v;
@@ -1380,18 +1381,18 @@
break;
}
- if (v->start == 0 && v->len == -1)
+ if (v->start == 0 && v->end == -1)
return s;
if (v->start < 0)
v->start += strlen(s);
- if (v->len < 0)
- v->len += strlen(s) - v->start + 1;
+ if (v->end < 0)
+ v->end += strlen(s) + 1;
s = (v->start > (int)strlen(s)) ? dupstring("") : dupstring(s + v->start);
- if (v->len <= 0)
+ if (v->end <= v->start)
s[0] = '\0';
- else if (v->len <= (int)strlen(s))
- s[v->len + (s[v->len - 1] == Meta)] = '\0';
+ else if (v->end - v->start <= (int)strlen(s))
+ s[v->end - v->start + (s[v->end - v->start - 1] == Meta)] = '\0';
return s;
}
@@ -1417,20 +1418,20 @@
return s;
}
s = getvaluearr(v);
- if (v->start == 0 && v->len == -1)
+ if (v->start == 0 && v->end == -1)
return s;
if (v->start < 0)
v->start += arrlen(s);
- if (v->len < 0)
- v->len += arrlen(s) - v->start + 1;
+ if (v->end < 0)
+ v->end += arrlen(s) + 1;
if (v->start > arrlen(s) || v->start < 0)
s = arrdup(nular);
else
s = arrdup(s + v->start);
- if (v->len <= 0)
+ if (v->end <= v->start)
s[0] = NULL;
- else if (v->len <= arrlen(s))
- s[v->len] = NULL;
+ else if (v->end - v->start <= arrlen(s))
+ s[v->end - v->start] = NULL;
return s;
}
@@ -1508,7 +1509,7 @@
v->pm->flags &= ~PM_UNSET;
switch (PM_TYPE(v->pm->flags)) {
case PM_SCALAR:
- if (v->start == 0 && v->len == -1) {
+ if (v->start == 0 && v->end == -1) {
(v->pm->sets.cfn) (v->pm, val);
if (v->pm->flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z) && !v->pm->ct)
v->pm->ct = strlen(val);
@@ -1519,7 +1520,7 @@
z = dupstring((v->pm->gets.cfn) (v->pm));
zlen = strlen(z);
if (v->inv && unset(KSHARRAYS))
- v->start--;
+ v->start--, v->end--;
if (v->start < 0) {
v->start += zlen;
if (v->start < 0)
@@ -1527,14 +1528,14 @@
}
if (v->start > zlen)
v->start = zlen;
- if (v->len < 0)
- v->len += zlen - v->start + 1;
- if (v->len > zlen - v->start)
- v->len = zlen - v->start;
- x = (char *) zalloc(strlen(val) + zlen - v->len + 1);
+ if (v->end < 0)
+ v->end += zlen + 1;
+ else if (v->end > zlen)
+ v->end = zlen;
+ x = (char *) zalloc(v->start + strlen(val) + zlen - v->end + 1);
strncpy(x, z, v->start);
strcpy(x + v->start, val);
- strcat(x + v->start, z + v->start + v->len);
+ strcat(x + v->start, z + v->end);
(v->pm->sets.cfn) (v->pm, x);
zsfree(val);
}
@@ -1631,7 +1632,7 @@
zerr("attempt to assign array value to non-array", NULL, 0);
return;
}
- if (v->start == 0 && v->len == -1) {
+ if (v->start == 0 && v->end == -1) {
if (PM_TYPE(v->pm->flags) == PM_HASHED)
arrhashsetfn(v->pm, val);
else
@@ -1646,21 +1647,23 @@
return;
}
if (v->inv && unset(KSHARRAYS))
- v->start--;
+ v->start--, v->end--;
q = old = v->pm->gets.afn(v->pm);
n = arrlen(old);
- if (v->start < 0)
+ if (v->start < 0) {
v->start += n;
- if (v->len < 0)
- v->len += n - v->start + 1;
- if (v->start < 0)
- v->start = 0;
- if (v->len < 0)
- v->len = 0;
+ if (v->start < 0)
+ v->start = 0;
+ }
+ if (v->end < 0) {
+ v->end += n + 1;
+ if (v->end < 0)
+ v->end = 0;
+ }
ll = v->start + arrlen(val);
- if (v->start + v->len - 1 < n)
- ll += n - (v->start + v->len - 1);
+ if (v->end <= n)
+ ll += n - v->end + 1;
p = new = (char **) zcalloc(sizeof(char *) * (ll + 1));
@@ -1668,8 +1671,8 @@
*p++ = i < n ? ztrdup(*q++) : ztrdup("");
for (r = val; *r;)
*p++ = ztrdup(*r++);
- if (v->start + v->len < n)
- for (q = old + v->start + v->len; *q;)
+ if (v->end < n)
+ for (q = old + v->end; *q;)
*p++ = ztrdup(*q++);
*p = NULL;
@@ -2164,7 +2167,7 @@
HashTable opmtab = paramtab, ht = 0;
char **aptr = val;
Value v = (Value) hcalloc(sizeof *v);
- v->len = -1;
+ v->end = -1;
if (alen % 2) {
freearray(val);
Index: Src/subst.c
@@ -1138,7 +1138,7 @@
v = (Value) hcalloc(sizeof *v);
v->isarr = isarr;
v->pm = pm;
- v->len = -1;
+ v->end = -1;
if (getindex(&s, v) || s == os)
break;
}
Index: Src/zsh.h
@@ -468,7 +468,7 @@
Param pm; /* parameter node */
int inv; /* should we return the index ? */
int start; /* first element of array slice, or -1 */
- int len; /* length of array slice, or -1 */
+ int end; /* 1-rel last element of array slice, or -1 */
char **arr; /* cache for hash turned into array */
};
Index: Src/Modules/mapfile.c
@@ -203,7 +203,7 @@
struct value v;
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
Index: Src/Modules/parameter.c
@@ -230,7 +230,7 @@
struct value v;
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -401,7 +401,7 @@
struct value v;
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -755,7 +755,7 @@
char *val;
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1434,7 +1434,7 @@
char *val;
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
@@ -1660,7 +1660,7 @@
char *val;
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
Index: Src/Zle/complete.c
@@ -1034,7 +1034,7 @@
pp = compkpms; cp->name; cp++, pp++)
if (!strcmp(hn->nam, cp->name)) {
v.isarr = v.inv = v.start = 0;
- v.len = -1;
+ v.end = -1;
v.arr = NULL;
v.pm = (Param) hn;
if (cp->type == PM_INTEGER)
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
prev parent reply other threads:[~2000-06-02 2:09 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-06-01 15:50 Bart Schaefer
2000-06-01 20:51 ` Wayne Davison
2000-06-02 2:08 ` Wayne Davison [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.21.0006011856170.24307-100000@phong.blorf.net \
--to=wayned@users.sourceforge.net \
--cc=zsh-workers@sunsite.auc.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).