|
|
1.1 ! root 1: static char *sccsid = "@(#)sh.exp.c 4.1 10/9/80"; ! 2: ! 3: #include "sh.h" ! 4: ! 5: /* ! 6: * C shell ! 7: */ ! 8: ! 9: #define IGNORE 1 /* in ignore, it means to ignore value, just parse */ ! 10: #define NOGLOB 2 /* in ignore, it means not to globone */ ! 11: ! 12: #define ADDOP 1 ! 13: #define MULOP 2 ! 14: #define EQOP 4 ! 15: #define RELOP 8 ! 16: #define RESTOP 16 ! 17: #define ANYOP 31 ! 18: ! 19: #define EQEQ 1 ! 20: #define GTR 2 ! 21: #define LSS 4 ! 22: #define NOTEQ 6 ! 23: #define EQMATCH 7 ! 24: #define NOTEQMATCH 8 ! 25: ! 26: exp(vp) ! 27: register char ***vp; ! 28: { ! 29: ! 30: return (exp0(vp, 0)); ! 31: } ! 32: ! 33: exp0(vp, ignore) ! 34: register char ***vp; ! 35: bool ignore; ! 36: { ! 37: register int p1 = exp1(vp, ignore); ! 38: ! 39: #ifdef EDEBUG ! 40: etraci("exp0 p1", p1, vp); ! 41: #endif ! 42: if (**vp && eq(**vp, "||")) { ! 43: register int p2; ! 44: ! 45: (*vp)++; ! 46: p2 = exp0(vp, (ignore&IGNORE) || p1); ! 47: #ifdef EDEBUG ! 48: etraci("exp0 p2", p2, vp); ! 49: #endif ! 50: return (p1 || p2); ! 51: } ! 52: return (p1); ! 53: } ! 54: ! 55: exp1(vp, ignore) ! 56: register char ***vp; ! 57: { ! 58: register int p1 = exp2(vp, ignore); ! 59: ! 60: #ifdef EDEBUG ! 61: etraci("exp1 p1", p1, vp); ! 62: #endif ! 63: if (**vp && eq(**vp, "&&")) { ! 64: register int p2; ! 65: ! 66: (*vp)++; ! 67: p2 = exp1(vp, (ignore&IGNORE) || !p1); ! 68: #ifdef EDEBUG ! 69: etraci("exp1 p2", p2, vp); ! 70: #endif ! 71: return (p1 && p2); ! 72: } ! 73: return (p1); ! 74: } ! 75: ! 76: exp2(vp, ignore) ! 77: register char ***vp; ! 78: bool ignore; ! 79: { ! 80: register int p1 = exp2a(vp, ignore); ! 81: ! 82: #ifdef EDEBUG ! 83: etraci("exp3 p1", p1, vp); ! 84: #endif ! 85: if (**vp && eq(**vp, "|")) { ! 86: register int p2; ! 87: ! 88: (*vp)++; ! 89: p2 = exp2(vp, ignore); ! 90: #ifdef EDEBUG ! 91: etraci("exp3 p2", p2, vp); ! 92: #endif ! 93: return (p1 | p2); ! 94: } ! 95: return (p1); ! 96: } ! 97: ! 98: exp2a(vp, ignore) ! 99: register char ***vp; ! 100: bool ignore; ! 101: { ! 102: register int p1 = exp2b(vp, ignore); ! 103: ! 104: #ifdef EDEBUG ! 105: etraci("exp2a p1", p1, vp); ! 106: #endif ! 107: if (**vp && eq(**vp, "^")) { ! 108: register int p2; ! 109: ! 110: (*vp)++; ! 111: p2 = exp2a(vp, ignore); ! 112: #ifdef EDEBUG ! 113: etraci("exp2a p2", p2, vp); ! 114: #endif ! 115: return (p1 ^ p2); ! 116: } ! 117: return (p1); ! 118: } ! 119: ! 120: exp2b(vp, ignore) ! 121: register char ***vp; ! 122: bool ignore; ! 123: { ! 124: register int p1 = exp2c(vp, ignore); ! 125: ! 126: #ifdef EDEBUG ! 127: etraci("exp2b p1", p1, vp); ! 128: #endif ! 129: if (**vp && eq(**vp, "&")) { ! 130: register int p2; ! 131: ! 132: (*vp)++; ! 133: p2 = exp2b(vp, ignore); ! 134: #ifdef EDEBUG ! 135: etraci("exp2b p2", p2, vp); ! 136: #endif ! 137: return (p1 & p2); ! 138: } ! 139: return (p1); ! 140: } ! 141: ! 142: exp2c(vp, ignore) ! 143: register char ***vp; ! 144: bool ignore; ! 145: { ! 146: register char *p1 = exp3(vp, ignore); ! 147: register char *p2; ! 148: register int i; ! 149: ! 150: #ifdef EDEBUG ! 151: etracc("exp2c p1", p1, vp); ! 152: #endif ! 153: if (i = isa(**vp, EQOP)) { ! 154: (*vp)++; ! 155: if (i == EQMATCH || i == NOTEQMATCH) ! 156: ignore |= NOGLOB; ! 157: p2 = exp3(vp, ignore); ! 158: #ifdef EDEBUG ! 159: etracc("exp2c p2", p2, vp); ! 160: #endif ! 161: if (!(ignore&IGNORE)) switch (i) { ! 162: ! 163: case EQEQ: ! 164: i = eq(p1, p2); ! 165: break; ! 166: ! 167: case NOTEQ: ! 168: i = !eq(p1, p2); ! 169: break; ! 170: ! 171: case EQMATCH: ! 172: i = Gmatch(p1, p2); ! 173: break; ! 174: ! 175: case NOTEQMATCH: ! 176: i = !Gmatch(p1, p2); ! 177: break; ! 178: } ! 179: xfree(p1), xfree(p2); ! 180: return (i); ! 181: } ! 182: i = egetn(p1); ! 183: xfree(p1); ! 184: return (i); ! 185: } ! 186: ! 187: char * ! 188: exp3(vp, ignore) ! 189: register char ***vp; ! 190: bool ignore; ! 191: { ! 192: register char *p1, *p2; ! 193: register int i; ! 194: ! 195: p1 = exp3a(vp, ignore); ! 196: #ifdef EDEBUG ! 197: etracc("exp3 p1", p1, vp); ! 198: #endif ! 199: if (i = isa(**vp, RELOP)) { ! 200: (*vp)++; ! 201: if (**vp && eq(**vp, "=")) ! 202: i |= 1, (*vp)++; ! 203: p2 = exp3(vp, ignore); ! 204: #ifdef EDEBUG ! 205: etracc("exp3 p2", p2, vp); ! 206: #endif ! 207: if (!(ignore&IGNORE)) switch (i) { ! 208: ! 209: case GTR: ! 210: i = egetn(p1) > egetn(p2); ! 211: break; ! 212: ! 213: case GTR|1: ! 214: i = egetn(p1) >= egetn(p2); ! 215: break; ! 216: ! 217: case LSS: ! 218: i = egetn(p1) < egetn(p2); ! 219: break; ! 220: ! 221: case LSS|1: ! 222: i = egetn(p1) <= egetn(p2); ! 223: break; ! 224: } ! 225: xfree(p1), xfree(p2); ! 226: return (putn(i)); ! 227: } ! 228: return (p1); ! 229: } ! 230: ! 231: char * ! 232: exp3a(vp, ignore) ! 233: register char ***vp; ! 234: bool ignore; ! 235: { ! 236: register char *p1, *p2, *op; ! 237: register int i; ! 238: ! 239: p1 = exp4(vp, ignore); ! 240: #ifdef EDEBUG ! 241: etracc("exp3a p1", p1, vp); ! 242: #endif ! 243: op = **vp; ! 244: if (op && any(op[0], "<>") && op[0] == op[1]) { ! 245: (*vp)++; ! 246: p2 = exp3a(vp, ignore); ! 247: #ifdef EDEBUG ! 248: etracc("exp3a p2", p2, vp); ! 249: #endif ! 250: if (op[0] == '<') ! 251: i = egetn(p1) << egetn(p2); ! 252: else ! 253: i = egetn(p1) >> egetn(p2); ! 254: xfree(p1), xfree(p2); ! 255: return (putn(i)); ! 256: } ! 257: return (p1); ! 258: } ! 259: ! 260: char * ! 261: exp4(vp, ignore) ! 262: register char ***vp; ! 263: bool ignore; ! 264: { ! 265: register char *p1, *p2; ! 266: register int i = 0; ! 267: ! 268: p1 = exp5(vp, ignore); ! 269: #ifdef EDEBUG ! 270: etracc("exp4 p1", p1, vp); ! 271: #endif ! 272: if (isa(**vp, ADDOP)) { ! 273: register char *op = *(*vp)++; ! 274: ! 275: p2 = exp4(vp, ignore); ! 276: #ifdef EDEBUG ! 277: etracc("exp4 p2", p2, vp); ! 278: #endif ! 279: if (!(ignore&IGNORE)) switch (op[0]) { ! 280: ! 281: case '+': ! 282: i = egetn(p1) + egetn(p2); ! 283: break; ! 284: ! 285: case '-': ! 286: i = egetn(p1) - egetn(p2); ! 287: break; ! 288: } ! 289: xfree(p1), xfree(p2); ! 290: return (putn(i)); ! 291: } ! 292: return (p1); ! 293: } ! 294: ! 295: char * ! 296: exp5(vp, ignore) ! 297: register char ***vp; ! 298: bool ignore; ! 299: { ! 300: register char *p1, *p2; ! 301: register int i = 0; ! 302: ! 303: p1 = exp6(vp, ignore); ! 304: #ifdef EDEBUG ! 305: etracc("exp5 p1", p1, vp); ! 306: #endif ! 307: if (isa(**vp, MULOP)) { ! 308: register char *op = *(*vp)++; ! 309: ! 310: p2 = exp5(vp, ignore); ! 311: #ifdef EDEBUG ! 312: etracc("exp5 p2", p2, vp); ! 313: #endif ! 314: if (!(ignore&IGNORE)) switch (op[0]) { ! 315: ! 316: case '*': ! 317: i = egetn(p1) * egetn(p2); ! 318: break; ! 319: ! 320: case '/': ! 321: i = egetn(p2); ! 322: if (i == 0) ! 323: error("Divide by 0"); ! 324: i = egetn(p1) / i; ! 325: break; ! 326: ! 327: case '%': ! 328: i = egetn(p2); ! 329: if (i == 0) ! 330: error("Mod by 0"); ! 331: i = egetn(p1) % i; ! 332: break; ! 333: } ! 334: xfree(p1), xfree(p2); ! 335: return (putn(i)); ! 336: } ! 337: return (p1); ! 338: } ! 339: ! 340: char * ! 341: exp6(vp, ignore) ! 342: register char ***vp; ! 343: { ! 344: int ccode, i; ! 345: register char *cp, *dp, *ep; ! 346: ! 347: if (eq(**vp, "!")) { ! 348: (*vp)++; ! 349: cp = exp6(vp, ignore); ! 350: #ifdef EDEBUG ! 351: etracc("exp6 ! cp", cp, vp); ! 352: #endif ! 353: i = egetn(cp); ! 354: xfree(cp); ! 355: return (putn(!i)); ! 356: } ! 357: if (eq(**vp, "~")) { ! 358: (*vp)++; ! 359: cp = exp6(vp, ignore); ! 360: #ifdef EDEBUG ! 361: etracc("exp6 ~ cp", cp, vp); ! 362: #endif ! 363: i = egetn(cp); ! 364: xfree(cp); ! 365: return (putn(~i)); ! 366: } ! 367: if (eq(**vp, "(")) { ! 368: (*vp)++; ! 369: ccode = exp0(vp, ignore); ! 370: #ifdef EDEBUG ! 371: etraci("exp6 () ccode", ccode, vp); ! 372: #endif ! 373: if (*vp == 0 || **vp == 0 || ***vp != ')') ! 374: bferr("Expression syntax"); ! 375: (*vp)++; ! 376: return (putn(ccode)); ! 377: } ! 378: if (eq(**vp, "{")) { ! 379: register char **v; ! 380: struct command faket; ! 381: char *fakecom[2]; ! 382: ! 383: faket.t_dtyp = TCOM; ! 384: faket.t_dflg = 0; ! 385: faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0; ! 386: faket.t_dcom = fakecom; ! 387: fakecom[0] = "{ ... }"; ! 388: fakecom[1] = NOSTR; ! 389: (*vp)++; ! 390: v = *vp; ! 391: for (;;) { ! 392: if (!**vp) ! 393: bferr("Missing }"); ! 394: if (eq(*(*vp)++, "}")) ! 395: break; ! 396: } ! 397: if (ignore&IGNORE) ! 398: return (""); ! 399: psavejob(); ! 400: if (pfork(&faket, -1) == 0) { ! 401: *--(*vp) = 0; ! 402: evalav(v); ! 403: exitstat(); ! 404: } ! 405: pwait(); ! 406: prestjob(); ! 407: #ifdef EDEBUG ! 408: etraci("exp6 {} status", egetn(value("status")), vp); ! 409: #endif ! 410: return (putn(egetn(value("status")) == 0)); ! 411: } ! 412: if (isa(**vp, ANYOP)) ! 413: return (""); ! 414: cp = *(*vp)++; ! 415: if (*cp == '-' && any(cp[1], "erwxfdzo")) { ! 416: struct stat stb; ! 417: ! 418: if (isa(**vp, ANYOP)) ! 419: bferr("Missing file name"); ! 420: dp = *(*vp)++; ! 421: if (ignore&IGNORE) ! 422: return (""); ! 423: ep = globone(dp); ! 424: switch (cp[1]) { ! 425: ! 426: case 'r': ! 427: i = !access(ep, 4); ! 428: break; ! 429: ! 430: case 'w': ! 431: i = !access(ep, 2); ! 432: break; ! 433: ! 434: case 'x': ! 435: i = !access(ep, 1); ! 436: break; ! 437: ! 438: default: ! 439: if (stat(ep, &stb)) { ! 440: xfree(ep); ! 441: return ("0"); ! 442: } ! 443: switch (cp[1]) { ! 444: ! 445: case 'f': ! 446: i = (stb.st_mode & S_IFMT) == S_IFREG; ! 447: break; ! 448: ! 449: case 'd': ! 450: i = (stb.st_mode & S_IFMT) == S_IFDIR; ! 451: break; ! 452: ! 453: case 'z': ! 454: i = stb.st_size == 0; ! 455: break; ! 456: ! 457: case 'e': ! 458: i = 1; ! 459: break; ! 460: ! 461: case 'o': ! 462: i = stb.st_uid == uid; ! 463: break; ! 464: } ! 465: } ! 466: #ifdef EDEBUG ! 467: etraci("exp6 -? i", i, vp); ! 468: #endif ! 469: xfree(ep); ! 470: return (putn(i)); ! 471: } ! 472: #ifdef EDEBUG ! 473: etracc("exp6 default", cp, vp); ! 474: #endif ! 475: return (ignore&NOGLOB ? cp : globone(cp)); ! 476: } ! 477: ! 478: evalav(v) ! 479: register char **v; ! 480: { ! 481: struct wordent paraml; ! 482: register struct wordent *hp = ¶ml; ! 483: struct command *t; ! 484: register struct wordent *wdp = hp; ! 485: ! 486: set("status", "0"); ! 487: hp->prev = hp->next = hp; ! 488: hp->word = ""; ! 489: while (*v) { ! 490: register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp); ! 491: ! 492: new->prev = wdp; ! 493: new->next = hp; ! 494: wdp->next = new; ! 495: wdp = new; ! 496: wdp->word = savestr(*v++); ! 497: } ! 498: hp->prev = wdp; ! 499: alias(¶ml); ! 500: t = syntax(paraml.next, ¶ml, 0); ! 501: if (err) ! 502: error(err); ! 503: execute(t, -1); ! 504: freelex(¶ml), freesyn(t); ! 505: } ! 506: ! 507: isa(cp, what) ! 508: register char *cp; ! 509: register int what; ! 510: { ! 511: ! 512: if (cp == 0) ! 513: return ((what & RESTOP) != 0); ! 514: if (cp[1] == 0) { ! 515: if ((what & ADDOP) && any(cp[0], "+-")) ! 516: return (1); ! 517: if ((what & MULOP) && any(cp[0], "*/%")) ! 518: return (1); ! 519: if ((what & RESTOP) && any(cp[0], "()!~^")) ! 520: return (1); ! 521: } ! 522: if ((what & RESTOP) && (any(cp[0], "|&") || eq(cp, "<<") || eq(cp, ">>"))) ! 523: return (1); ! 524: if (what & EQOP) { ! 525: if (eq(cp, "==")) ! 526: return (EQEQ); ! 527: if (eq(cp, "!=")) ! 528: return (NOTEQ); ! 529: if (eq(cp, "=~")) ! 530: return (EQMATCH); ! 531: if (eq(cp, "!~")) ! 532: return (NOTEQMATCH); ! 533: } ! 534: if (!(what & RELOP)) ! 535: return (0); ! 536: if (*cp == '<') ! 537: return (LSS); ! 538: if (*cp == '>') ! 539: return (GTR); ! 540: return (0); ! 541: } ! 542: ! 543: egetn(cp) ! 544: register char *cp; ! 545: { ! 546: ! 547: if (*cp && *cp != '-' && !digit(*cp)) ! 548: bferr("Expression syntax"); ! 549: return (getn(cp)); ! 550: } ! 551: ! 552: /* Phew! */ ! 553: ! 554: #ifdef EDEBUG ! 555: etraci(str, i, vp) ! 556: char *str; ! 557: int i; ! 558: char ***vp; ! 559: { ! 560: ! 561: printf("%s=%d\t", str, i); ! 562: blkpr(*vp); ! 563: printf("\n"); ! 564: } ! 565: ! 566: etracc(str, cp, vp) ! 567: char *str, *cp; ! 568: char ***vp; ! 569: { ! 570: ! 571: printf("%s=%s\t", str, cp); ! 572: blkpr(*vp); ! 573: printf("\n"); ! 574: } ! 575: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.