Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: parameter substitution close brace tidy up



(Don't you love the English language?  In most Indo-European languages
you would need grammar in that subject line.  Whereas I just stuck some
nouns and verbs and an adverb together and it's perfectly clear. [Heavy
irony.]  How about Parameterversetzungsschlussklammeaufputz, or
something?)

This is mainly just so that people don't complain that ${i:s/foo/bar}
doesn't work any more; it checks earlier for a closing brace, nulls it
out, and remembers the position.  Much of the patch is just renaming the
variables either to use or not to use the new end-substitution variable
fstr.  There are not supposed to be any other effects, but the code here
is fiendishly complicated and I can't 100% guarantee it.  I spoilt the
purity of paramsubst() by adding a comment, too.

*** Src/subst.c.cbr	Tue Jan 13 11:42:12 1998
--- Src/subst.c	Thu Mar 19 10:32:26 1998
***************
*** 688,694 ****
  paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
  {
      char *aptr = *str;
!     char *s = aptr, *u, *idbeg, *idend, *ostr = (char *) getdata(n);
      int colf;			/* != 0 means we found a colon after the name */
      int doub = 0;		/* != 0 means we have %%, not %, or ##, not # */
      int isarr = 0;
--- 688,694 ----
  paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
  {
      char *aptr = *str;
!     char *s = aptr, *fstr, *idbeg, *idend, *ostr = (char *) getdata(n);
      int colf;			/* != 0 means we found a colon after the name */
      int doub = 0;		/* != 0 means we have %%, not %, or ##, not # */
      int isarr = 0;
***************
*** 1070,1075 ****
--- 1070,1099 ----
      if ((colf = *s == ':'))
  	s++;
  
+ 
+     /* fstr is to be the text following the substitution.  If we have *
+      * braces, we look for it here, else we infer it later on.        */
+     fstr = s;
+     if (inbrace) {
+ 	int bct;
+ 	for (bct = 1;; fstr++) {
+ 	    if (!*fstr)
+ 		break;
+ 	    else if (*fstr == Inbrace)
+ 		bct++;
+ 	    else if (*fstr == Outbrace && !--bct)
+ 		break;
+ 	}
+ 
+ 	if (bct) {
+ 	noclosebrace:
+ 	    zerr("closing brace expected", NULL, 0);
+ 	    return NULL;
+ 	}
+ 	if (*fstr)
+ 	    *fstr++ = '\0';
+     }
+ 
      /* Check for ${..?..} or ${..=..} or one of those. *
       * Only works if the name is in braces.            */
  
***************
*** 1080,1086 ****
  		    *s == '%' ||
  		    *s == '#' || *s == Pound ||
  		    *s == '?' || *s == Quest)) {
- 	int bct;
  
  	if (!flnum)
  	    flnum++;
--- 1104,1109 ----
***************
*** 1092,1119 ****
  	    s++;
  	    doub = 1;
  	}
! 	u = s + 1;
  
  	flags |= (doub << 1) | (substr << 2) | (colf << 8);
  	if (!(flags & 0xf8))
  	    flags |= 16;
  
- 	for (bct = 1; bct && *++s;) {
- 	    if (*s == Inbrace)
- 		bct++;
- 	    else if (*s == Outbrace)
- 		bct--;
- 	}
- 
- 	if (bct)
- 	    goto noclosebrace;
- 
- 	if (*s)
- 	    *s++ = '\0';
  	if (colf && !vunset)
  	    vunset = (isarr) ? !*aval : !*val || (*val == Nularg && !val[1]);
  
