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