fixed bug in realloc: copy the min size of the new and old block.
[unix-history] / usr / src / bin / csh / lex.c
index ab9f46e..dcafbe0 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)lex.c      5.21 (Berkeley) %G%";
+static char sccsid[] = "@(#)lex.c      5.26 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -35,19 +35,19 @@ static Char *word __P((void));
 static int      getC1 __P((int));
 static void     getdol __P((void));
 static void     getexcl __P((int));
 static int      getC1 __P((int));
 static void     getdol __P((void));
 static void     getexcl __P((int));
-static struct Hist 
+static struct Hist
                *findev __P((Char *, bool));
 static void     setexclp __P((Char *));
 static int      bgetc __P((void));
 static void     bfree __P((void));
                *findev __P((Char *, bool));
 static void     setexclp __P((Char *));
 static int      bgetc __P((void));
 static void     bfree __P((void));
-static struct wordent 
+static struct wordent
                *gethent __P((int));
 static int      matchs __P((Char *, Char *));
 static int      getsel __P((int *, int *, int));
                *gethent __P((int));
 static int      matchs __P((Char *, Char *));
 static int      getsel __P((int *, int *, int));
-static struct wordent 
+static struct wordent
                *getsub __P((struct wordent *));
                *getsub __P((struct wordent *));
-static Char    *subword __P((Char *, int, bool *));
-static struct wordent 
+static Char    *subword __P((Char *, int, bool *));
+static struct wordent
                *dosub __P((int, struct wordent *, bool));
 
 /*
                *dosub __P((int, struct wordent *, bool));
 
 /*
@@ -80,7 +80,7 @@ static struct wordent *exclnxt = NULL;
 static int exclc = 0;
 
 /* "Globp" for alias resubstitution */
 static int exclc = 0;
 
 /* "Globp" for alias resubstitution */
-static Char *alvecp = NULL;
+Char *alvecp = NULL;
 int aret = F_SEEK;
 
 /*
 int aret = F_SEEK;
 
 /*
@@ -159,7 +159,7 @@ prlex(fp, sp0)
     register struct wordent *sp = sp0->next;
 
     for (;;) {
     register struct wordent *sp = sp0->next;
 
     for (;;) {
-       (void) fprintf(fp, "%s", short2str(sp->word));
+       (void) fprintf(fp, "%s", vis_str(sp->word));
        sp = sp->next;
        if (sp == sp0)
            break;
        sp = sp->next;
        if (sp == sp0)
            break;
@@ -218,7 +218,8 @@ word()
     wp = wbuf;
     i = BUFSIZ - 4;
 loop:
     wp = wbuf;
     i = BUFSIZ - 4;
 loop:
-    while ((c = getC(DOALL)) == ' ' || c == '\t');
+    while ((c = getC(DOALL)) == ' ' || c == '\t')
+       continue;
     if (cmap(c, _META | _ESC))
        switch (c) {
        case '&':
     if (cmap(c, _META | _ESC))
        switch (c) {
        case '&':
@@ -409,6 +410,7 @@ getdol()
 
     case '<':
     case '$':
 
     case '<':
     case '$':
+    case '!':
        if (special)
            seterror(ERR_SPDOLLT);
        *np = 0;
        if (special)
            seterror(ERR_SPDOLLT);
        *np = 0;
@@ -521,15 +523,49 @@ getdol()
         * -strike
         */
 
         * -strike
         */
 
