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: #ifndef lint
   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 3 times
asyn0 defined in line 54; used 2 times
asyn3 defined in line 93; used 2 times
asyntax defined in line 41; used 2 times
freenod defined in line 143; used 2 times
freesyn defined in line 601; used 6 times
syn0 defined in line 188; used 3 times
syn1 defined in line 255; used 3 times
syn1a defined in line 296; used 4 times
syn1b defined in line 337; used 4 times
syn2 defined in line 378; used 4 times
syn3 defined in line 429; used 3 times
syntax defined in line 169; used 6 times

Defined variables

RELPAR defined in line 419; used 3 times
sccsid defined in line 8; never used

Defined macros

PDIAG defined in line 162; used 3 times
PHERE defined in line 159; used 2 times
PIN defined in line 160; used 2 times
POUT defined in line 161; used 3 times
Last modified: 1986-05-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1811
Valid CSS Valid XHTML 1.0 Strict