1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/sh.exp.c,v 3.0 1991/07/04 21:49:28 christos Exp $ */
   2: /*
   3:  * sh.exp.c: Expression evaluations
   4:  */
   5: /*-
   6:  * Copyright (c) 1980, 1991 The Regents of the University of California.
   7:  * All rights reserved.
   8:  *
   9:  * Redistribution and use in source and binary forms, with or without
  10:  * modification, are permitted provided that the following conditions
  11:  * are met:
  12:  * 1. Redistributions of source code must retain the above copyright
  13:  *    notice, this list of conditions and the following disclaimer.
  14:  * 2. Redistributions in binary form must reproduce the above copyright
  15:  *    notice, this list of conditions and the following disclaimer in the
  16:  *    documentation and/or other materials provided with the distribution.
  17:  * 3. All advertising materials mentioning features or use of this software
  18:  *    must display the following acknowledgement:
  19:  *	This product includes software developed by the University of
  20:  *	California, Berkeley and its contributors.
  21:  * 4. Neither the name of the University nor the names of its contributors
  22:  *    may be used to endorse or promote products derived from this software
  23:  *    without specific prior written permission.
  24:  *
  25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35:  * SUCH DAMAGE.
  36:  */
  37: #include "config.h"
  38: #if !defined(lint) && !defined(pdp11)
  39: static char *rcsid()
  40:     { return "$Id: sh.exp.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; }
  41: #endif
  42: 
  43: #include "sh.h"
  44: 
  45: /*
  46:  * C shell
  47:  */
  48: 
  49: #define IGNORE  1   /* in ignore, it means to ignore value, just parse */
  50: #define NOGLOB  2   /* in ignore, it means not to globone */
  51: 
  52: #define ADDOP   1
  53: #define MULOP   2
  54: #define EQOP    4
  55: #define RELOP   8
  56: #define RESTOP  16
  57: #define ANYOP   31
  58: 
  59: #define EQEQ    1
  60: #define GTR 2
  61: #define LSS 4
  62: #define NOTEQ   6
  63: #define EQMATCH 7
  64: #define NOTEQMATCH 8
  65: 
  66: static  int  exp1   __P((Char ***, bool));
  67: static  int  exp2   __P((Char ***, bool));
  68: static  int  exp2a  __P((Char ***, bool));
  69: static  int  exp2b  __P((Char ***, bool));
  70: static  int  exp2c  __P((Char ***, bool));
  71: static  Char    *exp3   __P((Char ***, bool));
  72: static  Char    *exp3a  __P((Char ***, bool));
  73: static  Char    *exp4   __P((Char ***, bool));
  74: static  Char    *exp5   __P((Char ***, bool));
  75: static  Char    *exp6   __P((Char ***, bool));
  76: static  void     evalav __P((Char **));
  77: static  int  isa    __P((Char *, int));
  78: static  int  egetn  __P((Char *));
  79: 
  80: #ifdef EDEBUG
  81: static  void     etracc __P((char *, Char *, Char ***));
  82: static  void     etraci __P((char *, int, Char ***));
  83: #endif
  84: 
  85: int
  86: exp(vp)
  87:     register Char ***vp;
  88: {
  89:     return (exp0(vp, 0));
  90: }
  91: 
  92: int
  93: exp0(vp, ignore)
  94:     register Char ***vp;
  95:     bool    ignore;
  96: {
  97:     register int p1 = exp1(vp, ignore);
  98: 
  99: #ifdef EDEBUG
 100:     etraci("exp0 p1", p1, vp);
 101: #endif
 102:     if (**vp && eq(**vp, STRor2)) {
 103:     register int p2;
 104: 
 105:     (*vp)++;
 106:     p2 = exp0(vp, (ignore & IGNORE) || p1);
 107: #ifdef EDEBUG
 108:     etraci("exp0 p2", p2, vp);
 109: #endif
 110:     return (p1 || p2);
 111:     }
 112:     return (p1);
 113: }
 114: 
 115: static int
 116: exp1(vp, ignore)
 117:     register Char ***vp;
 118:     bool    ignore;
 119: {
 120:     register int p1 = exp2(vp, ignore);
 121: 
 122: #ifdef EDEBUG
 123:     etraci("exp1 p1", p1, vp);
 124: #endif
 125:     if (**vp && eq(**vp, STRand2)) {
 126:     register int p2;
 127: 
 128:     (*vp)++;
 129:     p2 = exp1(vp, (ignore & IGNORE) || !p1);
 130: #ifdef EDEBUG
 131:     etraci("exp1 p2", p2, vp);
 132: #endif
 133:     return (p1 && p2);
 134:     }
 135:     return (p1);
 136: }
 137: 
 138: static int
 139: exp2(vp, ignore)
 140:     register Char ***vp;
 141:     bool    ignore;
 142: {
 143:     register int p1 = exp2a(vp, ignore);
 144: 
 145: #ifdef EDEBUG
 146:     etraci("exp3 p1", p1, vp);
 147: #endif
 148:     if (**vp && eq(**vp, STRor)) {
 149:     register int p2;
 150: 
 151:     (*vp)++;
 152:     p2 = exp2(vp, ignore);
 153: #ifdef EDEBUG
 154:     etraci("exp3 p2", p2, vp);
 155: #endif
 156:     return (p1 | p2);
 157:     }
 158:     return (p1);
 159: }
 160: 
 161: static int
 162: exp2a(vp, ignore)
 163:     register Char ***vp;
 164:     bool    ignore;
 165: {
 166:     register int p1 = exp2b(vp, ignore);
 167: 
 168: #ifdef EDEBUG
 169:     etraci("exp2a p1", p1, vp);
 170: #endif
 171:     if (**vp && eq(**vp, STRcaret)) {
 172:     register int p2;
 173: 
 174:     (*vp)++;
 175:     p2 = exp2a(vp, ignore);
 176: #ifdef EDEBUG
 177:     etraci("exp2a p2", p2, vp);
 178: #endif
 179:     return (p1 ^ p2);
 180:     }
 181:     return (p1);
 182: }
 183: 
 184: static int
 185: exp2b(vp, ignore)
 186:     register Char ***vp;
 187:     bool    ignore;
 188: {
 189:     register int p1 = exp2c(vp, ignore);
 190: 
 191: #ifdef EDEBUG
 192:     etraci("exp2b p1", p1, vp);
 193: #endif
 194:     if (**vp && eq(**vp, STRand)) {
 195:     register int p2;
 196: 
 197:     (*vp)++;
 198:     p2 = exp2b(vp, ignore);
 199: #ifdef EDEBUG
 200:     etraci("exp2b p2", p2, vp);
 201: #endif
 202:     return (p1 & p2);
 203:     }
 204:     return (p1);
 205: }
 206: 
 207: static int
 208: exp2c(vp, ignore)
 209:     register Char ***vp;
 210:     bool    ignore;
 211: {
 212:     register Char *p1 = exp3(vp, ignore);
 213:     register Char *p2;
 214:     register int i;
 215: 
 216: #ifdef EDEBUG
 217:     etracc("exp2c p1", p1, vp);
 218: #endif
 219:     if (i = isa(**vp, EQOP)) {
 220:     (*vp)++;
 221:     if (i == EQMATCH || i == NOTEQMATCH)
 222:         ignore |= NOGLOB;
 223:     p2 = exp3(vp, ignore);
 224: #ifdef EDEBUG
 225:     etracc("exp2c p2", p2, vp);
 226: #endif
 227:     if (!(ignore & IGNORE))
 228:         switch (i) {
 229: 
 230:         case EQEQ:
 231:         i = eq(p1, p2);
 232:         break;
 233: 
 234:         case NOTEQ:
 235:         i = !eq(p1, p2);
 236:         break;
 237: 
 238:         case EQMATCH:
 239:         i = Gmatch(p1, p2);
 240:         break;
 241: 
 242:         case NOTEQMATCH:
 243:         i = !Gmatch(p1, p2);
 244:         break;
 245:         }
 246:     xfree((ptr_t) p1);
 247:     xfree((ptr_t) p2);
 248:     return (i);
 249:     }
 250:     i = egetn(p1);
 251:     xfree((ptr_t) p1);
 252:     return (i);
 253: }
 254: 
 255: static Char *
 256: exp3(vp, ignore)
 257:     register Char ***vp;
 258:     bool    ignore;
 259: {
 260:     register Char *p1, *p2;
 261:     register int i;
 262: 
 263:     p1 = exp3a(vp, ignore);
 264: #ifdef EDEBUG
 265:     etracc("exp3 p1", p1, vp);
 266: #endif
 267:     if (i = isa(**vp, RELOP)) {
 268:     (*vp)++;
 269:     if (**vp && eq(**vp, STRequal))
 270:         i |= 1, (*vp)++;
 271:     p2 = exp3(vp, ignore);
 272: #ifdef EDEBUG
 273:     etracc("exp3 p2", p2, vp);
 274: #endif
 275:     if (!(ignore & IGNORE))
 276:         switch (i) {
 277: 
 278:         case GTR:
 279:         i = egetn(p1) > egetn(p2);
 280:         break;
 281: 
 282:         case GTR | 1:
 283:         i = egetn(p1) >= egetn(p2);
 284:         break;
 285: 
 286:         case LSS:
 287:         i = egetn(p1) < egetn(p2);
 288:         break;
 289: 
 290:         case LSS | 1:
 291:         i = egetn(p1) <= egetn(p2);
 292:         break;
 293:         }
 294:     xfree((ptr_t) p1);
 295:     xfree((ptr_t) p2);
 296:     return (putn(i));
 297:     }
 298:     return (p1);
 299: }
 300: 
 301: static Char *
 302: exp3a(vp, ignore)
 303:     register Char ***vp;
 304:     bool    ignore;
 305: {
 306:     register Char *p1, *p2, *op;
 307:     register int i;
 308: 
 309:     p1 = exp4(vp, ignore);
 310: #ifdef EDEBUG
 311:     etracc("exp3a p1", p1, vp);
 312: #endif
 313:     op = **vp;
 314:     if (op && any("<>", op[0]) && op[0] == op[1]) {
 315:     (*vp)++;
 316:     p2 = exp3a(vp, ignore);
 317: #ifdef EDEBUG
 318:     etracc("exp3a p2", p2, vp);
 319: #endif
 320:     if (op[0] == '<')
 321:         i = egetn(p1) << egetn(p2);
 322:     else
 323:         i = egetn(p1) >> egetn(p2);
 324:     xfree((ptr_t) p1);
 325:     xfree((ptr_t) p2);
 326:     return (putn(i));
 327:     }
 328:     return (p1);
 329: }
 330: 
 331: static Char *
 332: exp4(vp, ignore)
 333:     register Char ***vp;
 334:     bool    ignore;
 335: {
 336:     register Char *p1, *p2;
 337:     register int i = 0;
 338: 
 339:     p1 = exp5(vp, ignore);
 340: #ifdef EDEBUG
 341:     etracc("exp4 p1", p1, vp);
 342: #endif
 343:     if (isa(**vp, ADDOP)) {
 344:     register Char *op = *(*vp)++;
 345: 
 346:     p2 = exp4(vp, ignore);
 347: #ifdef EDEBUG
 348:     etracc("exp4 p2", p2, vp);
 349: #endif
 350:     if (!(ignore & IGNORE))
 351:         switch (op[0]) {
 352: 
 353:         case '+':
 354:         i = egetn(p1) + egetn(p2);
 355:         break;
 356: 
 357:         case '-':
 358:         i = egetn(p1) - egetn(p2);
 359:         break;
 360:         }
 361:     xfree((ptr_t) p1);
 362:     xfree((ptr_t) p2);
 363:     return (putn(i));
 364:     }
 365:     return (p1);
 366: }
 367: 
 368: static Char *
 369: exp5(vp, ignore)
 370:     register Char ***vp;
 371:     bool    ignore;
 372: {
 373:     register Char *p1, *p2;
 374:     register int i = 0;
 375: 
 376:     p1 = exp6(vp, ignore);
 377: #ifdef EDEBUG
 378:     etracc("exp5 p1", p1, vp);
 379: #endif
 380:     if (isa(**vp, MULOP)) {
 381:     register Char *op = *(*vp)++;
 382: 
 383:     p2 = exp5(vp, ignore);
 384: #ifdef EDEBUG
 385:     etracc("exp5 p2", p2, vp);
 386: #endif
 387:     if (!(ignore & IGNORE))
 388:         switch (op[0]) {
 389: 
 390:         case '*':
 391:         i = egetn(p1) * egetn(p2);
 392:         break;
 393: 
 394:         case '/':
 395:         i = egetn(p2);
 396:         if (i == 0)
 397:             stderror(ERR_DIV0);
 398:         i = egetn(p1) / i;
 399:         break;
 400: 
 401:         case '%':
 402:         i = egetn(p2);
 403:         if (i == 0)
 404:             stderror(ERR_MOD0);
 405:         i = egetn(p1) % i;
 406:         break;
 407:         }
 408:     xfree((ptr_t) p1);
 409:     xfree((ptr_t) p2);
 410:     return (putn(i));
 411:     }
 412:     return (p1);
 413: }
 414: 
 415: static Char *
 416: exp6(vp, ignore)
 417:     register Char ***vp;
 418:     bool    ignore;
 419: {
 420:     int     ccode, i = 0;
 421:     register Char *cp, *dp, *ep;
 422: 
 423:     if (**vp == 0)
 424:     stderror(ERR_NAME | ERR_EXPRESSION);
 425:     if (eq(**vp, STRbang)) {
 426:     (*vp)++;
 427:     cp = exp6(vp, ignore);
 428: #ifdef EDEBUG
 429:     etracc("exp6 ! cp", cp, vp);
 430: #endif
 431:     i = egetn(cp);
 432:     xfree((ptr_t) cp);
 433:     return (putn(!i));
 434:     }
 435:     if (eq(**vp, STRtilde)) {
 436:     (*vp)++;
 437:     cp = exp6(vp, ignore);
 438: #ifdef EDEBUG
 439:     etracc("exp6 ~ cp", cp, vp);
 440: #endif
 441:     i = egetn(cp);
 442:     xfree((ptr_t) cp);
 443:     return (putn(~i));
 444:     }
 445:     if (eq(**vp, STRLparen)) {
 446:     (*vp)++;
 447:     ccode = exp0(vp, ignore);
 448: #ifdef EDEBUG
 449:     etraci("exp6 () ccode", ccode, vp);
 450: #endif
 451:     if (*vp == 0 || **vp == 0 || ***vp != ')')
 452:         stderror(ERR_NAME | ERR_EXPRESSION);
 453:     (*vp)++;
 454:     return (putn(ccode));
 455:     }
 456:     if (eq(**vp, STRLbrace)) {
 457:     register Char **v;
 458:     struct command faket;
 459:     Char   *fakecom[2];
 460: 
 461:     faket.t_dtyp = NODE_COMMAND;
 462:     faket.t_dflg = 0;
 463:     faket.t_dcar = faket.t_dcdr = faket.t_dspr = NULL;
 464:     faket.t_dcom = fakecom;
 465:     fakecom[0] = STRfkcom;
 466:     fakecom[1] = NOSTR;
 467:     (*vp)++;
 468:     v = *vp;
 469:     for (;;) {
 470:         if (!**vp)
 471:         stderror(ERR_NAME | ERR_MISSING, '}');
 472:         if (eq(*(*vp)++, STRRbrace))
 473:         break;
 474:     }
 475:     if (ignore & IGNORE)
 476:         return (Strsave(STRNULL));
 477:     psavejob();
 478:     if (pfork(&faket, -1) == 0) {
 479:         *--(*vp) = 0;
 480:         evalav(v);
 481:         exitstat();
 482:     }
 483:     pwait();
 484:     prestjob();
 485: #ifdef EDEBUG
 486:     etraci("exp6 {} status", egetn(value(STRstatus)), vp);
 487: #endif
 488:     return (putn(egetn(value(STRstatus)) == 0));
 489:     }
 490:     if (isa(**vp, ANYOP))
 491:     return (Strsave(STRNULL));
 492:     cp = *(*vp)++;
 493:     if (*cp == '-' && any("erwxfdzopls", cp[1])) {
 494:     struct stat stb;
 495: 
 496:     if (cp[2] != '\0')
 497:         stderror(ERR_NAME | ERR_FILEINQ);
 498:     /*
 499: 	 * Detect missing file names by checking for operator in the file name
 500: 	 * position.  However, if an operator name appears there, we must make
 501: 	 * sure that there's no file by that name (e.g., "/") before announcing
 502: 	 * an error.  Even this check isn't quite right, since it doesn't take
 503: 	 * globbing into account.
 504: 	 */
 505:     if (isa(**vp, ANYOP) && stat(short2str(**vp), &stb))
 506:         stderror(ERR_NAME | ERR_FILENAME);
 507: 
 508:     dp = *(*vp)++;
 509:     if (ignore & IGNORE)
 510:         return (Strsave(STRNULL));
 511:     ep = globone(dp, G_ERROR);
 512:     switch (cp[1]) {
 513: 
 514:     case 'r':
 515:         i = !access(short2str(ep), R_OK);
 516:         break;
 517: 
 518:     case 'w':
 519:         i = !access(short2str(ep), W_OK);
 520:         break;
 521: 
 522:     case 'x':
 523:         i = !access(short2str(ep), X_OK);
 524:         break;
 525: 
 526:     default:
 527:         if (
 528: #ifdef S_IFLNK
 529:         cp[1] == 'l' ? lstat(short2str(ep), &stb) :
 530: #endif
 531:         stat(short2str(ep), &stb)) {
 532:         xfree((ptr_t) ep);
 533:         return (Strsave(STR0));
 534:         }
 535:         switch (cp[1]) {
 536: 
 537:         case 'f':
 538:         i = S_ISREG(stb.st_mode);
 539:         break;
 540: 
 541:         case 'd':
 542:         i = S_ISDIR(stb.st_mode);
 543:         break;
 544: 
 545:         case 'p':
 546: #ifdef S_ISFIFO
 547:         i = S_ISFIFO(stb.st_mode);
 548: #else
 549:         i = 0;
 550: #endif
 551:         break;
 552: 
 553:         case 'l':
 554: #ifdef S_ISLNK
 555:         i = S_ISLNK(stb.st_mode);
 556: #else
 557:         i = 0;
 558: #endif
 559:         break;
 560: 
 561:         case 's':
 562: #ifdef S_ISSOCK
 563:         i = S_ISSOCK(stb.st_mode);
 564: #else
 565:         i = 0;
 566: #endif
 567:         break;
 568: 
 569:         case 'z':
 570:         i = stb.st_size == 0;
 571:         break;
 572: 
 573:         case 'e':
 574:         i = 1;
 575:         break;
 576: 
 577:         case 'o':
 578:         i = stb.st_uid == uid;
 579:         break;
 580:         }
 581:     }
 582: #ifdef EDEBUG
 583:     etraci("exp6 -? i", i, vp);
 584: #endif
 585:     xfree((ptr_t) ep);
 586:     return (putn(i));
 587:     }
 588: #ifdef EDEBUG
 589:     etracc("exp6 default", cp, vp);
 590: #endif
 591:     return (ignore & NOGLOB ? Strsave(cp) : globone(cp, G_ERROR));
 592: }
 593: 
 594: static void
 595: evalav(v)
 596:     register Char **v;
 597: {
 598:     struct wordent paraml1;
 599:     register struct wordent *hp = &paraml1;
 600:     struct command *t;
 601:     register struct wordent *wdp = hp;
 602: 
 603:     set(STRstatus, Strsave(STR0));
 604:     hp->prev = hp->next = hp;
 605:     hp->word = STRNULL;
 606:     while (*v) {
 607:     register struct wordent *new =
 608:     (struct wordent *) xcalloc(1, sizeof *wdp);
 609: 
 610:     new->prev = wdp;
 611:     new->next = hp;
 612:     wdp->next = new;
 613:     wdp = new;
 614:     wdp->word = Strsave(*v++);
 615:     }
 616:     hp->prev = wdp;
 617:     alias(&paraml1);
 618:     t = syntax(paraml1.next, &paraml1, 0);
 619:     if (seterr)
 620:     stderror(ERR_OLD);
 621:     execute(t, -1, NULL, NULL);
 622:     freelex(&paraml1), freesyn(t);
 623: }
 624: 
 625: static int
 626: isa(cp, what)
 627:     register Char *cp;
 628:     register int what;
 629: {
 630:     if (cp == 0)
 631:     return ((what & RESTOP) != 0);
 632:     if (cp[1] == 0) {
 633:     if (what & ADDOP && (*cp == '+' || *cp == '-'))
 634:         return (1);
 635:     if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
 636:         return (1);
 637:     if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
 638:                   *cp == '~' || *cp == '^' || *cp == '"'))
 639:         return (1);
 640:     }
 641:     else if (cp[2] == 0) {
 642:     if (what & RESTOP) {
 643:         if (cp[0] == '|' && cp[1] == '&')
 644:         return (1);
 645:         if (cp[0] == '<' && cp[1] == '<')
 646:         return (1);
 647:         if (cp[0] == '>' && cp[1] == '>')
 648:         return (1);
 649:     }
 650:     if (what & EQOP) {
 651:         if (cp[0] == '=') {
 652:         if (cp[1] == '=')
 653:             return (EQEQ);
 654:         if (cp[1] == '~')
 655:             return (EQMATCH);
 656:         }
 657:         else if (cp[0] == '!') {
 658:         if (cp[1] == '=')
 659:             return (NOTEQ);
 660:         if (cp[1] == '~')
 661:             return (NOTEQMATCH);
 662:         }
 663:     }
 664:     }
 665:     if (what & RELOP) {
 666:     if (*cp == '<')
 667:         return (LSS);
 668:     if (*cp == '>')
 669:         return (GTR);
 670:     }
 671:     return (0);
 672: }
 673: 
 674: static int
 675: egetn(cp)
 676:     register Char *cp;
 677: {
 678:     if (*cp && *cp != '-' && !Isdigit(*cp))
 679:     stderror(ERR_NAME | ERR_EXPRESSION);
 680:     return (getn(cp));
 681: }
 682: 
 683: /* Phew! */
 684: 
 685: #ifdef EDEBUG
 686: static void
 687: etraci(str, i, vp)
 688:     char   *str;
 689:     int     i;
 690:     Char ***vp;
 691: {
 692:     xprintf("%s=%d\t", str, i);
 693:     blkpr(*vp);
 694:     xprintf("\n");
 695: }
 696: static void
 697: etracc(str, cp, vp)
 698:     char   *str;
 699:     Char   *cp;
 700:     Char ***vp;
 701: {
 702:     xprintf("%s=%s\t", str, cp);
 703:     blkpr(*vp);
 704:     xprintf("\n");
 705: }
 706: #endif