-       int     gmodflag = 0;
+       int     gmodflag = 0, amodflag = 0;
 
        do {
            *np++ = c, c = getC(DOEXCL);
 
        do {
            *np++ = c, c = getC(DOEXCL);
-           if (c == 'g')
-               gmodflag++, *np++ = c, c = getC(DOEXCL);
+           if (c == 'g' || c == 'a') {
+               if (c == 'g')
+                   gmodflag++;
+               else
+                   amodflag++;
+               *np++ = c; c = getC(DOEXCL);
+           }
+           if ((c == 'g' && !gmodflag) || (c == 'a' && !amodflag)) {
+               if (c == 'g')
+                   gmodflag++;
+               else
+                   amodflag++;
+               *np++ = c; c = getC(DOEXCL);
+           }
            *np++ = c;
            *np++ = c;
-           if (!any("htrqxe", c)) {
-               if (gmodflag && c == '\n')
+           /* scan s// [eichin:19910926.0512EST] */
+           if (c == 's') {
+               int delimcnt = 2;
+               int delim = getC(0);
+               *np++ = delim;
+               
+               if (!delim || letter(delim)
+                   || Isdigit(delim) || any(" \t\n", delim)) {
+                   seterror(ERR_BADSUBST);
+                   break;
+               }       
+               while ((c = getC(0)) != (-1)) {
+                   *np++ = c;
+                   if(c == delim) delimcnt--;
+                   if(!delimcnt) break;
+               }
+               if(delimcnt) {
+                   seterror(ERR_BADSUBST);
+                   break;
+               }
+               c = 's';
+           }
+           if (!any("htrqxes", c)) {
+               if ((amodflag || gmodflag) && c == '\n')
                    stderror(ERR_VARSYN);       /* strike */
                seterror(ERR_VARMOD, c);
                *np = 0;
                    stderror(ERR_VARSYN);       /* strike */
                seterror(ERR_VARMOD, c);
                *np = 0;
@@ -667,14 +703,21 @@ getsub(en)
     int     delim;
     register int c;
     int     sc;
     int     delim;
     register int c;
     int     sc;
-    bool global = 0;
+    bool global;
     Char    orhsb[sizeof(rhsb) / sizeof(Char)];
 
     do {
        exclnxt = 0;
     Char    orhsb[sizeof(rhsb) / sizeof(Char)];
 
     do {
        exclnxt = 0;
+       global = 0;
        sc = c = getC(0);
        sc = c = getC(0);
-       if (c == 'g')
-           global++, sc = c = getC(0);
+       if (c == 'g' || c == 'a') {
+           global |= (c == 'g') ? 1 : 2;
+           sc = c = getC(0);
+       }
+       if (((c =='g') && !(global & 1)) || ((c == 'a') && !(global & 2))) {
+           global |= (c == 'g') ? 1 : 2;
+           sc = c = getC(0);
+       }
 
        switch (c) {
        case 'p':
 
        switch (c) {
        case 'p':
@@ -683,7 +726,7 @@ getsub(en)
 
        case 'x':
        case 'q':
 
        case 'x':
        case 'q':
-           global++;
+           global |= 1;
 
            /* fall into ... */
 
 
            /* fall into ... */
 
@@ -755,7 +798,7 @@ getsub(en)
                    break;
 #ifdef notdef
                if (c == '~') {
                    break;
 #ifdef notdef
                if (c == '~') {
-                   if (&cp[Strlen(orhsb)] > &rhsb[sizeof(rhsb) / 
+                   if (&cp[Strlen(orhsb)] > &rhsb[sizeof(rhsb) /
                                                   sizeof(Char) - 2])
                        goto toorhs;
                    (void) Strcpy(cp, orhsb);
                                                   sizeof(Char) - 2])
                        goto toorhs;
                    (void) Strcpy(cp, orhsb);
@@ -799,24 +842,46 @@ dosub(sc, en, global)
     bool global;
 {
     struct wordent lexi;
     bool global;
 {
     struct wordent lexi;
-    bool    didsub = 0;
+    bool    didsub = 0, didone = 0;
     struct wordent *hp = &lexi;
     register struct wordent *wdp;
     register int i = exclc;
 
     wdp = hp;
     while (--i >= 0) {
     struct wordent *hp = &lexi;
     register struct wordent *wdp;
     register int i = exclc;
 
     wdp = hp;
     while (--i >= 0) {
-       register struct wordent *new;
+       register struct wordent *new = 
+               (struct wordent *) xcalloc(1, sizeof *wdp);
 
 
-       new = (struct wordent *) xcalloc(1, sizeof *wdp);
        new->word = 0;
        new->prev = wdp;
        new->next = hp;
        wdp->next = new;
        wdp = new;
        en = en->next;
        new->word = 0;
        new->prev = wdp;
        new->next = hp;
        wdp->next = new;
        wdp = new;
        en = en->next;
-       wdp->word = (en->word && (global ||didsub == 0)) ?
-           subword(en->word, sc, &didsub) : Strsave(en->word);
+       if (en->word) {
+           Char *tword, *otword;
+
+           if ((global & 1) || didsub == 0) {
+               tword = subword(en->word, sc, &didone);
+               if (didone)
+                   didsub = 1;
+               if (global & 2) {
+                   while (didone && tword != STRNULL) {
+                       otword = tword;
+                       tword = subword(otword, sc, &didone);
+                       if (Strcmp(tword, otword) == 0) {
+                           xfree((ptr_t) otword);
+                           break;
+                       }
+                       else
+                           xfree((ptr_t) otword);
+                   }
+               }
+           }
+           else
+               tword = Strsave(en->word);
+           wdp->word = tword;
+       }
     }
     if (didsub == 0)
        seterror(ERR_MODFAIL);
     }
     if (didsub == 0)
        seterror(ERR_MODFAIL);
@@ -834,6 +899,7 @@ subword(cp, type, adid)
     register Char *wp, *mp, *np;
     register int i;
 
     register Char *wp, *mp, *np;
     register int i;
 
+    *adid = 0;
     switch (type) {
 
     case 'r':
     switch (type) {
 
     case 'r':
@@ -940,6 +1006,8 @@ domod(cp, type)
                return (xp);
            }
        return (Strsave(type == 'e' ? STRNULL : cp));
                return (xp);
            }
        return (Strsave(type == 'e' ? STRNULL : cp));
+    default:
+       break;
     }
     return (0);
 }
     }
     return (0);
 }
@@ -1091,7 +1159,7 @@ gethent(sc)
            }
            np = lhsb;
            event = 0;
            }
            np = lhsb;
            event = 0;
-           while (!cmap(c, _META | _Q | _Q1) && !any("{}:", c)) {
+           while (!cmap(c, _ESC | _META | _Q | _Q1) && !any("${}:", c)) {
                if (event != -1 && Isdigit(c))
                    event = event * 10 + c - '0';
                else
                if (event != -1 && Isdigit(c))
                    event = event * 10 + c - '0';
                else
@@ -1153,7 +1221,7 @@ gethent(sc)
            return (&hp->Hlex);
        }
     np = putn(event);
            return (&hp->Hlex);
        }
     np = putn(event);
-    seterror(ERR_NOEVENT, short2str(np));
+    seterror(ERR_NOEVENT, vis_str(np));
     return (0);
 }
 
     return (0);
 }
 
@@ -1204,7 +1272,7 @@ findev(cp, anyarg)
            argno++;
        } while (lp->word[0] != '\n');
     }
            argno++;
        } while (lp->word[0] != '\n');
     }
