|
|
1.1 ! root 1: /* Copyright (c) 1979 Regents of the University of California */ ! 2: #include "sh.h" ! 3: ! 4: /* ! 5: * C shell ! 6: */ ! 7: ! 8: /* ! 9: * Perform aliasing on the word list lex ! 10: * Do a (very rudimentary) parse to separate into commands. ! 11: * If word 0 of a command has an alias, do it. ! 12: * Repeat a maximum of 20 times. ! 13: */ ! 14: alias(lex) ! 15: register struct wordent *lex; ! 16: { ! 17: int aleft = 21; ! 18: jmp_buf osetexit; ! 19: ! 20: getexit(osetexit); ! 21: setexit(); ! 22: if (haderr) { ! 23: resexit(osetexit); ! 24: reset(); ! 25: } ! 26: if (--aleft == 0) ! 27: error("Alias loop"); ! 28: asyntax(lex->next, lex); ! 29: resexit(osetexit); ! 30: } ! 31: ! 32: asyntax(p1, p2) ! 33: register struct wordent *p1, *p2; ! 34: { ! 35: ! 36: while (p1 != p2) ! 37: if (any(p1->word[0], ";&\n")) ! 38: p1 = p1->next; ! 39: else { ! 40: asyn0(p1, p2); ! 41: return; ! 42: } ! 43: } ! 44: ! 45: asyn0(p1, p2) ! 46: struct wordent *p1; ! 47: register struct wordent *p2; ! 48: { ! 49: register struct wordent *p; ! 50: register int l = 0; ! 51: ! 52: for (p = p1; p != p2; p = p->next) ! 53: switch (p->word[0]) { ! 54: ! 55: case '(': ! 56: l++; ! 57: continue; ! 58: ! 59: case ')': ! 60: l--; ! 61: if (l < 0) ! 62: error("Too many )'s"); ! 63: continue; ! 64: ! 65: case '>': ! 66: if (p->next != p2 && eq(p->next->word, "&")) ! 67: p = p->next; ! 68: continue; ! 69: ! 70: case '&': ! 71: case '|': ! 72: case ';': ! 73: case '\n': ! 74: if (l != 0) ! 75: continue; ! 76: asyn3(p1, p); ! 77: asyntax(p->next, p2); ! 78: return; ! 79: } ! 80: if (l == 0) ! 81: asyn3(p1, p2); ! 82: } ! 83: ! 84: asyn3(p1, p2) ! 85: struct wordent *p1; ! 86: register struct wordent *p2; ! 87: { ! 88: register struct varent *ap; ! 89: struct wordent alout; ! 90: register bool redid; ! 91: ! 92: if (p1 == p2) ! 93: return; ! 94: if (p1->word[0] == '(') { ! 95: for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev) ! 96: if (p2 == p1) ! 97: return; ! 98: if (p2 == p1->next) ! 99: return; ! 100: asyn0(p1->next, p2); ! 101: return; ! 102: } ! 103: ap = adrof1(p1->word, &aliases); ! 104: if (ap == 0) ! 105: return; ! 106: alhistp = p1->prev; ! 107: alhistt = p2; ! 108: alvec = ap->vec; ! 109: redid = lex(&alout); ! 110: alhistp = alhistt = 0; ! 111: alvec = 0; ! 112: if (err) { ! 113: freelex(&alout); ! 114: error(err); ! 115: } ! 116: if (p1->word[0] && eq(p1->word, alout.next->word)) { ! 117: char *cp = alout.next->word; ! 118: ! 119: alout.next->word = strspl("\200", cp); ! 120: xfree(cp); ! 121: } ! 122: p1 = freenod(p1, redid ? p2 : p1->next); ! 123: if (alout.next != &alout) { ! 124: p1->next->prev = alout.prev->prev; ! 125: alout.prev->prev->next = p1->next; ! 126: alout.next->prev = p1; ! 127: p1->next = alout.next; ! 128: xfree(alout.prev->word); ! 129: xfree(alout.prev); ! 130: } ! 131: reset(); /* throw! */ ! 132: } ! 133: ! 134: struct wordent * ! 135: freenod(p1, p2) ! 136: register struct wordent *p1, *p2; ! 137: { ! 138: register struct wordent *retp = p1->prev; ! 139: ! 140: while (p1 != p2) { ! 141: xfree(p1->word); ! 142: p1 = p1->next; ! 143: xfree(p1->prev); ! 144: } ! 145: retp->next = p2; ! 146: p2->prev = retp; ! 147: return (retp); ! 148: } ! 149: ! 150: #define PHERE 1 ! 151: #define PIN 2 ! 152: #define POUT 4 ! 153: #define PDIAG 8 ! 154: ! 155: /* ! 156: * syntax ! 157: * empty ! 158: * syn0 ! 159: */ ! 160: struct command * ! 161: syntax(p1, p2, flags) ! 162: register struct wordent *p1, *p2; ! 163: int flags; ! 164: { ! 165: ! 166: while (p1 != p2) ! 167: if (any(p1->word[0], ";&\n")) ! 168: p1 = p1->next; ! 169: else ! 170: return (syn0(p1, p2, flags)); ! 171: return (0); ! 172: } ! 173: ! 174: /* ! 175: * syn0 ! 176: * syn1 ! 177: * syn1 & syntax ! 178: */ ! 179: struct command * ! 180: syn0(p1, p2, flags) ! 181: struct wordent *p1, *p2; ! 182: int flags; ! 183: { ! 184: register struct wordent *p; ! 185: register struct command *t, *t1; ! 186: int l; ! 187: ! 188: l = 0; ! 189: for (p = p1; p != p2; p = p->next) ! 190: switch (p->word[0]) { ! 191: ! 192: case '(': ! 193: l++; ! 194: continue; ! 195: ! 196: case ')': ! 197: l--; ! 198: if (l < 0) ! 199: seterr("Too many )'s"); ! 200: continue; ! 201: ! 202: case '|': ! 203: if (p->word[1] == '|') ! 204: continue; ! 205: /* fall into ... */ ! 206: ! 207: case '>': ! 208: if (p->next != p2 && eq(p->next->word, "&")) ! 209: p = p->next; ! 210: continue; ! 211: ! 212: case '&': ! 213: if (l != 0) ! 214: break; ! 215: if (p->word[1] == '&') ! 216: continue; ! 217: t1 = syn1(p1, p, flags); ! 218: if (t1->t_dtyp == TLST) { ! 219: t = (struct command *) calloc(1, sizeof (*t)); ! 220: t->t_dtyp = TPAR; ! 221: t->t_dflg = FAND|FPRS|FINT; ! 222: t->t_dspr = t1; ! 223: t1 = t; ! 224: } else ! 225: t1->t_dflg |= FAND|FPRS|FINT; ! 226: t = (struct command *) calloc(1, sizeof (*t)); ! 227: t->t_dtyp = TLST; ! 228: t->t_dflg = 0; ! 229: t->t_dcar = t1; ! 230: t->t_dcdr = syntax(p, p2, flags); ! 231: return(t); ! 232: } ! 233: if (l == 0) ! 234: return (syn1(p1, p2, flags)); ! 235: seterr("Too many ('s"); ! 236: return (0); ! 237: } ! 238: ! 239: /* ! 240: * syn1 ! 241: * syn1a ! 242: * syn1a ; syntax ! 243: */ ! 244: struct command * ! 245: syn1(p1, p2, flags) ! 246: struct wordent *p1, *p2; ! 247: int flags; ! 248: { ! 249: register struct wordent *p; ! 250: register struct command *t; ! 251: int l; ! 252: ! 253: l = 0; ! 254: for (p = p1; p != p2; p = p->next) ! 255: switch (p->word[0]) { ! 256: ! 257: case '(': ! 258: l++; ! 259: continue; ! 260: ! 261: case ')': ! 262: l--; ! 263: continue; ! 264: ! 265: case ';': ! 266: case '\n': ! 267: if (l != 0) ! 268: break; ! 269: t = (struct command *) calloc(1, sizeof (*t)); ! 270: t->t_dtyp = TLST; ! 271: t->t_dcar = syn1a(p1, p, flags); ! 272: t->t_dcdr = syntax(p->next, p2, flags); ! 273: if (t->t_dcdr == 0) ! 274: t->t_dcdr = t->t_dcar, t->t_dcar = 0; ! 275: return (t); ! 276: } ! 277: return (syn1a(p1, p2, flags)); ! 278: } ! 279: ! 280: /* ! 281: * syn1a ! 282: * syn1b ! 283: * syn1b || syn1a ! 284: */ ! 285: struct command * ! 286: syn1a(p1, p2, flags) ! 287: struct wordent *p1, *p2; ! 288: int flags; ! 289: { ! 290: register struct wordent *p; ! 291: register struct command *t; ! 292: register int l = 0; ! 293: ! 294: for (p = p1; p != p2; p = p->next) ! 295: switch (p->word[0]) { ! 296: ! 297: case '(': ! 298: l++; ! 299: continue; ! 300: ! 301: case ')': ! 302: l--; ! 303: continue; ! 304: ! 305: case '|': ! 306: if (p->word[1] != '|') ! 307: continue; ! 308: if (l == 0) { ! 309: t = (struct command *) calloc(1, sizeof (*t)); ! 310: t->t_dtyp = TOR; ! 311: t->t_dcar = syn1b(p1, p, flags); ! 312: t->t_dcdr = syn1a(p->next, p2, flags); ! 313: t->t_dflg = 0; ! 314: return (t); ! 315: } ! 316: continue; ! 317: } ! 318: return (syn1b(p1, p2, flags)); ! 319: } ! 320: ! 321: /* ! 322: * syn1b ! 323: * syn2 ! 324: * syn2 && syn1b ! 325: */ ! 326: struct command * ! 327: syn1b(p1, p2, flags) ! 328: struct wordent *p1, *p2; ! 329: int flags; ! 330: { ! 331: register struct wordent *p; ! 332: register struct command *t; ! 333: register int l = 0; ! 334: ! 335: l = 0; ! 336: for (p = p1; p != p2; p = p->next) ! 337: switch (p->word[0]) { ! 338: ! 339: case '(': ! 340: l++; ! 341: continue; ! 342: ! 343: case ')': ! 344: l--; ! 345: continue; ! 346: ! 347: case '&': ! 348: if (p->word[1] == '&' && l == 0) { ! 349: t = (struct command *) calloc(1, sizeof (*t)); ! 350: t->t_dtyp = TAND; ! 351: t->t_dcar = syn2(p1, p, flags); ! 352: t->t_dcdr = syn1b(p->next, p2, flags); ! 353: t->t_dflg = 0; ! 354: return (t); ! 355: } ! 356: continue; ! 357: } ! 358: return (syn2(p1, p2, flags)); ! 359: } ! 360: ! 361: /* ! 362: * syn2 ! 363: * syn3 ! 364: * syn3 | syn2 ! 365: * syn3 |& syn2 ! 366: */ ! 367: struct command * ! 368: syn2(p1, p2, flags) ! 369: struct wordent *p1, *p2; ! 370: int flags; ! 371: { ! 372: register struct wordent *p, *pn; ! 373: register struct command *t; ! 374: register int l = 0; ! 375: int f; ! 376: ! 377: for (p = p1; p != p2; p = p->next) ! 378: switch (p->word[0]) { ! 379: ! 380: case '(': ! 381: l++; ! 382: continue; ! 383: ! 384: case ')': ! 385: l--; ! 386: continue; ! 387: ! 388: case '|': ! 389: if (l != 0) ! 390: continue; ! 391: t = (struct command *) calloc(1, sizeof (*t)); ! 392: f = flags | POUT; ! 393: pn = p->next; ! 394: if (pn != p2 && pn->word[0] == '&') { ! 395: f |= PDIAG; ! 396: t->t_dflg |= FDIAG; ! 397: } ! 398: t->t_dtyp = TFIL; ! 399: t->t_dcar = syn3(p1, p, f); ! 400: if (pn != p2 && pn->word[0] == '&') ! 401: p = pn; ! 402: t->t_dcdr = syn2(p->next, p2, flags | PIN); ! 403: return (t); ! 404: } ! 405: return (syn3(p1, p2, flags)); ! 406: } ! 407: ! 408: char *RELPAR = "<>()"; ! 409: ! 410: /* ! 411: * syn3 ! 412: * ( syn0 ) [ < in ] [ > out ] ! 413: * word word* [ < in ] [ > out ] ! 414: * KEYWORD ( word* ) word* [ < in ] [ > out ] ! 415: * ! 416: * KEYWORD = (@ exit foreach if set switch test while) ! 417: */ ! 418: struct command * ! 419: syn3(p1, p2, flags) ! 420: struct wordent *p1, *p2; ! 421: int flags; ! 422: { ! 423: register struct wordent *p; ! 424: struct wordent *lp, *rp; ! 425: register struct command *t; ! 426: register int l; ! 427: char **av; ! 428: int n, c; ! 429: bool specp = 0; ! 430: ! 431: if (p1 != p2) { ! 432: p = p1; ! 433: again: ! 434: switch (srchx(p->word)) { ! 435: ! 436: case ZELSE: ! 437: p = p->next; ! 438: if (p != p2) ! 439: goto again; ! 440: break; ! 441: ! 442: case ZEXIT: ! 443: case ZFOREACH: ! 444: case ZIF: ! 445: case ZLET: ! 446: case ZSET: ! 447: case ZSWITCH: ! 448: case ZWHILE: ! 449: specp = 1; ! 450: break; ! 451: } ! 452: } ! 453: n = 0; ! 454: l = 0; ! 455: for (p = p1; p != p2; p = p->next) ! 456: switch (p->word[0]) { ! 457: ! 458: case '(': ! 459: if (specp) ! 460: n++; ! 461: l++; ! 462: continue; ! 463: ! 464: case ')': ! 465: if (specp) ! 466: n++; ! 467: l--; ! 468: continue; ! 469: ! 470: case '>': ! 471: case '<': ! 472: if (l != 0) { ! 473: if (specp) ! 474: n++; ! 475: continue; ! 476: } ! 477: if (p->next == p2) ! 478: continue; ! 479: if (any(p->next->word[0], RELPAR)) ! 480: continue; ! 481: n--; ! 482: continue; ! 483: ! 484: default: ! 485: if (!specp && l != 0) ! 486: continue; ! 487: n++; ! 488: continue; ! 489: } ! 490: if (n < 0) ! 491: n = 0; ! 492: t = (struct command *) calloc(1, sizeof (*t)); ! 493: av = (char **) calloc(n + 1, sizeof (char **)); ! 494: t->t_dcom = av; ! 495: n = 0; ! 496: if (p2->word[0] == ')') ! 497: t->t_dflg = FPAR; ! 498: lp = 0; ! 499: rp = 0; ! 500: l = 0; ! 501: for (p = p1; p != p2; p = p->next) { ! 502: c = p->word[0]; ! 503: switch (c) { ! 504: ! 505: case '(': ! 506: if (l == 0) { ! 507: if (lp != 0 && !specp) ! 508: seterr("Badly placed ("); ! 509: lp = p->next; ! 510: } ! 511: l++; ! 512: goto savep; ! 513: ! 514: case ')': ! 515: l--; ! 516: if (l == 0) ! 517: rp = p; ! 518: goto savep; ! 519: ! 520: case '>': ! 521: if (l != 0) ! 522: goto savep; ! 523: if (p->word[1] == '>') ! 524: t->t_dflg |= FCAT; ! 525: if (p->next != p2 && eq(p->next->word, "&")) { ! 526: t->t_dflg |= FDIAG, p = p->next; ! 527: if (flags & (POUT|PDIAG)) ! 528: goto badout; ! 529: } ! 530: if (p->next != p2 && eq(p->next->word, "!")) ! 531: t->t_dflg |= FANY, p = p->next; ! 532: if (p->next == p2) { ! 533: missfile: ! 534: seterr("Missing name for redirect"); ! 535: continue; ! 536: } ! 537: p = p->next; ! 538: if (any(p->word[0], RELPAR)) ! 539: goto missfile; ! 540: if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit) ! 541: badout: ! 542: seterr("Ambiguous output redirect"); ! 543: else ! 544: t->t_drit = savestr(p->word); ! 545: continue; ! 546: ! 547: case '<': ! 548: if (l != 0) ! 549: goto savep; ! 550: if (p->word[1] == '<') ! 551: t->t_dflg |= FHERE; ! 552: if (p->next == p2) ! 553: goto missfile; ! 554: p = p->next; ! 555: if (any(p->word[0], RELPAR)) ! 556: goto missfile; ! 557: if ((flags & PHERE) && (t->t_dflg & FHERE)) ! 558: seterr("Can't << within ()'s"); ! 559: else if ((flags & PIN) || t->t_dlef) ! 560: seterr("Ambiguous input redirect"); ! 561: else ! 562: t->t_dlef = savestr(p->word); ! 563: continue; ! 564: ! 565: savep: ! 566: if (!specp) ! 567: continue; ! 568: default: ! 569: if (l != 0 && !specp) ! 570: continue; ! 571: if (err == 0) ! 572: av[n] = savestr(p->word); ! 573: n++; ! 574: continue; ! 575: } ! 576: } ! 577: if (lp != 0 && !specp) { ! 578: if (n != 0) ! 579: seterr("Badly placed ()'s"); ! 580: t->t_dtyp = TPAR; ! 581: t->t_dspr = syn0(lp, rp, PHERE); ! 582: } else { ! 583: if (n == 0) ! 584: seterr("Invalid null command"); ! 585: t->t_dtyp = TCOM; ! 586: } ! 587: return (t); ! 588: } ! 589: ! 590: freesyn(t) ! 591: register struct command *t; ! 592: { ! 593: register char **v; ! 594: ! 595: if (t == 0) ! 596: return; ! 597: switch (t->t_dtyp) { ! 598: ! 599: case TCOM: ! 600: for (v = t->t_dcom; *v; v++) ! 601: xfree(*v); ! 602: xfree(t->t_dcom); ! 603: goto lr; ! 604: ! 605: case TPAR: ! 606: freesyn(t->t_dspr); ! 607: /* fall into ... */ ! 608: ! 609: lr: ! 610: xfree(t->t_dlef), xfree(t->t_drit); ! 611: break; ! 612: ! 613: case TAND: ! 614: case TOR: ! 615: case TFIL: ! 616: case TLST: ! 617: freesyn(t->t_dcar), freesyn(t->t_dcdr); ! 618: break; ! 619: } ! 620: xfree(t); ! 621: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.