From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14153 invoked from network); 2 Jun 2000 02:09:24 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 2 Jun 2000 02:09:24 -0000 Received: (qmail 4803 invoked by alias); 2 Jun 2000 02:09:04 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 11717 Received: (qmail 4785 invoked from network); 2 Jun 2000 02:09:02 -0000 Date: Thu, 1 Jun 2000 19:08:57 -0700 (PDT) From: Wayne Davison X-Sender: wayne@phong.blorf.net To: Zsh Workers Subject: Re: Array slices (PWS's unposted Etc/NEWS change) In-Reply-To: <1000601155002.ZM3182@candle.brasslantern.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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---