zsh-workers
 help / color / mirror / code / Atom feed
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---


      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).