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