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