! 	switch (u[-1]) {
  	case '+':
  	    if (vunset) {
  		val = dupstring("");
--- 1115,1130 ----
  	    s++;
  	    doub = 1;
  	}
! 	s++;
  
  	flags |= (doub << 1) | (substr << 2) | (colf << 8);
  	if (!(flags & 0xf8))
  	    flags |= 16;
  
  	if (colf && !vunset)
  	    vunset = (isarr) ? !*aval : !*val || (*val == Nularg && !val[1]);
  
! 	switch (s[-1]) {
  	case '+':
  	    if (vunset) {
  		val = dupstring("");
***************
*** 1125,1140 ****
  	/* Fall Through! */
  	case '-':
  	    if (vunset) {
! 		val = dupstring(u);
  		multsub(&val, &aval, &isarr, NULL);
  		copied = 1;
  	    }
  	    break;
  	case ':':
! 	    if (*u != '=' && *u != Equals)
  		goto noclosebrace;
  	    vunset = 1;
! 	    u++;
  	    /* Fall through */
  	case '=':
  	case Equals:
--- 1136,1151 ----
  	/* Fall Through! */
  	case '-':
  	    if (vunset) {
! 		val = dupstring(s);
  		multsub(&val, &aval, &isarr, NULL);
  		copied = 1;
  	    }
  	    break;
  	case ':':
! 	    if (*s != '=' && *s != Equals)
  		goto noclosebrace;
  	    vunset = 1;
! 	    s++;
  	    /* Fall through */
  	case '=':
  	case Equals:
***************
*** 1143,1149 ****
  		int l;
  
  		*idend = '\0';
! 		val = dupstring(u);
  		isarr = 0;
  		if (spsep || spbreak || !arrasg)
  		    multsub(&val, NULL, NULL, sep);
--- 1154,1160 ----
  		int l;
  
  		*idend = '\0';
! 		val = dupstring(s);
  		isarr = 0;
  		if (spsep || spbreak || !arrasg)
  		    multsub(&val, NULL, NULL, sep);
***************
*** 1191,1197 ****
  		char *msg;
  
  		*idend = '\0';
! 		msg = tricat(idbeg, ": ", *u ? u : "parameter not set");
  		zerr("%s", msg, 0);
  		zsfree(msg);
  		if (!interact)
--- 1202,1208 ----
  		char *msg;
  
  		*idend = '\0';
! 		msg = tricat(idbeg, ": ", *s ? s : "parameter not set");
  		zerr("%s", msg, 0);
  		zsfree(msg);
  		if (!interact)
***************
*** 1203,1228 ****
  	case '#':
  	case Pound:
  	    if (qt)
! 		if (parse_subst_string(u)) {
  		    zerr("parse error in ${...%c...} substitution",
! 			 NULL, u[-1]);
  		    return NULL;
  		}
! 	    singsub(&u);
  
  	    if (!vunset && isarr) {
  		char **ap = aval;
  		char **pp = aval = (char **)ncalloc(sizeof(char *) * (arrlen(aval) + 1));
  
  		while ((*pp = *ap++)) {
! 		    if (getmatch(pp, u, flags, flnum))
  			pp++;
  		}
  		copied = 1;
  	    } else {
  		if (vunset)
  		    val = dupstring("");
! 		getmatch(&val, u, flags, flnum);
  		copied = 1;
  	    }
  	    break;
--- 1214,1239 ----
  	case '#':
  	case Pound:
  	    if (qt)
! 		if (parse_subst_string(s)) {
  		    zerr("parse error in ${...%c...} substitution",
! 			 NULL, s[-1]);
  		    return NULL;
  		}
! 	    singsub(&s);
  
  	    if (!vunset && isarr) {
  		char **ap = aval;
  		char **pp = aval = (char **)ncalloc(sizeof(char *) * (arrlen(aval) + 1));
  
  		while ((*pp = *ap++)) {
! 		    if (getmatch(pp, s, flags, flnum))
  			pp++;
  		}
  		copied = 1;
  	    } else {
  		if (vunset)
  		    val = dupstring("");
! 		getmatch(&val, s, flags, flnum);
  		copied = 1;
  	    }
  	    break;
***************
*** 1260,1266 ****
  		    }
  		    s = ss;
  		}
! 		if (inbrace && *s != Outbrace) {
  		    if (*s == ':' && !imeta(s[1]))
  			zerr("unrecognized modifier `%c'", NULL, s[1]);
  		    else
--- 1271,1277 ----
  		    }
  		    s = ss;
  		}
