zsh-workers
 help / color / mirror / code / Atom feed
* Array slices (PWS's unposted Etc/NEWS change)
@ 2000-06-01 15:50 Bart Schaefer
  2000-06-01 20:51 ` Wayne Davison
  2000-06-02  2:08 ` Wayne Davison
  0 siblings, 2 replies; 3+ messages in thread
From: Bart Schaefer @ 2000-06-01 15:50 UTC (permalink / raw)
  To: zsh-workers

 - Array slices ${array[a,b]} with b < a now correctly have zero length.

This isn't an accurate description.  The patch makes ${array[a,0]} have zero
length, for any value of a, unless ksharrays is set.  Previously $array[1,0]
behaved like $array[1,1], which was not the same as any other value of a.

Unfortunately (?) that means $array[0,0] != $array[0].  I'm not sure whether
that's likely to break anything.

That patch has also caused the failure in the last example here:
---------------------------
zagzig% foo=(a b c d e f g)
zagzig% echo $foo[1,4]
a b c d
zagzig% echo $foo[1,-4]
a b c d
zagzig% echo $foo[4,1]

zagzig% echo $foo[-4,1]
d e f g
---------------------------

Yowtch.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Array slices (PWS's unposted Etc/NEWS change)
  2000-06-01 15:50 Array slices (PWS's unposted Etc/NEWS change) Bart Schaefer
@ 2000-06-01 20:51 ` Wayne Davison
  2000-06-02  2:08 ` Wayne Davison
  1 sibling, 0 replies; 3+ messages in thread
From: Wayne Davison @ 2000-06-01 20:51 UTC (permalink / raw)
  To: Zsh Workers

On Thu, 1 Jun 2000, Bart Schaefer wrote:
> Unfortunately (?) that means $array[0,0] != $array[0].

This is quite easy to fix, so I think it should be.  I've appended
a patch (which I will check into cvs momentarily).

> That patch has also caused the failure in the last example here:
> ---------------------------
> zagzig% foo=(a b c d e f g)
> zagzig% echo $foo[-4,1]
> d e f g
> ---------------------------
> 
> Yowtch.

Ick.  Negative start values combined with positive end values are
currently broken.  This makes me think that I should have gone with
my alternative internal representation which was to change the end
position to be a 1-relative index (rather than the old 0-relative
index or the new length).  I'll look into this to see what might be
the cleanest solution.

..wayne..

---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: Src/params.c
@@ -941,7 +941,7 @@
 	    r = isset(KSHARRAYS) ? 1 : 0;
 	} else {
 	    r = mathevalarg(s, &s);
-	    if ((!r && !a2) || (isset(KSHARRAYS) && r >= 0))
+	    if (isset(KSHARRAYS) && r >= 0)
 		r++;
 	}
 	if (word && !v->isarr) {
@@ -1185,19 +1185,19 @@
 	} else {
 	    int com;
 
-	    if (start > 0)
-		start--;
 	    if ((com = (*s == ','))) {
 		s++;
 		len = getarg(&s, &inv, v, 1, &dummy);
 		if (len > 0) {
-		    len -= start;
+		    len -= start - 1;
 		    if (len < 0)
 			len = 0;
 		}
 	    } else {
 		len = wlen ? wlen : 1;
 	    }
+	    if (start > 0)
+		start--;
 	    if (*s == ']' || *s == Outbrack) {
 		s++;
 		if (v->isarr && len == 1 && !com &&
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Array slices (PWS's unposted Etc/NEWS change)
  2000-06-01 15:50 Array slices (PWS's unposted Etc/NEWS change) Bart Schaefer
  2000-06-01 20:51 ` Wayne Davison
@ 2000-06-02  2:08 ` Wayne Davison
  1 sibling, 0 replies; 3+ messages in thread
From: Wayne Davison @ 2000-06-02  2:08 UTC (permalink / raw)
  To: Zsh Workers

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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2000-06-02  2:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-06-01 15:50 Array slices (PWS's unposted Etc/NEWS change) Bart Schaefer
2000-06-01 20:51 ` Wayne Davison
2000-06-02  2:08 ` Wayne Davison

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