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 = &paraml;
 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(&paraml);
 510:     t = syntax(paraml.next, &paraml, 0);
 511:     if (err)
 512:         error(err);
 513:     execute(t, -1);
 514:     freelex(&paraml), 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

Defined functions

egetn defined in line 564; used 27 times
etracc defined in line 587; used 13 times
etraci defined in line 576; used 13 times
evalav defined in line 488; used 1 times
exp defined in line 34; used 5 times
exp0 defined in line 41; used 4 times
exp1 defined in line 63; used 2 times
exp2 defined in line 84; used 2 times
exp2a defined in line 106; used 2 times
exp2b defined in line 128; used 2 times
exp2c defined in line 150; used 1 times
exp3 defined in line 195; used 4 times
exp3a defined in line 239; used 3 times
exp4 defined in line 268; used 3 times
exp5 defined in line 303; used 3 times
exp6 defined in line 348; used 4 times
isa defined in line 517; used 6 times

Defined variables

sccsid defined in line 8; never used

Defined macros

ADDOP defined in line 20; used 2 times
ANYOP defined in line 25; used 2 times
EQEQ defined in line 27; used 1 times
EQMATCH defined in line 31; used 2 times
EQOP defined in line 22; used 2 times
GTR defined in line 28; used 2 times
IGNORE defined in line 17; used 8 times
LSS defined in line 29; used 2 times
MULOP defined in line 21; used 2 times
NOGLOB defined in line 18; used 2 times
NOTEQ defined in line 30; used 1 times
NOTEQMATCH defined in line 32; used 2 times
RELOP defined in line 23; used 2 times
RESTOP defined in line 24; used 3 times
Last modified: 1985-06-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1737
Valid CSS Valid XHTML 1.0 Strict