|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.