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 = &paraml;
 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(&paraml);
 500:     t = syntax(paraml.next, &paraml, 0);
 501:     if (err)
 502:         error(err);
 503:     execute(t, -1);
 504:     freelex(&paraml), 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

Defined functions

egetn defined in line 543; used 27 times
etracc defined in line 566; used 13 times
etraci defined in line 555; used 13 times
evalav defined in line 478; used 1 times
exp defined in line 26; used 5 times
exp0 defined in line 33; used 4 times
exp1 defined in line 55; used 2 times
exp2 defined in line 76; used 2 times
exp2a defined in line 98; used 2 times
exp2b defined in line 120; used 2 times
exp2c defined in line 142; used 1 times
exp3 defined in line 187; used 4 times
exp3a defined in line 231; used 3 times
exp4 defined in line 260; used 3 times
exp5 defined in line 295; used 3 times
exp6 defined in line 340; used 4 times
isa defined in line 507; used 6 times

Defined variables

sccsid defined in line 1; never used

Defined macros

ADDOP defined in line 12; used 2 times
ANYOP defined in line 17; used 2 times
EQEQ defined in line 19; used 1 times
EQMATCH defined in line 23; used 2 times
EQOP defined in line 14; used 2 times
GTR defined in line 20; used 2 times
IGNORE defined in line 9; used 8 times
LSS defined in line 21; used 2 times
MULOP defined in line 13; used 2 times
NOGLOB defined in line 10; used 2 times
NOTEQ defined in line 22; used 1 times
NOTEQMATCH defined in line 24; used 2 times
RELOP defined in line 15; used 2 times
RESTOP defined in line 16; used 3 times
Last modified: 1980-10-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1735
Valid CSS Valid XHTML 1.0 Strict