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