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