From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13868 invoked from network); 19 Mar 1998 10:12:33 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 19 Mar 1998 10:12:33 -0000 Received: (from list@localhost) by math.gatech.edu (8.8.5/8.8.5) id EAA19167; Thu, 19 Mar 1998 04:55:15 -0500 (EST) Resent-Date: Thu, 19 Mar 1998 04:55:15 -0500 (EST) Message-Id: <199803190954.KAA24667@hydra.ifh.de> To: zsh-workers@math.gatech.edu (Zsh hackers list) Subject: PATCH: parameter substitution close brace tidy up Date: Thu, 19 Mar 1998 10:54:25 +0100 From: Peter Stephenson Resent-Message-ID: <"IKE6T2.0.Qh4.2kE4r"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/3806 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu (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 Tel: +39 50 844536 WWW: http://www.ifh.de/~pws/ Gruppo Teorico, Dipartimento di Fisica Piazza Torricelli 2, 56100 Pisa, Italy