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

Defined functions

alias defined in line 15; used 3 times
asyn0 defined in line 46; used 2 times
asyn3 defined in line 85; used 2 times
asyntax defined in line 33; used 2 times
freenod defined in line 135; used 2 times
freesyn defined in line 591; used 6 times
syn0 defined in line 180; used 3 times
syn1 defined in line 245; used 3 times
syn1a defined in line 286; used 4 times
syn1b defined in line 327; used 4 times
syn2 defined in line 368; used 4 times
syn3 defined in line 419; used 3 times
syntax defined in line 161; used 6 times

Defined variables

RELPAR defined in line 409; used 3 times
sccsid defined in line 1; never used

Defined macros

PDIAG defined in line 154; used 3 times
PHERE defined in line 151; used 2 times
PIN defined in line 152; used 2 times
POUT defined in line 153; used 3 times
Last modified: 1980-10-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1327
Valid CSS Valid XHTML 1.0 Strict