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: }