-    seterror(ERR_NOEVENT, short2str(cp));
+    seterror(ERR_NOEVENT, vis_str(cp));
     return (0);
 }
 
     return (0);
 }
 
@@ -1241,7 +1309,7 @@ top:
     aret = F_SEEK;
     if (alvecp) {
        aret = A_SEEK;
     aret = F_SEEK;
     if (alvecp) {
        aret = A_SEEK;
-       if (c = *alvecp++) 
+       if (c = *alvecp++)
            return (c);
        if (alvec && *alvec) {
                alvecp = *alvec++;
            return (c);
        if (alvec && *alvec) {
                alvecp = *alvec++;
@@ -1316,7 +1384,7 @@ reread:
                    tpgrp != ctpgrp) {
                    (void) tcsetpgrp(FSHTTY, tpgrp);
                    (void) killpg((pid_t) ctpgrp, SIGHUP);
                    tpgrp != ctpgrp) {
                    (void) tcsetpgrp(FSHTTY, tpgrp);
                    (void) killpg((pid_t) ctpgrp, SIGHUP);
-                   (void) fprintf(csherr, "Reset tty pgrp from %d to %d\n", 
+                   (void) fprintf(csherr, "Reset tty pgrp from %d to %d\n",
                                   ctpgrp, tpgrp);
                    goto reread;
                }
                                   ctpgrp, tpgrp);
                    goto reread;
                }
@@ -1483,7 +1551,7 @@ bseek(l)
        alvec = l->a_seek;
        alvecp = (Char *) l->f_seek;
        return;
        alvec = l->a_seek;
        alvecp = (Char *) l->f_seek;
        return;
-    case F_SEEK:       
+    case F_SEEK:
        fseekp = l->f_seek;
        return;
     default:
        fseekp = l->f_seek;
        return;
     default: