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

##### Functions

    alias             X
    asyn0             X
    asyn3             X
    asyntax           X
    freenod           X
    freesyn           X
    syn0              X
    syn1              X
    syn1a             X
    syn1b             X
    syn2              X
    syn3              X
    syntax            X

##### Variables

    RELPAR            X

##### Macros

    PDIAG             X
    PHERE             X
    PIN               X
    POUT              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.parse.c	5.3 (Berkeley) 5/13/86";
       9: #endif
      10:
      11: #include "sh.h"
      12:
      13: /*
      14:  * C shell
      15:  */
      16:
      17: /*
      18:  * Perform aliasing on the word list lex
      19:  * Do a (very rudimentary) parse to separate into commands.
      20:  * If word 0 of a command has an alias, do it.
      21:  * Repeat a maximum of 20 times.
      22:  */
      23: alias(lex)
      24:     register struct wordent *lex;
      25: {
      26:     int aleft = 21;
      27:     jmp_buf osetexit;
      28:
      29:     getexit(osetexit);
      30:     setexit();
      31:     if (haderr) {
      32:         resexit(osetexit);
      33:         reset();
      34:     }
      35:     if (--aleft == 0)
      36:         error("Alias loop");
      37:     asyntax(lex->next, lex);
      38:     resexit(osetexit);
      39: }
      40:
      41: asyntax(p1, p2)
      42:     register struct wordent *p1, *p2;
      43: {
      44:
      45:     while (p1 != p2)
      46:         if (any(p1->word[0], ";&\n"))
      47:             p1 = p1->next;
      48:         else {
      49:             asyn0(p1, p2);
      50:             return;
      51:         }
      52: }
      53:
      54: asyn0(p1, p2)
      55:     struct wordent *p1;
      56:     register struct wordent *p2;
      57: {
      58:     register struct wordent *p;
      59:     register int l = 0;
      60:
      61:     for (p = p1; p != p2; p = p->next)
      62:         switch (p->word[0]) {
      63:
      64:         case '(':
      65:             l++;
      66:             continue;
      67:
      68:         case ')':
      69:             l--;
      70:             if (l < 0)
      71:                 error("Too many )'s");
      72:             continue;
      73:
      74:         case '>':
      75:             if (p->next != p2 && eq(p->next->word, "&"))
      76:                 p = p->next;
      77:             continue;
      78:
      79:         case '&':
      80:         case '|':
      81:         case ';':
      82:         case '\n':
      83:             if (l != 0)
      84:                 continue;
      85:             asyn3(p1, p);
      86:             asyntax(p->next, p2);
      87:             return;
      88:         }
      89:     if (l == 0)
      90:         asyn3(p1, p2);
      91: }
      92:
      93: asyn3(p1, p2)
      94:     struct wordent *p1;
      95:     register struct wordent *p2;
      96: {
      97:     register struct varent *ap;
      98:     struct wordent alout;
      99:     register bool redid;
     100:
     101:     if (p1 == p2)
     102:         return;
     103:     if (p1->word[0] == '(') {
     104:         for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
     105:             if (p2 == p1)
     106:                 return;
     107:         if (p2 == p1->next)
     108:             return;
     109:         asyn0(p1->next, p2);
     110:         return;
     111:     }
     112:     ap = adrof1(p1->word, &aliases);
     113:     if (ap == 0)
     114:         return;
     115:     alhistp = p1->prev;
     116:     alhistt = p2;
     117:     alvec = ap->vec;
     118:     redid = lex(&alout);
     119:     alhistp = alhistt = 0;
     120:     alvec = 0;
     121:     if (err) {
     122:         freelex(&alout);
     123:         error(err);
     124:     }
     125:     if (p1->word[0] && eq(p1->word, alout.next->word)) {
     126:         char *cp = alout.next->word;
     127:
     128:         alout.next->word = strspl("\200", cp);
     129:         XFREE(cp)
     130:     }
     131:     p1 = freenod(p1, redid ? p2 : p1->next);
     132:     if (alout.next != &alout) {
     133:         p1->next->prev = alout.prev->prev;
     134:         alout.prev->prev->next = p1->next;
     135:         alout.next->prev = p1;
     136:         p1->next = alout.next;
     137:         XFREE(alout.prev->word)
     138:         XFREE((char *)alout.prev)
     139:     }
     140:     reset();        /* throw! */
     141: }
     142:
     143: struct wordent *
     144: freenod(p1, p2)
     145:     register struct wordent *p1, *p2;
     146: {
     147:     register struct wordent *retp = p1->prev;
     148:
     149:     while (p1 != p2) {
     150:         XFREE(p1->word)
     151:         p1 = p1->next;
     152:         XFREE((char *)p1->prev)
     153:     }
     154:     retp->next = p2;
     155:     p2->prev = retp;
     156:     return (retp);
     157: }
     158:
     159: #define PHERE   1
     160: #define PIN 2
     161: #define POUT    4
     162: #define PDIAG   8
     163:
     164: /*
     165:  * syntax
     166:  *	empty
     167:  *	syn0
     168:  */
     169: struct command *
     170: syntax(p1, p2, flags)
     171:     register struct wordent *p1, *p2;
     172:     int flags;
     173: {
     174:
     175:     while (p1 != p2)
     176:         if (any(p1->word[0], ";&\n"))
     177:             p1 = p1->next;
     178:         else
     179:             return (syn0(p1, p2, flags));
     180:     return (0);
     181: }
     182:
     183: /*
     184:  * syn0
     185:  *	syn1
     186:  *	syn1 & syntax
     187:  */
     188: struct command *
     189: syn0(p1, p2, flags)
     190:     struct wordent *p1, *p2;
     191:     int flags;
     192: {
     193:     register struct wordent *p;
     194:     register struct command *t, *t1;
     195:     int l;
     196:
     197:     l = 0;
     198:     for (p = p1; p != p2; p = p->next)
     199:         switch (p->word[0]) {
     200:
     201:         case '(':
     202:             l++;
     203:             continue;
     204:
     205:         case ')':
     206:             l--;
     207:             if (l < 0)
     208:                 seterr("Too many )'s");
     209:             continue;
     210:
     211:         case '|':
     212:             if (p->word[1] == '|')
     213:                 continue;
     214:             /* fall into ... */
     215:
     216:         case '>':
     217:             if (p->next != p2 && eq(p->next->word, "&"))
     218:                 p = p->next;
     219:             continue;
     220:
     221:         case '&':
     222:             if (l != 0)
     223:                 break;
     224:             if (p->word[1] == '&')
     225:                 continue;
     226:             t1 = syn1(p1, p, flags);
     227:                 if (t1->t_dtyp == TLST ||
     228:                     t1->t_dtyp == TAND ||
     229:                     t1->t_dtyp == TOR) {
     230:                 t = (struct command *) calloc(1, sizeof (*t));
     231:                 t->t_dtyp = TPAR;
     232:                 t->t_dflg = FAND|FINT;
     233:                 t->t_dspr = t1;
     234:                 t1 = t;
     235:             } else
     236:                 t1->t_dflg |= FAND|FINT;
     237:             t = (struct command *) calloc(1, sizeof (*t));
     238:             t->t_dtyp = TLST;
     239:             t->t_dflg = 0;
     240:             t->t_dcar = t1;
     241:             t->t_dcdr = syntax(p, p2, flags);
     242:             return(t);
     243:         }
     244:     if (l == 0)
     245:         return (syn1(p1, p2, flags));
     246:     seterr("Too many ('s");
     247:     return (0);
     248: }
     249:
     250: /*
     251:  * syn1
     252:  *	syn1a
     253:  *	syn1a ; syntax
     254:  */
     255: struct command *
     256: syn1(p1, p2, flags)
     257:     struct wordent *p1, *p2;
     258:     int flags;
     259: {
     260:     register struct wordent *p;
     261:     register struct command *t;
     262:     int l;
     263:
     264:     l = 0;
     265:     for (p = p1; p != p2; p = p->next)
     266:         switch (p->word[0]) {
     267:
     268:         case '(':
     269:             l++;
     270:             continue;
     271:
     272:         case ')':
     273:             l--;
     274:             continue;
     275:
     276:         case ';':
     277:         case '\n':
     278:             if (l != 0)
     279:                 break;
     280:             t = (struct command *) calloc(1, sizeof (*t));
     281:             t->t_dtyp = TLST;
     282:             t->t_dcar = syn1a(p1, p, flags);
     283:             t->t_dcdr = syntax(p->next, p2, flags);
     284:             if (t->t_dcdr == 0)
     285:                 t->t_dcdr = t->t_dcar, t->t_dcar = 0;
     286:             return (t);
     287:         }
     288:     return (syn1a(p1, p2, flags));
     289: }
     290:
     291: /*
     292:  * syn1a
     293:  *	syn1b
     294:  *	syn1b || syn1a
     295:  */
     296: struct command *
     297: syn1a(p1, p2, flags)
     298:     struct wordent *p1, *p2;
     299:     int flags;
     300: {
     301:     register struct wordent *p;
     302:     register struct command *t;
     303:     register int l = 0;
     304:
     305:     for (p = p1; p != p2; p = p->next)
     306:         switch (p->word[0]) {
     307:
     308:         case '(':
     309:             l++;
     310:             continue;
     311:
     312:         case ')':
     313:             l--;
     314:             continue;
     315:
     316:         case '|':
     317:             if (p->word[1] != '|')
     318:                 continue;
     319:             if (l == 0) {
     320:                 t = (struct command *) calloc(1, sizeof (*t));
     321:                 t->t_dtyp = TOR;
     322:                 t->t_dcar = syn1b(p1, p, flags);
     323:                 t->t_dcdr = syn1a(p->next, p2, flags);
     324:                 t->t_dflg = 0;
     325:                 return (t);
     326:             }
     327:             continue;
     328:         }
     329:     return (syn1b(p1, p2, flags));
     330: }
     331:
     332: /*
     333:  * syn1b
     334:  *	syn2
     335:  *	syn2 && syn1b
     336:  */
     337: struct command *
     338: syn1b(p1, p2, flags)
     339:     struct wordent *p1, *p2;
     340:     int flags;
     341: {
     342:     register struct wordent *p;
     343:     register struct command *t;
     344:     register int l = 0;
     345:
     346:     l = 0;
     347:     for (p = p1; p != p2; p = p->next)
     348:         switch (p->word[0]) {
     349:
     350:         case '(':
     351:             l++;
     352:             continue;
     353:
     354:         case ')':
     355:             l--;
     356:             continue;
     357:
     358:         case '&':
     359:             if (p->word[1] == '&' && l == 0) {
     360:                 t = (struct command *) calloc(1, sizeof (*t));
     361:                 t->t_dtyp = TAND;
     362:                 t->t_dcar = syn2(p1, p, flags);
     363:                 t->t_dcdr = syn1b(p->next, p2, flags);
     364:                 t->t_dflg = 0;
     365:                 return (t);
     366:             }
     367:             continue;
     368:         }
     369:     return (syn2(p1, p2, flags));
     370: }
     371:
     372: /*
     373:  * syn2
     374:  *	syn3
     375:  *	syn3 | syn2
     376:  *	syn3 |& syn2
     377:  */
     378: struct command *
     379: syn2(p1, p2, flags)
     380:     struct wordent *p1, *p2;
     381:     int flags;
     382: {
     383:     register struct wordent *p, *pn;
     384:     register struct command *t;
     385:     register int l = 0;
     386:     int f;
     387:
     388:     for (p = p1; p != p2; p = p->next)
     389:         switch (p->word[0]) {
     390:
     391:         case '(':
     392:             l++;
     393:             continue;
     394:
     395:         case ')':
     396:             l--;
     397:             continue;
     398:
     399:         case '|':
     400:             if (l != 0)
     401:                 continue;
     402:             t = (struct command *) calloc(1, sizeof (*t));
     403:             f = flags | POUT;
     404:             pn = p->next;
     405:             if (pn != p2 && pn->word[0] == '&') {
     406:                 f |= PDIAG;
     407:                 t->t_dflg |= FDIAG;
     408:             }
     409:             t->t_dtyp = TFIL;
     410:             t->t_dcar = syn3(p1, p, f);
     411:             if (pn != p2 && pn->word[0] == '&')
     412:                 p = pn;
     413:             t->t_dcdr = syn2(p->next, p2, flags | PIN);
     414:             return (t);
     415:         }
     416:     return (syn3(p1, p2, flags));
     417: }
     418:
     419: char    *RELPAR =   "<>()";
     420:
     421: /*
     422:  * syn3
     423:  *	( syn0 ) [ < in  ] [ > out ]
     424:  *	word word* [ < in ] [ > out ]
     425:  *	KEYWORD ( word* ) word* [ < in ] [ > out ]
     426:  *
     427:  *	KEYWORD = (@ exit foreach if set switch test while)
     428:  */
     429: struct command *
     430: syn3(p1, p2, flags)
     431:     struct wordent *p1, *p2;
     432:     int flags;
     433: {
     434:     register struct wordent *p;
     435:     struct wordent *lp, *rp;
     436:     register struct command *t;
     437:     register int l;
     438:     char **av;
     439:     int n, c;
     440:     bool specp = 0;
     441:
     442:     if (p1 != p2) {
     443:         p = p1;
     444: again:
     445:         switch (srchx(p->word)) {
     446:
     447:         case ZELSE:
     448:             p = p->next;
     449:             if (p != p2)
     450:                 goto again;
     451:             break;
     452:
     453:         case ZEXIT:
     454:         case ZFOREACH:
     455:         case ZIF:
     456:         case ZLET:
     457:         case ZSET:
     458:         case ZSWITCH:
     459:         case ZWHILE:
     460:             specp = 1;
     461:             break;
     462:         }
     463:     }
     464:     n = 0;
     465:     l = 0;
     466:     for (p = p1; p != p2; p = p->next)
     467:         switch (p->word[0]) {
     468:
     469:         case '(':
     470:             if (specp)
     471:                 n++;
     472:             l++;
     473:             continue;
     474:
     475:         case ')':
     476:             if (specp)
     477:                 n++;
     478:             l--;
     479:             continue;
     480:
     481:         case '>':
     482:         case '<':
     483:             if (l != 0) {
     484:                 if (specp)
     485:                     n++;
     486:                 continue;
     487:             }
     488:             if (p->next == p2)
     489:                 continue;
     490:             if (any(p->next->word[0], RELPAR))
     491:                 continue;
     492:             n--;
     493:             continue;
     494:
     495:         default:
     496:             if (!specp && l != 0)
     497:                 continue;
     498:             n++;
     499:             continue;
     500:         }
     501:     if (n < 0)
     502:         n = 0;
     503:     t = (struct command *) calloc(1, sizeof (*t));
     504:     av = (char **) calloc((unsigned) (n + 1), sizeof (char **));
     505:     t->t_dcom = av;
     506:     n = 0;
     507:     if (p2->word[0] == ')')
     508:         t->t_dflg = FPAR;
     509:     lp = 0;
     510:     rp = 0;
     511:     l = 0;
     512:     for (p = p1; p != p2; p = p->next) {
     513:         c = p->word[0];
     514:         switch (c) {
     515:
     516:         case '(':
     517:             if (l == 0) {
     518:                 if (lp != 0 && !specp)
     519:                     seterr("Badly placed (");
     520:                 lp = p->next;
     521:             }
     522:             l++;
     523:             goto savep;
     524:
     525:         case ')':
     526:             l--;
     527:             if (l == 0)
     528:                 rp = p;
     529:             goto savep;
     530:
     531:         case '>':
     532:             if (l != 0)
     533:                 goto savep;
     534:             if (p->word[1] == '>')
     535:                 t->t_dflg |= FCAT;
     536:             if (p->next != p2 && eq(p->next->word, "&")) {
     537:                 t->t_dflg |= FDIAG, p = p->next;
     538:                 if (flags & (POUT|PDIAG))
     539:                     goto badout;
     540:             }
     541:             if (p->next != p2 && eq(p->next->word, "!"))
     542:                 t->t_dflg |= FANY, p = p->next;
     543:             if (p->next == p2) {
     544: missfile:
     545:                 seterr("Missing name for redirect");
     546:                 continue;
     547:             }
     548:             p = p->next;
     549:             if (any(p->word[0], RELPAR))
     550:                 goto missfile;
     551:             if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
     552: badout:
     553:                 seterr("Ambiguous output redirect");
     554:             else
     555:                 t->t_drit = savestr(p->word);
     556:             continue;
     557:
     558:         case '<':
     559:             if (l != 0)
     560:                 goto savep;
     561:             if (p->word[1] == '<')
     562:                 t->t_dflg |= FHERE;
     563:             if (p->next == p2)
     564:                 goto missfile;
     565:             p = p->next;
     566:             if (any(p->word[0], RELPAR))
     567:                 goto missfile;
     568:             if ((flags & PHERE) && (t->t_dflg & FHERE))
     569:                 seterr("Can't << within ()'s");
     570:             else if ((flags & PIN) || t->t_dlef)
     571:                 seterr("Ambiguous input redirect");
     572:             else
     573:                 t->t_dlef = savestr(p->word);
     574:             continue;
     575:
     576: savep:
     577:             if (!specp)
     578:                 continue;
     579:         default:
     580:             if (l != 0 && !specp)
     581:                 continue;
     582:             if (err == 0)
     583:                 av[n] = savestr(p->word);
     584:             n++;
     585:             continue;
     586:         }
     587:     }
     588:     if (lp != 0 && !specp) {
     589:         if (n != 0)
     590:             seterr("Badly placed ()'s");
     591:         t->t_dtyp = TPAR;
     592:         t->t_dspr = syn0(lp, rp, PHERE);
     593:     } else {
     594:         if (n == 0)
     595:             seterr("Invalid null command");
     596:         t->t_dtyp = TCOM;
     597:     }
     598:     return (t);
     599: }
     600:
     601: freesyn(t)
     602:     register struct command *t;
     603: {
     604:     register char **v;
     605:
     606:     if (t == 0)
     607:         return;
     608:     switch (t->t_dtyp) {
     609:
     610:     case TCOM:
     611:         for (v = t->t_dcom; *v; v++)
     612:             XFREE(*v)
     613:         XFREE((char *)t->t_dcom)
     614:         goto lr;
     615:
     616:     case TPAR:
     617:         freesyn(t->t_dspr);
     618:         /* fall into ... */
     619:
     620: lr:
     621:         XFREE(t->t_dlef)
     622:         XFREE(t->t_drit)
     623:         break;
     624:
     625:     case TAND:
     626:     case TOR:
     627:     case TFIL:
     628:     case TLST:
     629:         freesyn(t->t_dcar), freesyn(t->t_dcdr);
     630:         break;
     631:     }
     632:     XFREE((char *)t)
     633: }

