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 = &paraml;
 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(&paraml);
 483:     t = syntax(paraml.next, &paraml, 0);
 484:     if (err)
 485:         error(err);
 486:     execute(t);
 487:     freelex(&paraml), 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

Defined functions

egetn defined in line 522; used 27 times
etracc defined in line 545; used 13 times
etraci defined in line 534; used 13 times
evalav defined in line 460; used 1 times
exp defined in line 21; used 5 times
exp0 defined in line 28; used 4 times
exp1 defined in line 50; used 2 times
exp2 defined in line 71; used 2 times
exp2a defined in line 93; used 2 times
exp2b defined in line 115; used 2 times
exp2c defined in line 137; used 1 times
exp3 defined in line 172; used 4 times
exp3a defined in line 216; used 3 times
exp4 defined in line 245; used 3 times
exp5 defined in line 280; used 3 times
exp6 defined in line 325; used 4 times
isa defined in line 490; used 6 times

Defined macros

ADDOP defined in line 9; used 2 times
ANYOP defined in line 14; used 2 times
EQEQ defined in line 16; used 1 times
EQOP defined in line 11; used 2 times
GTR defined in line 17; used 2 times
LSS defined in line 18; used 2 times
MULOP defined in line 10; used 2 times
NOTEQ defined in line 19; used 1 times
RELOP defined in line 12; used 2 times
RESTOP defined in line 13; used 3 times
Last modified: 1981-12-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1886
Valid CSS Valid XHTML 1.0 Strict