# 2.11BSD#431 - /usr/src/bin/csh/sh.lex.c

##### Functions

    addla             X
    bfree             X
    bgetc             X
    bseek             X
    btell             X
    btoeof            X
    copylex           X
    domod             X
    dosub             X
    findev            X
    freelex           X
    getC1             X
    getdol            X
    getexcl           X
    gethent           X
    getsel            X
    getsub            X
    lex               X
    matchs            X
    noev              X
    prlex             X
    readc             X
    setexclp          X
    settell           X
    subword           X
    unreadc           X
    word              X

##### Variables

    alvecp            X
    exclc             X
    exclnxt           X
    exclp             X
    getCtmp           X
    hadhist           X
    lhsb              X
    peekc             X
    peekd             X
    peekread          X
    quesarg           X
    rhsb              X
    slhs              X

##### Macros

    getC              X
    ungetC            X
    ungetD            X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley Software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char *sccsid = "@(#)sh.lex.c	5.4 (Berkeley) 3/29/86";
       9: #endif
      10:
      11: #include "sh.h"
      12: #include <sgtty.h>
      13:
      14: /*
      15:  * C shell
      16:  */
      17:
      18: /*
      19:  * These lexical routines read input and form lists of words.
      20:  * There is some involved processing here, because of the complications
      21:  * of input buffering, and especially because of history substitution.
      22:  */
      23:
      24: char    *word();
      25:
      26: /*
      27:  * Peekc is a peek characer for getC, peekread for readc.
      28:  * There is a subtlety here in many places... history routines
      29:  * will read ahead and then insert stuff into the input stream.
      30:  * If they push back a character then they must push it behind
      31:  * the text substituted by the history substitution.  On the other
      32:  * hand in several places we need 2 peek characters.  To make this
      33:  * all work, the history routines read with getC, and make use both
      34:  * of ungetC and unreadc.  The key observation is that the state
      35:  * of getC at the call of a history reference is such that calls
      36:  * to getC from the history routines will always yield calls of
      37:  * readc, unless this peeking is involved.  That is to say that during
      38:  * getexcl the variables lap, exclp, and exclnxt are all zero.
      39:  *
      40:  * Getdol invokes history substitution, hence the extra peek, peekd,
      41:  * which it can ungetD to be before history substitutions.
      42:  */
      43: char    peekc, peekd;
      44: char    peekread;
      45:
      46: char    *exclp;         /* (Tail of) current word from ! subst */
      47: struct  wordent *exclnxt;   /* The rest of the ! subst words */
      48: int exclc;          /* Count of remainig words in ! subst */
      49: char    *alvecp;        /* "Globp" for alias resubstitution */
      50:
      51: /*
      52:  * Lex returns to its caller not only a wordlist (as a "var" parameter)
      53:  * but also whether a history substitution occurred.  This is used in
      54:  * the main (process) routine to determine whether to echo, and also
      55:  * when called by the alias routine to determine whether to keep the
      56:  * argument list.
      57:  */
      58: bool    hadhist;
      59:
      60: char getCtmp;
      61: #define getC(f)     ((getCtmp = peekc) ? (peekc = 0, getCtmp) : getC1(f))
      62: #define ungetC(c)   peekc = c
      63: #define ungetD(c)   peekd = c
      64:
      65: lex(hp)
      66:     register struct wordent *hp;
      67: {
      68:     register struct wordent *wdp;
      69:     int c;
      70:
      71:     lineloc = btell();
      72:     hp->next = hp->prev = hp;
      73:     hp->word = "";
      74:     alvecp = 0, hadhist = 0;
      75:     do
      76:         c = readc(0);
      77:     while (c == ' ' || c == '\t');
      78:     if (c == HISTSUB && intty)
      79:         /* ^lef^rit	from tty is short !:s^lef^rit */
      80:         getexcl(c);
      81:     else
      82:         unreadc(c);
      83:     wdp = hp;
      84:     /*
      85: 	 * The following loop is written so that the links needed
      86: 	 * by freelex will be ready and rarin to go even if it is
      87: 	 * interrupted.
      88: 	 */
      89:     do {
      90:         register struct wordent *new = (struct wordent *) xalloc(sizeof *wdp);
      91:
      92:         new->word = 0;
      93:         new->prev = wdp;
      94:         new->next = hp;
      95:         wdp->next = new;
      96:         wdp = new;
      97:         wdp->word = word();
      98:     } while (wdp->word[0] != '\n');
      99:     hp->prev = wdp;
     100:     return (hadhist);
     101: }
     102:
     103: prlex(sp0)
     104:     struct wordent *sp0;
     105: {
     106:     register struct wordent *sp = sp0->next;
     107:
     108:     for (;;) {
     109:         printf("%s", sp->word);
     110:         sp = sp->next;
     111:         if (sp == sp0)
     112:             break;
     113:         if (sp->word[0] != '\n')
     114:             putchar(' ');
     115:     }
     116: }
     117:
     118: copylex(hp, fp)
     119:     register struct wordent *hp;
     120:     register struct wordent *fp;
     121: {
     122:     register struct wordent *wdp;
     123:
     124:     wdp = hp;
     125:     fp = fp->next;
     126:     do {
     127:         register struct wordent *new = (struct wordent *) xalloc(sizeof *wdp);
     128:
     129:         new->prev = wdp;
     130:         new->next = hp;
     131:         wdp->next = new;
     132:         wdp = new;
     133:         wdp->word = savestr(fp->word);
     134:         fp = fp->next;
     135:     } while (wdp->word[0] != '\n');
     136:     hp->prev = wdp;
     137: }
     138:
     139: freelex(vp)
     140:     register struct wordent *vp;
     141: {
     142:     register struct wordent *fp;
     143:
     144:     while (vp->next != vp) {
     145:         fp = vp->next;
     146:         vp->next = fp->next;
     147:         XFREE(fp->word)
     148:         XFREE((char *)fp)
     149:     }
     150:     vp->prev = vp;
     151: }
     152:
     153: char *
     154: word()
     155: {
     156:     register char c, c1;
     157:     register char *wp;
     158:     char wbuf[BUFSIZ];
     159:     register bool dolflg;
     160:     register int i;
     161:
     162:     wp = wbuf;
     163:     i = BUFSIZ - 4;
     164: loop:
     165:     while ((c = getC(DOALL)) == ' ' || c == '\t')
     166:         ;
     167:     if (cmap(c, _META|_ESC))
     168:         switch (c) {
     169:         case '&':
     170:         case '|':
     171:         case '<':
     172:         case '>':
     173:             *wp++ = c;
     174:             c1 = getC(DOALL);
     175:             if (c1 == c)
     176:                 *wp++ = c1;
     177:             else
     178:                 ungetC(c1);
     179:             goto ret;
     180:
     181:         case '#':
     182:             if (intty)
     183:                 break;
     184:             c = 0;
     185:             do {
     186:                 c1 = c;
     187:                 c = getC(0);
     188:             } while (c != '\n');
     189:             if (c1 == '\\')
     190:                 goto loop;
     191:             /* fall into ... */
     192:
     193:         case ';':
     194:         case '(':
     195:         case ')':
     196:         case '\n':
     197:             *wp++ = c;
     198:             goto ret;
     199:
     200:         case '\\':
     201:             c = getC(0);
     202:             if (c == '\n') {
     203:                 if (onelflg == 1)
     204:                     onelflg = 2;
     205:                 goto loop;
     206:             }
     207:             if (c != HIST)
     208:                 *wp++ = '\\', --i;
     209:             c |= QUOTE;
     210:         }
     211:     c1 = 0;
     212:     dolflg = DOALL;
     213:     for (;;) {
     214:         if (c1) {
     215:             if (c == c1) {
     216:                 c1 = 0;
     217:                 dolflg = DOALL;
     218:             } else if (c == '\\') {
     219:                 c = getC(0);
     220:                 if (c == HIST)
     221:                     c |= QUOTE;
     222:                 else {
     223:                     if (c == '\n')
     224:                         /*
     225: 						if (c1 == '`')
     226: 							c = ' ';
     227: 						else
     228: 						*/
     229:                             c |= QUOTE;
     230:                     ungetC(c);
     231:                     c = '\\';
     232:                 }
     233:             } else if (c == '\n') {
     234:                 seterrc("Unmatched ", c1);
     235:                 ungetC(c);
     236:                 break;
     237:             }
     238:         } else if (cmap(c, _META|_Q|_Q1|_ESC)) {
     239:             if (c == '\\') {
     240:                 c = getC(0);
     241:                 if (c == '\n') {
     242:                     if (onelflg == 1)
     243:                         onelflg = 2;
     244:                     break;
     245:                 }
     246:                 if (c != HIST)
     247:                     *wp++ = '\\', --i;
     248:                 c |= QUOTE;
     249:             } else if (cmap(c, _Q|_Q1)) {       /* '"` */
     250:                 c1 = c;
     251:                 dolflg = c == '"' ? DOALL : DOEXCL;
     252:             } else if (c != '#' || !intty) {
     253:                 ungetC(c);
     254:                 break;
     255:             }
     256:         }
     257:         if (--i > 0) {
     258:             *wp++ = c;
     259:             c = getC(dolflg);
     260:         } else {
     261:             seterr("Word too long");
     262:             wp = &wbuf[1];
     263:             break;
     264:         }
     265:     }
     266: ret:
     267:     *wp = 0;
     268:     return (savestr(wbuf));
     269: }
     270:
     271: getC1(flag)
     272:     register int flag;
     273: {
     274:     register char c;
     275:
     276: top:
     277:     if (c = peekc) {
     278:         peekc = 0;
     279:         return (c);
     280:     }
     281:     if (lap) {
     282:         if ((c = *lap++) == 0)
     283:             lap = 0;
     284:         else {
     285:             if (cmap(c, _META|_Q|_Q1))
     286:                 c |= QUOTE;
     287:             return (c);
     288:         }
     289:     }
     290:     if (c = peekd) {
     291:         peekd = 0;
     292:         return (c);
     293:     }
     294:     if (exclp) {
     295:         if (c = *exclp++)
     296:             return (c);
     297:         if (exclnxt && --exclc >= 0) {
     298:             exclnxt = exclnxt->next;
     299:             setexclp(exclnxt->word);
     300:             return (' ');
     301:         }
     302:         exclp = 0;
     303:         exclnxt = 0;
     304:     }
     305:     if (exclnxt) {
     306:         exclnxt = exclnxt->next;
     307:         if (--exclc < 0)
     308:             exclnxt = 0;
     309:         else
     310:             setexclp(exclnxt->word);
     311:         goto top;
     312:     }
     313:     c = readc(0);
     314:     if (c == '$' && (flag & DODOL)) {
     315:         getdol();
     316:         goto top;
     317:     }
     318:     if (c == HIST && (flag & DOEXCL)) {
     319:         getexcl(0);
     320:         goto top;
     321:     }
     322:     return (c);
     323: }
     324:
     325: getdol()
     326: {
     327:     register char *np;
     328:     char name[40];
     329:     register int c;
     330:     int sc;
     331:     bool special = 0;
     332:
     333:     np = name, *np++ = '$';
     334:     c = sc = getC(DOEXCL);
     335:     if (any(c, "\t \n")) {
     336:         ungetD(c);
     337:         ungetC('$' | QUOTE);
     338:         return;
     339:     }
     340:     if (c == '{')
     341:         *np++ = c, c = getC(DOEXCL);
     342:     if (c == '#' || c == '?')
     343:         special++, *np++ = c, c = getC(DOEXCL);
     344:     *np++ = c;
     345:     switch (c) {
     346:
     347:     case '<':
     348:     case '$':
     349:         if (special)
     350:             goto vsyn;
     351:         goto ret;
     352:
     353:     case '\n':
     354:         ungetD(c);
     355:         np--;
     356:         goto vsyn;
     357:
     358:     case '*':
     359:         if (special)
     360:             goto vsyn;
     361:         goto ret;
     362:
     363:     default:
     364:         if (digit(c)) {
     365: /*
     366:  * let $?0 pass for now
     367: 			if (special)
     368: 				goto vsyn;
     369: */
     370:             while (digit(c = getC(DOEXCL))) {
     371:                 if (np < &name[sizeof name / 2])
     372:                     *np++ = c;
     373:             }
     374:         } else if (letter(c))
     375:             while (letter(c = getC(DOEXCL))) {
     376:                 if (np < &name[sizeof name / 2])
     377:                     *np++ = c;
     378:             }
     379:         else
     380:             goto vsyn;
     381:     }
     382:     if (c == '[') {
     383:         *np++ = c;
     384:         do {
     385:             c = getC(DOEXCL);
     386:             if (c == '\n') {
     387:                 ungetD(c);
     388:                 np--;
     389:                 goto vsyn;
     390:             }
     391:             if (np >= &name[sizeof name - 8])
     392:                 goto vsyn;
     393:             *np++ = c;
     394:         } while (c != ']');
     395:         c = getC(DOEXCL);
     396:     }
     397:     if (c == ':') {
     398:         *np++ = c, c = getC(DOEXCL);
     399:         if (c == 'g')
     400:             *np++ = c, c = getC(DOEXCL);
     401:         *np++ = c;
     402:         if (!any(c, "htrqxe"))
     403:             goto vsyn;
     404:     } else
     405:         ungetD(c);
     406:     if (sc == '{') {
     407:         c = getC(DOEXCL);
     408:         if (c != '}') {
     409:             ungetC(c);
     410:             goto vsyn;
     411:         }
     412:         *np++ = c;
     413:     }
     414: ret:
     415:     *np = 0;
     416:     addla(name);
     417:     return;
     418:
     419: vsyn:
     420:     seterr("Variable syntax");
     421:     goto ret;
     422: }
     423:
     424: addla(cp)
     425:     char *cp;
     426: {
     427:     char buf[BUFSIZ];
     428:
     429:     if (lap != 0 && strlen(cp) + strlen(lap) >= sizeof (labuf) - 4) {
     430:         seterr("Expansion buf ovflo");
     431:         return;
     432:     }
     433:     if (lap)
     434:         (void) strcpy(buf, lap);
     435:     (void) strcpy(labuf, cp);
     436:     if (lap)
     437:         (void) strcat(labuf, buf);
     438:     lap = labuf;
     439: }
     440:
     441: char    lhsb[32];
     442: char    slhs[32];
     443: char    rhsb[64];
     444: int quesarg;
     445:
     446: getexcl(sc)
     447:     char sc;
     448: {
     449:     register struct wordent *hp, *ip;
     450:     int left, right, dol;
     451:     register int c;
     452:
     453:     if (sc == 0) {
     454:         sc = getC(0);
     455:         if (sc != '{') {
     456:             ungetC(sc);
     457:             sc = 0;
     458:         }
     459:     }
     460:     quesarg = -1;
     461:     lastev = eventno;
     462:     hp = gethent(sc);
     463:     if (hp == 0)
     464:         return;
     465:     hadhist = 1;
     466:     dol = 0;
     467:     if (hp == alhistp)
     468:         for (ip = hp->next->next; ip != alhistt; ip = ip->next)
     469:             dol++;
     470:     else
     471:         for (ip = hp->next->next; ip != hp->prev; ip = ip->next)
     472:             dol++;
     473:     left = 0, right = dol;
     474:     if (sc == HISTSUB) {
     475:         ungetC('s'), unreadc(HISTSUB), c = ':';
     476:         goto subst;
     477:     }
     478:     c = getC(0);
     479:     if (!any(c, ":^$*-%"))
     480:         goto subst;
     481:     left = right = -1;
     482:     if (c == ':') {
     483:         c = getC(0);
     484:         unreadc(c);
     485:         if (letter(c) || c == '&') {
     486:             c = ':';
     487:             left = 0, right = dol;
     488:             goto subst;
     489:         }
     490:     } else
     491:         ungetC(c);
     492:     if (!getsel(&left, &right, dol))
     493:         return;
     494:     c = getC(0);
     495:     if (c == '*')
     496:         ungetC(c), c = '-';
     497:     if (c == '-') {
     498:         if (!getsel(&left, &right, dol))
     499:             return;
     500:         c = getC(0);
     501:     }
     502: subst:
     503:     exclc = right - left + 1;
     504:     while (--left >= 0)
     505:         hp = hp->next;
     506:     if (sc == HISTSUB || c == ':') {
     507:         do {
     508:             hp = getsub(hp);
     509:             c = getC(0);
     510:         } while (c == ':');
     511:     }
     512:     unreadc(c);
     513:     if (sc == '{') {
     514:         c = getC(0);
     515:         if (c != '}')
     516:             seterr("Bad ! form");
     517:     }
     518:     exclnxt = hp;
     519: }
     520:
     521: struct wordent *
     522: getsub(en)
     523:     struct wordent *en;
     524: {
     525:     register char *cp;
     526:     int delim;
     527:     register int c;
     528:     int sc;
     529:     bool global = 0;
     530:     char orhsb[sizeof rhsb];
     531:
     532:     exclnxt = 0;
     533:     sc = c = getC(0);
     534:     if (c == 'g')
     535:         global++, c = getC(0);
     536:     switch (c) {
     537:
     538:     case 'p':
     539:         justpr++;
     540:         goto ret;
     541:
     542:     case 'x':
     543:     case 'q':
     544:         global++;
     545:         /* fall into ... */
     546:
     547:     case 'h':
     548:     case 'r':
     549:     case 't':
     550:     case 'e':
     551:         break;
     552:
     553:     case '&':
     554:         if (slhs[0] == 0) {
     555:             seterr("No prev sub");
     556:             goto ret;
     557:         }
     558:         (void) strcpy(lhsb, slhs);
     559:         break;
     560:
     561: /*
     562: 	case '~':
     563: 		if (lhsb[0] == 0)
     564: 			goto badlhs;
     565: 		break;
     566: */
     567:
     568:     case 's':
     569:         delim = getC(0);
     570:         if (letter(delim) || digit(delim) || any(delim, " \t\n")) {
     571:             unreadc(delim);
     572: bads:
     573:             lhsb[0] = 0;
     574:             seterr("Bad substitute");
     575:             goto ret;
     576:         }
     577:         cp = lhsb;
     578:         for (;;) {
     579:             c = getC(0);
     580:             if (c == '\n') {
     581:                 unreadc(c);
     582:                 break;
     583:             }
     584:             if (c == delim)
     585:                 break;
     586:             if (cp > &lhsb[sizeof lhsb - 2])
     587:                 goto bads;
     588:             if (c == '\\') {
     589:                 c = getC(0);
     590:                 if (c != delim && c != '\\')
     591:                     *cp++ = '\\';
     592:             }
     593:             *cp++ = c;
     594:         }
     595:         if (cp != lhsb)
     596:             *cp++ = 0;
     597:         else if (lhsb[0] == 0) {
     598: /*badlhs:*/
     599:             seterr("No prev lhs");
     600:             goto ret;
     601:         }
     602:         cp = rhsb;
     603:         (void) strcpy(orhsb, cp);
     604:         for (;;) {
     605:             c = getC(0);
     606:             if (c == '\n') {
     607:                 unreadc(c);
     608:                 break;
     609:             }
     610:             if (c == delim)
     611:                 break;
     612: /*
     613: 			if (c == '~') {
     614: 				if (&cp[strlen(orhsb)] > &rhsb[sizeof rhsb - 2])
     615: 					goto toorhs;
     616: 				(void) strcpy(cp, orhsb);
     617: 				cp = strend(cp);
     618: 				continue;
     619: 			}
     620: */
     621:             if (cp > &rhsb[sizeof rhsb - 2]) {
     622: /*toorhs:*/
     623:                 seterr("Rhs too long");
     624:                 goto ret;
     625:             }
     626:             if (c == '\\') {
     627:                 c = getC(0);
     628:                 if (c != delim /* && c != '~' */)
     629:                     *cp++ = '\\';
     630:             }
     631:             *cp++ = c;
     632:         }
     633:         *cp++ = 0;
     634:         break;
     635:
     636:     default:
     637:         if (c == '\n')
     638:             unreadc(c);
     639:         seterrc("Bad ! modifier: ", c);
     640:         goto ret;
     641:     }
     642:     (void) strcpy(slhs, lhsb);
     643:     if (exclc)
     644:         en = dosub(sc, en, global);
     645: ret:
     646:     return (en);
     647: }
     648:
     649: struct wordent *
     650: dosub(sc, en, global)
     651:     int sc;
     652:     struct wordent *en;
     653:     bool global;
     654: {
     655:     struct wordent lex;
     656:     bool didsub = 0;
     657:     struct wordent *hp = &lex;
     658:     register struct wordent *wdp;
     659:     register int i = exclc;
     660:
     661:     wdp = hp;
     662:     while (--i >= 0) {
     663:         register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
     664:
     665:         new->prev = wdp;
     666:         new->next = hp;
     667:         wdp->next = new;
     668:         wdp = new;
     669:         en = en->next;
     670:         wdp->word = global || didsub == 0 ?
     671:             subword(en->word, sc, &didsub) : savestr(en->word);
     672:     }
     673:     if (didsub == 0)
     674:         seterr("Modifier failed");
     675:     hp->prev = wdp;
     676:     return (&enthist(-1000, &lex, 0)->Hlex);
     677: }
     678:
     679: char *
     680: subword(cp, type, adid)
     681:     char *cp;
     682:     int type;
     683:     bool *adid;
     684: {
     685:     char wbuf[BUFSIZ];
     686:     register char *wp, *mp, *np;
     687:     register int i;
     688:
     689:     switch (type) {
     690:
     691:     case 'r':
     692:     case 'e':
     693:     case 'h':
     694:     case 't':
     695:     case 'q':
     696:     case 'x':
     697:         wp = domod(cp, type);
     698:         if (wp == 0)
     699:             return (savestr(cp));
     700:         *adid = 1;
     701:         return (wp);
     702:
     703:     default:
     704:         wp = wbuf;
     705:         i = BUFSIZ - 4;
     706:         for (mp = cp; *mp; mp++)
     707:             if (matchs(mp, lhsb)) {
     708:                 for (np = cp; np < mp;)
     709:                     *wp++ = *np++, --i;
     710:                 for (np = rhsb; *np; np++) switch (*np) {
     711:
     712:                 case '\\':
     713:                     if (np[1] == '&')
     714:                         np++;
     715:                     /* fall into ... */
     716:
     717:                 default:
     718:                     if (--i < 0)
     719:                         goto ovflo;
     720:                     *wp++ = *np;
     721:                     continue;
     722:
     723:                 case '&':
     724:                     i -= strlen(lhsb);
     725:                     if (i < 0)
     726:                         goto ovflo;
     727:                     *wp = 0;
     728:                     (void) strcat(wp, lhsb);
     729:                     wp = strend(wp);
     730:                     continue;
     731:                 }
     732:                 mp += strlen(lhsb);
     733:                 i -= strlen(mp);
     734:                 if (i < 0) {
     735: ovflo:
     736:                     seterr("Subst buf ovflo");
     737:                     return ("");
     738:                 }
     739:                 *wp = 0;
     740:                 (void) strcat(wp, mp);
     741:                 *adid = 1;
     742:                 return (savestr(wbuf));
     743:             }
     744:         return (savestr(cp));
     745:     }
     746: }
     747:
     748: char *
     749: domod(cp, type)
     750:     char *cp;
     751:     int type;
     752: {
     753:     register char *wp, *xp;
     754:     register int c;
     755:
     756:     switch (type) {
     757:
     758:     case 'x':
     759:     case 'q':
     760:         wp = savestr(cp);
     761:         for (xp = wp; c = *xp; xp++)
     762:             if ((c != ' ' && c != '\t') || type == 'q')
     763:                 *xp |= QUOTE;
     764:         return (wp);
     765:
     766:     case 'h':
     767:     case 't':
     768:         if (!any('/', cp))
     769:             return (type == 't' ? savestr(cp) : 0);
     770:         wp = strend(cp);
     771:         while (*--wp != '/')
     772:             continue;
     773:         if (type == 'h')
     774:             xp = savestr(cp), xp[wp - cp] = 0;
     775:         else
     776:             xp = savestr(wp + 1);
     777:         return (xp);
     778:
     779:     case 'e':
     780:     case 'r':
     781:         wp = strend(cp);
     782:         for (wp--; wp >= cp && *wp != '/'; wp--)
     783:             if (*wp == '.') {
     784:                 if (type == 'e')
     785:                     xp = savestr(wp + 1);
     786:                 else
     787:                     xp = savestr(cp), xp[wp - cp] = 0;
     788:                 return (xp);
     789:             }
     790:         return (savestr(type == 'e' ? "" : cp));
     791:     }
     792:     return (0);
     793: }
     794:
     795: matchs(str, pat)
     796:     register char *str, *pat;
     797: {
     798:
     799:     while (*str && *pat && *str == *pat)
     800:         str++, pat++;
     801:     return (*pat == 0);
     802: }
     803:
     804: getsel(al, ar, dol)
     805:     register int *al, *ar;
     806:     int dol;
     807: {
     808:     register int c = getC(0);
     809:     register int i;
     810:     bool first = *al < 0;
     811:
     812:     switch (c) {
     813:
     814:     case '%':
     815:         if (quesarg == -1)
     816:             goto bad;
     817:         if (*al < 0)
     818:             *al = quesarg;
     819:         *ar = quesarg;
     820:         break;
     821:
     822:     case '-':
     823:         if (*al < 0) {
     824:             *al = 0;
     825:             *ar = dol - 1;
     826:             unreadc(c);
     827:         }
     828:         return (1);
     829:
     830:     case '^':
     831:         if (*al < 0)
     832:             *al = 1;
     833:         *ar = 1;
     834:         break;
     835:
     836:     case '$':
     837:         if (*al < 0)
     838:             *al = dol;
     839:         *ar = dol;
     840:         break;
     841:
     842:     case '*':
     843:         if (*al < 0)
     844:             *al = 1;
     845:         *ar = dol;
     846:         if (*ar < *al) {
     847:             *ar = 0;
     848:             *al = 1;
     849:             return (1);
     850:         }
     851:         break;
     852:
     853:     default:
     854:         if (digit(c)) {
     855:             i = 0;
     856:             while (digit(c)) {
     857:                 i = i * 10 + c - '0';
     858:                 c = getC(0);
     859:             }
     860:             if (i < 0)
     861:                 i = dol + 1;
     862:             if (*al < 0)
     863:                 *al = i;
     864:             *ar = i;
     865:         } else
     866:             if (*al < 0)
     867:                 *al = 0, *ar = dol;
     868:             else
     869:                 *ar = dol - 1;
     870:         unreadc(c);
     871:         break;
     872:     }
     873:     if (first) {
     874:         c = getC(0);
     875:         unreadc(c);
     876:         if (any(c, "-$*"))
     877:             return (1);
     878:     }
     879:     if (*al > *ar || *ar > dol) {
     880: bad:
     881:         seterr("Bad ! arg selector");
     882:         return (0);
     883:     }
     884:     return (1);
     885:
     886: }
     887:
     888: struct wordent *
     889: gethent(sc)
     890:     int sc;
     891: {
     892:     register struct Hist *hp;
     893:     register char *np;
     894:     register int c;
     895:     int event;
     896:     bool back = 0;
     897:
     898:     c = sc == HISTSUB ? HIST : getC(0);
     899:     if (c == HIST) {
     900:         if (alhistp)
     901:             return (alhistp);
     902:         event = eventno;
     903:         goto skip;
     904:     }
     905:     switch (c) {
     906:
     907:     case ':':
     908:     case '^':
     909:     case '$':
     910:     case '*':
     911:     case '%':
     912:         ungetC(c);
     913:         if (lastev == eventno && alhistp)
     914:             return (alhistp);
     915:         event = lastev;
     916:         break;
     917:
     918:     case '-':
     919:         back = 1;
     920:         c = getC(0);
     921:         goto number;
     922:
     923:     case '#':           /* !# is command being typed in (mrh) */
     924:         return(&paraml);
     925:
     926:     default:
     927:         if (any(c, "(=~")) {
     928:             unreadc(c);
     929:             ungetC(HIST);
     930:             return (0);
     931:         }
     932:         if (digit(c))
     933:             goto number;
     934:         np = lhsb;
     935:         while (!any(c, ": \t\\\n}")) {
     936:             if (np < &lhsb[sizeof lhsb - 2])
     937:                 *np++ = c;
     938:             c = getC(0);
     939:         }
     940:         unreadc(c);
     941:         if (np == lhsb) {
     942:             ungetC(HIST);
     943:             return (0);
     944:         }
     945:         *np++ = 0;
     946:         hp = findev(lhsb, 0);
     947:         if (hp)
     948:             lastev = hp->Hnum;
     949:         return (&hp->Hlex);
     950:
     951:     case '?':
     952:         np = lhsb;
     953:         for (;;) {
     954:             c = getC(0);
     955:             if (c == '\n') {
     956:                 unreadc(c);
     957:                 break;
     958:             }
     959:             if (c == '?')
     960:                 break;
     961:             if (np < &lhsb[sizeof lhsb - 2])
     962:                 *np++ = c;
     963:         }
     964:         if (np == lhsb) {
     965:             if (lhsb[0] == 0) {
     966:                 seterr("No prev search");
     967:                 return (0);
     968:             }
     969:         } else
     970:             *np++ = 0;
     971:         hp = findev(lhsb, 1);
     972:         if (hp)
     973:             lastev = hp->Hnum;
     974:         return (&hp->Hlex);
     975:
     976:     number:
     977:         event = 0;
     978:         while (digit(c)) {
     979:             event = event * 10 + c - '0';
     980:             c = getC(0);
     981:         }
     982:         if (back)
     983:             event = eventno + (alhistp == 0) - (event ? event : 0);
     984:         unreadc(c);
     985:         break;
     986:     }
     987: skip:
     988:     for (hp = Histlist.Hnext; hp; hp = hp->Hnext)
     989:         if (hp->Hnum == event) {
     990:             hp->Href = eventno;
     991:             lastev = hp->Hnum;
     992:             return (&hp->Hlex);
     993:         }
     994:     np = putn(event);
     995:     noev(np);
     996:     return (0);
     997: }
     998:
     999: struct Hist *
    1000: findev(cp, anyarg)
    1001:     char *cp;
    1002:     bool anyarg;
    1003: {
    1004:     register struct Hist *hp;
    1005:
    1006:     for (hp = Histlist.Hnext; hp; hp = hp->Hnext) {
    1007:         char *dp;
    1008:         register char *p, *q;
    1009:         register struct wordent *lp = hp->Hlex.next;
    1010:         int argno = 0;
    1011:
    1012:         if (lp->word[0] == '\n')
    1013:             continue;
    1014:         if (!anyarg) {
    1015:             p = cp;
    1016:             q = lp->word;
    1017:             do
    1018:                 if (!*p)
    1019:                     return (hp);
    1020:             while (*p++ == *q++);
    1021:             continue;
    1022:         }
    1023:         do {
    1024:             for (dp = lp->word; *dp; dp++) {
    1025:                 p = cp;
    1026:                 q = dp;
    1027:                 do
    1028:                     if (!*p) {
    1029:                         quesarg = argno;
    1030:                         return (hp);
    1031:                     }
    1032:                 while (*p++ == *q++);
    1033:             }
    1034:             lp = lp->next;
    1035:             argno++;
    1036:         } while (lp->word[0] != '\n');
    1037:     }
    1038:     noev(cp);
    1039:     return (0);
    1040: }
    1041:
    1042: noev(cp)
    1043:     char *cp;
    1044: {
    1045:
    1046:     seterr2(cp, ": Event not found");
    1047: }
    1048:
    1049: setexclp(cp)
    1050:     register char *cp;
    1051: {
    1052:
    1053:     if (cp && cp[0] == '\n')
    1054:         return;
    1055:     exclp = cp;
    1056: }
    1057:
    1058: unreadc(c)
    1059:     char c;
    1060: {
    1061:
    1062:     peekread = c;
    1063: }
    1064:
    1065: readc(wanteof)
    1066:     bool wanteof;
    1067: {
    1068:     register int c;
    1069:     static sincereal;
    1070:
    1071:     if (c = peekread) {
    1072:         peekread = 0;
    1073:         return (c);
    1074:     }
    1075: top:
    1076:     if (alvecp) {
    1077:         if (c = *alvecp++)
    1078:             return (c);
    1079:         if (*alvec) {
    1080:             alvecp = *alvec++;
    1081:             return (' ');
    1082:         }
    1083:     }
    1084:     if (alvec) {
    1085:         if (alvecp = *alvec) {
    1086:             alvec++;
    1087:             goto top;
    1088:         }
    1089:         /* Infinite source! */
    1090:         return ('\n');
    1091:     }
    1092:     if (evalp) {
    1093:         if (c = *evalp++)
    1094:             return (c);
    1095:         if (*evalvec) {
    1096:             evalp = *evalvec++;
    1097:             return (' ');
    1098:         }
    1099:         evalp = 0;
    1100:     }
    1101:     if (evalvec) {
    1102:         if (evalvec == (char **)1) {
    1103:             doneinp = 1;
    1104:             reset();
    1105:         }
    1106:         if (evalp = *evalvec) {
    1107:             evalvec++;
    1108:             goto top;
    1109:         }
    1110:         evalvec = (char **)1;
    1111:         return ('\n');
    1112:     }
    1113:     do {
    1114:         if (arginp == (char *) 1 || onelflg == 1) {
    1115:             if (wanteof)
    1116:                 return (-1);
    1117:             exitstat();
    1118:         }
    1119:         if (arginp) {
    1120:             if ((c = *arginp++) == 0) {
    1121:                 arginp = (char *) 1;
    1122:                 return ('\n');
    1123:             }
    1124:             return (c);
    1125:         }
    1126: reread:
    1127:         c = bgetc();
    1128:         if (c < 0) {
    1129:             struct sgttyb tty;
    1130:
    1131:             if (wanteof)
    1132:                 return (-1);
    1133:             /* was isatty but raw with ignoreeof yields problems */
    1134:             if (ioctl(SHIN, TIOCGETP, (char *)&tty) == 0 &&
    1135:                 (tty.sg_flags & RAW) == 0) {
    1136:                 /* was 'short' for FILEC */
    1137:                 int ctpgrp;
    1138:
    1139:                 if (++sincereal > 25)
    1140:                     goto oops;
    1141:                 if (tpgrp != -1 &&
    1142:                     ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp) == 0 &&
    1143:                     tpgrp != ctpgrp) {
    1144:                     (void) ioctl(FSHTTY, TIOCSPGRP,
    1145:                         (char *)&tpgrp);
    1146:                     (void) killpg(ctpgrp, SIGHUP);
    1147: printf("Reset tty pgrp from %d to %d\n", ctpgrp, tpgrp);
    1148:                     goto reread;
    1149:                 }
    1150:                 if (adrof("ignoreeof")) {
    1151:                     if (loginsh)
    1152:                         printf("\nUse \"logout\" to logout.\n");
    1153:                     else
    1154:                         printf("\nUse \"exit\" to leave csh.\n");
    1155:                     reset();
    1156:                 }
    1157:                 if (chkstop == 0)
    1158:                     panystop(1);
    1159:             }
    1160: oops:
    1161:             doneinp = 1;
    1162:             reset();
    1163:         }
    1164:         sincereal = 0;
    1165:         if (c == '\n' && onelflg)
    1166:             onelflg--;
    1167:     } while (c == 0);
    1168:     return (c);
    1169: }
    1170:
    1171: bgetc()
    1172: {
    1173:     register int buf, off, c;
    1174: #ifdef FILEC
    1175:     char ttyline[BUFSIZ];
    1176:     register int numleft = 0, roomleft;
    1177: #endif
    1178:
    1179: #ifdef TELL
    1180:     if (cantell) {
    1181:         if (fseekp < fbobp || fseekp > feobp) {
    1182:             fbobp = feobp = fseekp;
    1183:             (void) lseek(SHIN, fseekp, 0);
    1184:         }
    1185:         if (fseekp == feobp) {
    1186:             fbobp = feobp;
    1187:             do
    1188:                 c = read(SHIN, fbuf[0], BUFSIZ);
    1189:             while (c < 0 && errno == EINTR);
    1190:             if (c <= 0)
    1191:                 return (-1);
    1192:             feobp += c;
    1193:         }
    1194:         c = fbuf[0][fseekp - fbobp];
    1195:         fseekp++;
    1196:         return (c & 0377);
    1197:     }
    1198: #endif
    1199: again:
    1200:     buf = (int) fseekp / BUFSIZ;
    1201:     if (buf >= fblocks) {
    1202:         register char **nfbuf =
    1203:             (char **) calloc((unsigned) (fblocks + 2),
    1204:                 sizeof (char **));
    1205:
    1206:         if (fbuf) {
    1207:             (void) blkcpy(nfbuf, fbuf);
    1208:             xfree((char *)fbuf);
    1209:         }
    1210:         fbuf = nfbuf;
    1211:         fbuf[fblocks] = calloc(BUFSIZ, sizeof (char));
    1212:         fblocks++;
    1213:         goto again;
    1214:     }
    1215:     if (fseekp >= feobp) {
    1216:         buf = (int) feobp / BUFSIZ;
    1217:         off = (int) feobp % BUFSIZ;
    1218: #ifndef FILEC
    1219:         for (;;) {
    1220:             c = read(SHIN, fbuf[buf] + off, BUFSIZ - off);
    1221: #else
    1222:         roomleft = BUFSIZ - off;
    1223:         for (;;) {
    1224:             if (filec && intty) {
    1225:                 c = numleft ? numleft : tenex(ttyline, BUFSIZ);
    1226:                 if (c > roomleft) {
    1227:                     /* start with fresh buffer */
    1228:                     feobp = fseekp = fblocks * BUFSIZ;
    1229:                     numleft = c;
    1230:                     goto again;
    1231:                 }
    1232:                 if (c > 0)
    1233:                     copy(fbuf[buf] + off, ttyline, c);
    1234:                 numleft = 0;
    1235:             } else
    1236:                 c = read(SHIN, fbuf[buf] + off, roomleft);
    1237: #endif
    1238:             if (c >= 0)
    1239:                 break;
    1240:             if (errno == EWOULDBLOCK) {
    1241:                 int off = 0;
    1242:
    1243:                 (void) ioctl(SHIN, FIONBIO, (char *)&off);
    1244:             } else if (errno != EINTR)
    1245:                 break;
    1246:         }
    1247:         if (c <= 0)
    1248:             return (-1);
    1249:         feobp += c;
    1250: #ifndef FILEC
    1251:         goto again;
    1252: #else
    1253:         if (filec && !intty)
    1254:             goto again;
    1255: #endif
    1256:     }
    1257:     c = fbuf[buf][(int) fseekp % BUFSIZ];
    1258:     fseekp++;
    1259:     return (c & 0377);
    1260: }
    1261:
    1262: bfree()
    1263: {
    1264:     register int sb, i;
    1265:
    1266: #ifdef TELL
    1267:     if (cantell)
    1268:         return;
    1269: #endif
    1270:     if (whyles)
    1271:         return;
    1272:     sb = (int) (fseekp - 1) / BUFSIZ;
    1273:     if (sb > 0) {
    1274:         for (i = 0; i < sb; i++)
    1275:             xfree(fbuf[i]);
    1276:         (void) blkcpy(fbuf, &fbuf[sb]);
    1277:         fseekp -= BUFSIZ * sb;
    1278:         feobp -= BUFSIZ * sb;
    1279:         fblocks -= sb;
    1280:     }
    1281: }
    1282:
    1283: bseek(l)
    1284:     off_t l;
    1285: {
    1286:     register struct whyle *wp;
    1287:
    1288:     fseekp = l;
    1289: #ifdef TELL
    1290:     if (!cantell) {
    1291: #endif
    1292:         if (!whyles)
    1293:             return;
    1294:         for (wp = whyles; wp->w_next; wp = wp->w_next)
    1295:             continue;
    1296:         if (wp->w_start > l)
    1297:             l = wp->w_start;
    1298: #ifdef TELL
    1299:     }
    1300: #endif
    1301: }
    1302:
    1303: /* any similarity to bell telephone is purely accidental */
    1304: #ifndef btell
    1305: off_t
    1306: btell()
    1307: {
    1308:
    1309:     return (fseekp);
    1310: }
    1311: #endif
    1312:
    1313: btoeof()
    1314: {
    1315:
    1316:     (void) lseek(SHIN, (off_t)0, 2);
    1317:     fseekp = feobp;
    1318:     wfree();
    1319:     bfree();
    1320: }
    1321:
    1322: #ifdef TELL
    1323: settell()
    1324: {
    1325:
    1326:     cantell = 0;
    1327:     if (arginp || onelflg || intty)
    1328:         return;
    1329:     if (lseek(SHIN, (off_t)0, 1) < 0 || errno == ESPIPE)
    1330:         return;
    1331:     fbuf = (char **) calloc(2, sizeof (char **));
    1332:     fblocks = 1;
    1333:     fbuf[0] = calloc(BUFSIZ, sizeof (char));
    1334:     fseekp = fbobp = feobp = lseek(SHIN, (off_t)0, 1);
    1335:     cantell = 1;
    1336: }
    1337: #endif

#### Defined functions

addla defined in line 424; used 5 times

- in line 416
- in /usr/src/bin/csh/sh.dol.c line 403, 480, 519-522(2)

bfree defined in line 1262; used 1 times

- in line 1319

bgetc defined in line 1171; used 1 times

- in line 1127

bseek defined in line 1283; used 5 times

- in /usr/src/bin/csh/sh.func.c line 285, 450, 463, 533, 689

btell defined in line 1305; never used
btoeof defined in line 1313; used 2 times

- in /usr/src/bin/csh/sh.err.c line 78
- in /usr/src/bin/csh/sh.func.c line 336

copylex defined in line 118; used 1 times

- in /usr/src/bin/csh/sh.hist.c line 58

domod defined in line 748; used 3 times

- in line 697
- in /usr/src/bin/csh/sh.dol.c line 516
- in /usr/src/bin/csh/sh.h line 406

dosub defined in line 649; used 2 times

- in line 644
- in /usr/src/bin/csh/sh.h line 407

findev defined in line 999; used 3 times

- in line 946, 971
- in /usr/src/bin/csh/sh.h line 414

freelex defined in line 139; used 5 times

- in /usr/src/bin/csh/sh.c line 701, 801
- in /usr/src/bin/csh/sh.exp.c line 514
- in /usr/src/bin/csh/sh.hist.c line 74
- in /usr/src/bin/csh/sh.parse.c line 122

getC1 defined in line 271; used 1 times

- in line 61

getdol defined in line 325; used 1 times

- in line 315

getexcl defined in line 446; used 2 times

- in line 80, 319

gethent defined in line 888; used 2 times

- in line 462
- in /usr/src/bin/csh/sh.h line 420

getsel defined in line 804; used 2 times

- in line 492, 498

getsub defined in line 521; used 2 times

- in line 508
- in /usr/src/bin/csh/sh.h line 421

lex defined in line 65; used 6 times

- in line 655-657(2), 676
- in /usr/src/bin/csh/sh.c line 748
- in /usr/src/bin/csh/sh.glob.c line 659
- in /usr/src/bin/csh/sh.parse.c line 118

matchs defined in line 795; used 1 times

- in line 707

noev defined in line 1042; used 2 times

- in line 995, 1038

prlex defined in line 103; used 7 times

- in /usr/src/bin/csh/sh.c line 751
- in /usr/src/bin/csh/sh.exec2.c line 201, 226-230(2), 238-243(2)
- in /usr/src/bin/csh/sh.hist.c line 141

readc defined in line 1065; used 8 times

- in line 76, 313
- in /usr/src/bin/csh/sh.dol.c line 595
- in /usr/src/bin/csh/sh.func.c line 621-628(3), 640-641(2)

setexclp defined in line 1049; used 2 times

- in line 299, 310

settell defined in line 1323; used 2 times

- in /usr/src/bin/csh/sh.c line 232, 510

subword defined in line 679; used 2 times

- in line 671
- in /usr/src/bin/csh/sh.h line 442

unreadc defined in line 1058; used 17 times

- in line 82, 475, 484, 512, 571, 581, 607, 638, 826, 870-875(2), 928, 940, 956, 984
- in /usr/src/bin/csh/sh.func.c line 637, 654

word defined in line 153; used 21 times

- in line 24, 73, 92-98(4), 109-113(2), 133-135(3), 147, 299, 310, 670-671(3), 1012-1016(2), 1024, 1036

#### Defined variables

alvecp defined in line 49; used 5 times

- in line 74, 1076-1085(4)

exclc defined in line 48; used 5 times

- in line 297, 307, 503, 643, 659

exclnxt defined in line 47; used 12 times

- in line 297-310(10), 518, 532

exclp defined in line 46; used 4 times

- in line 294-295(2), 302, 1055

getCtmp defined in line 60; used 2 times

- in line 61(2)

hadhist defined in line 58; used 3 times

- in line 74, 100, 465

lhsb defined in line 441; used 23 times

- in line 558, 573-577(2), 586(2), 595-597(2), 642, 707, 724-732(3), 934-946(5), 952, 961-965(4), 971

peekc defined in line 43; used 5 times

- in line 61-62(3), 277-278(2)

peekd defined in line 43; used 3 times

- in line 63, 290-291(2)

peekread defined in line 44; used 3 times

- in line 1062, 1071-1072(2)

quesarg defined in line 444; used 5 times

- in line 460, 815-819(3), 1029

rhsb defined in line 443; used 5 times

- in line 530, 602, 621(2), 710

sccsid defined in line 8; never used
slhs defined in line 442; used 3 times

- in line 554-558(2), 642

#### Defined macros

getC defined in line 61; used 39 times

- in line 165, 174, 187, 201, 219, 240, 259, 334, 341-343(2), 370-375(2), 385, 395-400(3), 407, 454, 478-483(2), 494, 500, 509-514(2), 533-535(2), 569, 579, 589, 605, 627, 808, 858, 874, 898, 920, 938, 954, 980

ungetC defined in line 62; used 13 times

- in line 178, 230-235(2), 253, 337, 409, 456, 475, 491-496(2), 912, 929, 942

ungetD defined in line 63; used 4 times

- in line 336, 354, 387, 405

Last modified: 1991-08-31 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3787 |