Defined functions

egetn defined in line 674; used 27 times
etracc defined in line 696; used 13 times
etraci defined in line 686; used 13 times
evalav defined in line 594; used 1 times
exp defined in line 85; used 5 times
exp0 defined in line 92; used 7 times
exp1 defined in line 115; used 2 times
exp2 defined in line 138; used 2 times
exp2a defined in line 161; used 2 times
exp2b defined in line 184; used 2 times
exp2c defined in line 207; used 1 times
exp3 defined in line 255; used 3 times
exp3a defined in line 301; used 2 times
exp4 defined in line 331; used 2 times
exp5 defined in line 368; used 2 times
exp6 defined in line 415; used 3 times
isa defined in line 625; used 6 times
rcsid defined in line 39; never used

Defined macros

ADDOP defined in line 52; used 2 times
ANYOP defined in line 57; used 2 times
EQEQ defined in line 59; used 1 times
EQMATCH defined in line 63; used 2 times
EQOP defined in line 54; used 2 times
GTR defined in line 60; used 2 times
IGNORE defined in line 49; used 8 times
LSS defined in line 61; used 2 times
MULOP defined in line 53; used 2 times
NOGLOB defined in line 50; used 2 times
NOTEQ defined in line 62; used 1 times
NOTEQMATCH defined in line 64; used 2 times
RELOP defined in line 55; used 2 times
RESTOP defined in line 56; used 3 times
Last modified: 1991-08-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3893
Valid CSS Valid XHTML 1.0 Strict