#### Defined functions

alias defined in line 23; used 4 times

- in /usr/src/bin/csh/sh.c line 784
- in /usr/src/bin/csh/sh.exec2.c line 166
- in /usr/src/bin/csh/sh.exp.c line 509
- in /usr/src/bin/csh/sh.glob.c line 662

asyn0 defined in line 54; used 2 times

- in line 49, 109

asyn3 defined in line 93; used 2 times

- in line 85-90(2)

asyntax defined in line 41; used 2 times

- in line 37, 86

freenod defined in line 143; used 2 times

- in line 131
- in /usr/src/bin/csh/sh.h line 415

freesyn defined in line 601; used 6 times

- in line 617, 629(2)
- in /usr/src/bin/csh/sh.c line 701, 801
- in /usr/src/bin/csh/sh.exp.c line 514

syn0 defined in line 188; used 3 times

- in line 179, 592
- in /usr/src/bin/csh/sh.h line 444

syn1 defined in line 255; used 3 times

- in line 226, 245
- in /usr/src/bin/csh/sh.h line 445

syn1a defined in line 296; used 4 times

- in line 282, 288, 323
- in /usr/src/bin/csh/sh.h line 446

syn1b defined in line 337; used 4 times

- in line 322, 329, 363
- in /usr/src/bin/csh/sh.h line 447

syn2 defined in line 378; used 4 times

- in line 362, 369, 413
- in /usr/src/bin/csh/sh.h line 448

syn3 defined in line 429; used 3 times

- in line 410, 416
- in /usr/src/bin/csh/sh.h line 449

syntax defined in line 169; used 6 times

- in line 241, 283
- in /usr/src/bin/csh/sh.c line 789
- in /usr/src/bin/csh/sh.exp.c line 510
- in /usr/src/bin/csh/sh.glob.c line 663
- in /usr/src/bin/csh/sh.h line 443

#### Defined variables

RELPAR defined in line 419; used 3 times

- in line 490, 549, 566

sccsid defined in line 8; never used

#### Defined macros

PDIAG defined in line 162; used 3 times

- in line 406, 538, 551

PHERE defined in line 159; used 2 times

- in line 568, 592

PIN defined in line 160; used 2 times

- in line 413, 570

POUT defined in line 161; used 3 times

- in line 403, 538, 551

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