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

Defined functions

asyn0 defined in line 50; used 2 times
asyn3 defined in line 89; used 2 times
asyntax defined in line 37; used 2 times
freenod defined in line 149; used 2 times
freesyn defined in line 605; used 6 times
syn0 defined in line 194; used 3 times
syn1 defined in line 259; used 3 times
syn1a defined in line 300; used 4 times
syn1b defined in line 341; used 4 times
syn2 defined in line 382; used 4 times
syn3 defined in line 433; used 3 times

Defined variables

RELPAR defined in line 423; used 3 times

Defined macros

PDIAG defined in line 168; used 3 times
PHERE defined in line 165; used 2 times
PIN defined in line 166; used 2 times
POUT defined in line 167; used 3 times
Last modified: 1980-09-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1363
Valid CSS Valid XHTML 1.0 Strict