! 		if (inbrace && *s) {
  		    if (*s == ':' && !imeta(s[1]))
  			zerr("unrecognized modifier `%c'", NULL, s[1]);
  		    else
***************
*** 1269,1282 ****
  		}
  	    }
  	}
! 	if (inbrace) {
! 	    if (*s != Outbrace) {
! 	      noclosebrace:
! 		zerr("closing brace expected", NULL, 0);
! 		return NULL;
! 	    }
! 	    s++;
! 	}
      }
      if (errflag)
  	return NULL;
--- 1280,1287 ----
  		}
  	    }
  	}
! 	if (!inbrace)
! 	    fstr = s;
      }
      if (errflag)
  	return NULL;
***************
*** 1370,1381 ****
  
  	if (!aval[0] && !plan9) {
  	    if (aptr > (char *) getdata(n) &&
! 		aptr[-1] == Dnull && *s == Dnull)
! 		*--aptr = '\0', s++;
! 	    y = (char *)ncalloc((aptr - ostr) + strlen(s) + 1);
  	    strcpy(y, ostr);
  	    *str = y + (aptr - ostr);
! 	    strcpy(*str, s);
  	    setdata(n, y);
  	    return n;
  	}
--- 1375,1386 ----
  
  	if (!aval[0] && !plan9) {
  	    if (aptr > (char *) getdata(n) &&
! 		aptr[-1] == Dnull && *fstr == Dnull)
! 		*--aptr = '\0', fstr++;
! 	    y = (char *)ncalloc((aptr - ostr) + strlen(fstr) + 1);
  	    strcpy(y, ostr);
  	    *str = y + (aptr - ostr);
! 	    strcpy(*str, fstr);
  	    setdata(n, y);
  	    return n;
  	}
***************
*** 1395,1402 ****
  	    LinkList tl = newlinklist();
  	    LinkNode tn;
  
! 	    *--s = Marker;
! 	    addlinknode(tl, s);
  	    if (!eval && !stringsubst(tl, firstnode(tl), ssub))
  		return NULL;
  	    *str = aptr;
--- 1400,1407 ----
  	    LinkList tl = newlinklist();
  	    LinkNode tn;
  
! 	    *--fstr = Marker;
! 	    addlinknode(tl, fstr);
  	    if (!eval && !stringsubst(tl, firstnode(tl), ssub))
  		return NULL;
  	    *str = aptr;
***************
*** 1474,1480 ****
  	    if (eval && parsestr(x))
  		return NULL;
  	    xlen = strlen(x);
! 	    *str = strcatsub(&y, aptr, aptr, x, xlen, s, globsubst);
  	    if (qt && !*y && isarr != 2)
  		y = dupstring(nulstring);
  	    insertlinknode(l, n, (void *) y), incnode(n);
--- 1479,1485 ----
  	    if (eval && parsestr(x))
  		return NULL;
  	    xlen = strlen(x);
! 	    *str = strcatsub(&y, aptr, aptr, x, xlen, fstr, globsubst);
  	    if (qt && !*y && isarr != 2)
  		y = dupstring(nulstring);
  	    insertlinknode(l, n, (void *) y), incnode(n);
***************
*** 1493,1499 ****
  	if (eval && parsestr(x))
  	    return NULL;
  	xlen = strlen(x);
! 	*str = strcatsub(&y, ostr, aptr, x, xlen, s, globsubst);
  	if (qt && !*y && isarr != 2)
  	    y = dupstring(nulstring);
  	setdata(n, (void *) y);
--- 1498,1504 ----
  	if (eval && parsestr(x))
  	    return NULL;
  	xlen = strlen(x);
! 	*str = strcatsub(&y, ostr, aptr, x, xlen, fstr, globsubst);
  	if (qt && !*y && isarr != 2)
  	    y = dupstring(nulstring);
  	setdata(n, (void *) y);

-- 
Peter Stephenson <pws@xxxxxx>       Tel: +39 50 844536
WWW:  http://www.ifh.de/~pws/
Gruppo Teorico, Dipartimento di Fisica
Piazza Torricelli 2, 56100 Pisa, Italy



Messages sorted by: Reverse Date, Date, Thread, Author