1: #include <stdio.h>
   2: #include <signal.h>
   3: 
   4: #define ERROR NULL
   5: #define READ    "r"
   6: #define WRITE   "w"
   7: 
   8: #define EOS 0
   9: int lpar    = '(';
  10: #define LPAR    lpar
  11: #define RPAR    ')'
  12: #define COMMA   ','
  13: #define GRAVE   '`'
  14: #define ACUTE   '\''
  15: #define LBRAK   '['
  16: #define RBRAK   ']'
  17: #ifdef  M4
  18: char    lquote  LBRAK;
  19: char    rquote  RBRAK;
  20: #endif
  21: #ifndef M4
  22: char    lquote  = GRAVE;
  23: char    rquote  = ACUTE;
  24: #endif
  25: #define COMMENT '#'
  26: #define ALPH    1
  27: #define DIG 2
  28: 
  29: #define HSHSIZ  199 /* prime */
  30: #define STACKS  50
  31: #define SAVS    4096
  32: #define TOKS    128
  33: 
  34: #define putbak(c)   *ip++ = c;
  35: #define getchr()    (ip>cur_ip?*--ip: getc(infile[infptr]))
  36: #define putchr(c)   if (cp==NULL) {if (curfile)putc(c,curfile);} else *op++ = c
  37: char    type[] = {
  38:     0,  0,  0,  0,  0,  0,  0,  0,
  39:     0,  0,  0,  0,  0,  0,  0,  0,
  40:     0,  0,  0,  0,  0,  0,  0,  0,
  41:     0,  0,  0,  0,  0,  0,  0,  0,
  42:     0,  0,  0,  0,  0,  0,  0,  0,
  43:     0,  0,  0,  0,  0,  0,  0,  0,
  44:     DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,
  45:     DIG,    DIG,    0,  0,  0,  0,  0,  0,
  46:     0,  ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
  47:     ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
  48:     ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
  49:     ALPH,   ALPH,   ALPH,   0,  0,  0,  0,  ALPH,
  50:     0,  ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
  51:     ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
  52:     ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
  53:     ALPH,   ALPH,   ALPH,   0,  0,  0,  0,  0,
  54: };
  55: 
  56: char    token[TOKS];
  57: char    eoa[]   = "\0";
  58: struct  nlist {
  59:     char    *name;
  60:     char    *def;
  61:     struct  nlist *next;
  62: };
  63: 
  64: struct  nlist   *hshtab[HSHSIZ];
  65: char    ibuf[SAVS+TOKS];
  66: char    obuf[SAVS+TOKS];
  67: char    *op = obuf;
  68: char    *ip = ibuf;
  69: char *ip_stk[10] = {ibuf};
  70: char *cur_ip = ibuf;
  71: struct call {
  72:     char    **argp;
  73:     int plev;
  74: };
  75: struct  call    *cp = NULL;
  76: 
  77: char    *makeloc;
  78: char    *ifdefloc;
  79: char    *lenloc;
  80: char    *undefloc;
  81: char    *shiftloc;
  82: char    *cqloc;
  83: char    *defloc;
  84: char    *evaloc;
  85: char    *incrloc;
  86: char    *substrloc;
  87: char    *indexloc;
  88: char    *transloc;
  89: char    *ifloc;
  90: char    *divloc;
  91: char    *divnumloc;
  92: char    *undivloc;
  93: char    *dnlloc;
  94: char    *inclloc;
  95: char    *sinclloc;
  96: char    *syscmdloc;
  97: char    *dumploc;
  98: char    *errploc;
  99: 
 100: char    *tempname;
 101: struct nlist    *lookup();
 102: char    *install();
 103: char    *malloc();
 104: char    *mktemp();
 105: char    *copy();
 106: long    ctol();
 107: int hshval;
 108: FILE    *olist[11] = { stdout };
 109: int okret;
 110: int curout  = 0;
 111: FILE    *curfile = { stdout };
 112: FILE    *infile[10] = { stdin };
 113: int infptr  = 0;
 114: 
 115: main(argc, argv)
 116: char **argv;
 117: {
 118:     char *argstk[STACKS+10];
 119:     struct call callst[STACKS];
 120:     register char *tp, **ap;
 121:     int delexit(), catchsig();
 122:     register t;
 123:     int i;
 124: 
 125: #ifdef gcos
 126: #ifdef M4
 127:     install("GCOS", eoa);
 128: #endif
 129: #ifndef M4
 130:     install("gcos", eoa);
 131: #endif
 132: #endif
 133: #ifdef unix
 134: #ifdef M4
 135:     install("UNIX", eoa);
 136: #endif
 137: #ifndef M4
 138:     install("unix", eoa);
 139: #endif
 140: #endif
 141: 
 142: #ifdef M4
 143:     makeloc = install("MAKETEMP", eoa);
 144:     ifdefloc = install("IFDEF", eoa);
 145:     lenloc = install("LEN", eoa);
 146:     undefloc = install("UNDEFINE", eoa);
 147:     shiftloc = install("SHIFT", eoa);
 148:     cqloc = install("CHANGEQUOTE", eoa);
 149:     defloc = install("DEFINE", eoa);
 150:     evaloc = install("EVAL", eoa);
 151:     inclloc = install("INCLUDE", eoa);
 152:     sinclloc = install("SINCLUDE", eoa);
 153:     syscmdloc = install("SYSCMD", eoa);
 154:     dumploc = install("DUMPDEF", eoa);
 155:     errploc = install("ERRPRINT", eoa);
 156:     incrloc = install("INCR", eoa);
 157:     substrloc = install("SUBSTR", eoa);
 158:     indexloc = install("INDEX", eoa);
 159:     transloc = install("TRANSLIT", eoa);
 160:     ifloc = install("IFELSE", eoa);
 161:     divloc = install("DIVERT", eoa);
 162:     divnumloc = install("DIVNUM", eoa);
 163:     undivloc = install("UNDIVERT", eoa);
 164:     dnlloc = install("DNL", eoa);
 165: #endif
 166: 
 167: #ifndef M4
 168:     makeloc = install("maketemp", eoa);
 169:     ifdefloc = install("ifdef", eoa);
 170:     lenloc = install("len", eoa);
 171:     undefloc = install("undefine", eoa);
 172:     shiftloc = install("shift", eoa);
 173:     cqloc = install("changequote", eoa);
 174:     defloc = install("define", eoa);
 175:     evaloc = install("eval", eoa);
 176:     inclloc = install("include", eoa);
 177:     sinclloc = install("sinclude", eoa);
 178:     syscmdloc = install("syscmd", eoa);
 179:     dumploc = install("dumpdef", eoa);
 180:     errploc = install("errprint", eoa);
 181:     incrloc = install("incr", eoa);
 182:     substrloc = install("substr", eoa);
 183:     indexloc = install("index", eoa);
 184:     transloc = install("translit", eoa);
 185:     ifloc = install("ifelse", eoa);
 186:     divloc = install("divert", eoa);
 187:     divnumloc = install("divnum", eoa);
 188:     undivloc = install("undivert", eoa);
 189:     dnlloc = install("dnl", eoa);
 190: #endif
 191:     ap = argstk;
 192: #ifndef gcos
 193:     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
 194:         signal(SIGHUP, catchsig);
 195:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
 196:         signal(SIGINT, catchsig);
 197:     tempname = mktemp("/tmp/m4aXXXXX");
 198:     close(creat(tempname, 0));
 199: #endif
 200: #ifdef gcos
 201:     tempname = "m4.tempa";
 202: #endif
 203:     if (argc>1)
 204:         putbak(0);
 205:     for (;;) {
 206:         tp = token;
 207:         *tp++ = t = getchr();
 208:         *tp = EOS;
 209:         if (t<=0) {
 210:             if (infptr > 0) {
 211:                 fclose(infile[infptr]);
 212:                 infptr--;
 213:                 cur_ip = ip_stk[infptr];
 214:                 continue;
 215:             }
 216:             if (argc<=1)
 217:                 break;
 218:             argc--;
 219:             argv++;
 220:             if (infile[infptr]!=stdin)
 221:                 fclose(infile[infptr]);
 222:             if (**argv=='-')
 223:                 infile[infptr] = stdin;
 224:             else if ((infile[infptr]=fopen(argv[0], READ))==ERROR) {
 225:                 fprintf(stderr, "m4: file not found: %s\n", argv[0]);
 226:                 delexit();
 227:             }
 228:             continue;
 229:         }
 230:         if (type[t]==ALPH) {
 231:             while ((t=type[*tp++=getchr()])==ALPH||t==DIG);
 232:             putbak(*--tp);
 233:             *tp = EOS;
 234:             if (*ap = lookup(token)->def) {
 235:                 if (++ap >= &argstk[STACKS]) {
 236:                     fprintf(stderr, "m4: arg stack overflow\n");
 237:                     delexit();
 238:                 }
 239:                 if (cp==NULL)
 240:                     cp = callst;
 241:                 else if (++cp > &callst[STACKS]) {
 242:                     fprintf(stderr, "m4: call stack overflow\n");
 243:                     delexit();
 244:                 }
 245:                 cp->argp = ap;
 246:                 *ap++ = op;
 247:                 puttok();
 248:                 *op++ = '\0';
 249:                 t = getchr();
 250:                 putbak(t);
 251:                 if (t!=LPAR) {
 252:                     /* if (t!=' ' && t!='\t') */
 253:                         putbak(')');
 254:                     putbak('(');
 255:                 }
 256:                 else    /* try to fix arg count */
 257:                     *ap++ = op;
 258:                 cp->plev = 0;
 259:             } else
 260:                 puttok();
 261:         } else if (t==lquote) {
 262:             i = 1;
 263:             for (;;) {
 264:                 t = getchr();
 265:                 if (t==rquote) {
 266:                     i--;
 267:                     if (i==0)
 268:                         break;
 269:                 } else if (t==lquote)
 270:                     i++;
 271:                 else if (t<0) {
 272:                     fprintf(stderr, "m4: EOF in string\n");
 273:                     delexit();
 274:                 }
 275:                 putchr(t);
 276:             }
 277:         } else if (t==COMMENT) {
 278:             putbak(t);
 279:             while ((t = getchr())!='\n'&& t>=0)
 280:                 if (cp==NULL)
 281:                     putchr(t);
 282:             putbak(t);
 283:         } else if (cp==NULL) {
 284:             puttok();
 285:         } else if (t==LPAR) {
 286:             if (cp->plev)
 287:                 *op++ = t;
 288:             cp->plev++;
 289:             while ( (t=getchr())==' ' || t=='\t' || t=='\n')
 290:                 ;   /* skip leading white space during arg collection */
 291:             putbak(t);
 292: /*
 293: 		} else if (t==' ' || t=='\t' || t=='\n') {
 294: 			continue;
 295: */
 296:         } else if (t==RPAR) {
 297:             cp->plev--;
 298:             if (cp->plev==0) {
 299:                 *op++ = '\0';
 300:                 expand(cp->argp, ap-cp->argp-1);
 301:                 op = *cp->argp;
 302:                 ap = cp->argp-1;
 303:                 cp--;
 304:                 if (cp < callst)
 305:                     cp = NULL;
 306:             } else
 307:                 *op++ = t;
 308:         } else if (t==COMMA && cp->plev<=1) {
 309:             *op++ = '\0';
 310:             *ap++ = op;
 311:             while ((t=getchr())==' ' || t=='\t' || t=='\n')
 312:                 ;   /* skip leading white space during arg collection */
 313:             putbak(t);
 314:         } else
 315:             *op++ = t;
 316:     }
 317:     if (cp!=NULL) {
 318:         fprintf(stderr, "m4: unexpected EOF\n");
 319:         delexit();
 320:     }
 321:     okret = 1;
 322:     delexit();
 323: }
 324: 
 325: catchsig()
 326: {
 327:     okret = 0;
 328:     delexit();
 329: }
 330: 
 331: delexit()
 332: {
 333:     register FILE *fp;
 334:     register i, c;
 335: 
 336:     if (!okret) {
 337:         signal(SIGHUP, SIG_IGN);
 338:         signal(SIGINT, SIG_IGN);
 339:     }
 340:     for (i=1; i<10; i++) {
 341:         if (olist[i]==NULL)
 342:             continue;
 343:         fclose(olist[i]);
 344:         tempname[7] = 'a'+i;
 345:         if (okret) {
 346:             fp = fopen(tempname, READ);
 347:             while ((c = getc(fp)) > 0)
 348:                 putchar(c);
 349:             fclose(fp);
 350:         }
 351:         unlink(tempname);
 352:     }
 353:     tempname[7] = 'a';
 354:     unlink(tempname);
 355:     exit(1-okret);
 356: }
 357: 
 358: puttok()
 359: {
 360:     register char *tp;
 361: 
 362:     tp = token;
 363:     if (cp) {
 364:         if (op >= &obuf[SAVS]) {
 365:             fprintf(stderr, "m4: argument overflow\n");
 366:             delexit();
 367:         }
 368:         while (*tp)
 369:             *op++ = *tp++;
 370:     } else if (curfile)
 371:         while (*tp)
 372:             putc(*tp++, curfile);
 373: }
 374: 
 375: pbstr(str)
 376: register char *str;
 377: {
 378:     register char *p;
 379: 
 380:     p = str;
 381:     while (*p++);
 382:     --p;
 383:     if (ip >= &ibuf[SAVS]) {
 384:         fprintf(stderr, "m4: pushback overflow\n");
 385:         delexit();
 386:     }
 387:     while (p > str)
 388:         putbak(*--p);
 389: }
 390: 
 391: expand(a1, c)
 392: register char **a1;
 393: {
 394:     register char *dp;
 395:     register n;
 396: 
 397:     dp = a1[-1];
 398:     if (dp==defloc)
 399:         dodef(a1, c);
 400:     else if (dp==evaloc)
 401:         doeval(a1, c);
 402:     else if (dp==inclloc)
 403:         doincl(a1, c, 1);
 404:     else if (dp==sinclloc)
 405:         doincl(a1, c, 0);
 406:     else if (dp==makeloc)
 407:         domake(a1, c);
 408:     else if (dp==syscmdloc)
 409:         dosyscmd(a1, c);
 410:     else if (dp==incrloc)
 411:         doincr(a1, c);
 412:     else if (dp==substrloc)
 413:         dosubstr(a1, c);
 414:     else if (dp==indexloc)
 415:         doindex(a1, c);
 416:     else if (dp==transloc)
 417:         dotransl(a1, c);
 418:     else if (dp==ifloc)
 419:         doif(a1, c);
 420:     else if (dp==divloc)
 421:         dodiv(a1, c);
 422:     else if (dp==divnumloc)
 423:         dodivnum(a1, c);
 424:     else if (dp==undivloc)
 425:         doundiv(a1, c);
 426:     else if (dp==dnlloc)
 427:         dodnl(a1, c);
 428:     else if (dp==dumploc)
 429:         dodump(a1, c);
 430:     else if (dp==errploc)
 431:         doerrp(a1, c);
 432:     else if (dp==lenloc)
 433:         dolen(a1, c);
 434:     else if (dp==ifdefloc)
 435:         doifdef(a1, c);
 436:     else if (dp==undefloc)
 437:         doundef(a1, c);
 438:     else if (dp==shiftloc)
 439:         doshift(a1, c);
 440:     else if (dp==cqloc)
 441:         docq(a1, c);
 442:     else {
 443:         while (*dp++);
 444:         for (dp--; dp>a1[-1]; ) {
 445:             if (--dp>a1[-1] && dp[-1]=='$') {
 446:                 n = *dp-'0';
 447:                 if (n>=0 && n<=9) {
 448:                     if (n <= c)
 449:                         pbstr(a1[n]);
 450:                     dp--;
 451:                 } else
 452:                     putbak(*dp);
 453:             } else
 454:                 putbak(*dp);
 455:         }
 456:     }
 457: }
 458: 
 459: struct nlist *lookup(str)
 460: char *str;
 461: {
 462:     register char *s1, *s2;
 463:     register struct nlist *np;
 464:     static struct nlist nodef;
 465: 
 466:     s1 = str;
 467:     for (hshval = 0; *s1; )
 468:         hshval += *s1++;
 469:     hshval %= HSHSIZ;
 470:     for (np = hshtab[hshval]; np!=NULL; np = np->next) {
 471:         s1 = str;
 472:         s2 = np->name;
 473:         while (*s1++ == *s2)
 474:             if (*s2++ == EOS)
 475:                 return(np);
 476:     }
 477:     return(&nodef);
 478: }
 479: 
 480: char *install(nam, val)
 481: char *nam, *val;
 482: {
 483:     register struct nlist *np;
 484: 
 485:     if ((np = lookup(nam))->name == NULL) {
 486:         np = (struct nlist *)malloc(sizeof(*np));
 487:         if (np == NULL) {
 488:             fprintf(stderr, "m4: no space for alloc\n");
 489:             exit(1);
 490:         }
 491:         np->name = copy(nam);
 492:         np->def = copy(val);
 493:         np->next = hshtab[hshval];
 494:         hshtab[hshval] = np;
 495:         return(np->def);
 496:     }
 497:     free(np->def);
 498:     np->def = copy(val);
 499:     return(np->def);
 500: }
 501: 
 502: doundef(ap, c)
 503: char **ap;
 504: {
 505:     register struct nlist *np, *tnp;
 506: 
 507:     if (c < 1 || (np = lookup(ap[1]))->name == NULL)
 508:         return;
 509:     tnp = hshtab[hshval];   /* lookup sets hshval */
 510:     if (tnp == np)  /* it's in first place */
 511:         hshtab[hshval] = np->next;
 512:     else {
 513:         for ( ; tnp->next != np; tnp = tnp->next)
 514:             ;
 515:         tnp->next = np->next;
 516:     }
 517:     free(np->name);
 518:     free(np->def);
 519:     free((char *)np);
 520: }
 521: 
 522: char *copy(s)
 523: register char *s;
 524: {
 525:     register char *p, *s1;
 526: 
 527:     p = s1 = malloc((unsigned)strlen(s)+1);
 528:     if (p == NULL) {
 529:         fprintf(stderr, "m4: no space for alloc\n");
 530:         exit(1);
 531:     }
 532:     while (*s1++ = *s++);
 533:     return(p);
 534: }
 535: 
 536: dodef(ap, c)
 537: char **ap;
 538: {
 539:     if (c >= 2) {
 540:         if (strcmp(ap[1], ap[2]) == 0) {
 541:             fprintf(stderr, "m4: %s defined as itself\n", ap[1]);
 542:             delexit();
 543:         }
 544:         install(ap[1], ap[2]);
 545:     }
 546:     else if (c == 1)
 547:         install(ap[1], "");
 548: }
 549: 
 550: doifdef(ap, c)
 551: char **ap;
 552: {
 553:     register struct nlist *np;
 554: 
 555:     if (c < 2)
 556:         return;
 557:     if (lookup(ap[1])->name != NULL)
 558:         pbstr(ap[2]);
 559:     else if (c >= 3)
 560:         pbstr(ap[3]);
 561: }
 562: 
 563: dolen(ap, c)
 564: char **ap;
 565: {
 566:     putnum((long) strlen(ap[1]));
 567: }
 568: 
 569: docq(ap, c)
 570: char **ap;
 571: {
 572:     if (c > 1) {
 573:         lquote = *ap[1];
 574:         rquote = *ap[2];
 575:     } else if (c == 1) {
 576:         lquote = rquote = *ap[1];
 577:     } else {
 578: #ifndef M4
 579:         lquote = GRAVE;
 580:         rquote = ACUTE;
 581: #endif
 582: #ifdef M4
 583:         lquote = LBRAK;
 584:         rquote = RBRAK;
 585: #endif
 586:     }
 587: }
 588: 
 589: doshift(ap, c)
 590: char **ap;
 591: {
 592:     fprintf(stderr, "m4: shift not yet implemented\n");
 593: }
 594: 
 595: dodump(ap, c)
 596: char **ap;
 597: {
 598:     int i;
 599:     register struct nlist *np;
 600: 
 601:     if (c > 0)
 602:         while (c--) {
 603:             if ((np = lookup(*++ap))->name != NULL)
 604:                 fprintf(stderr, "`%s'	`%s'\n", np->name, np->def);
 605:         }
 606:     else
 607:         for (i=0; i<HSHSIZ; i++)
 608:             for (np=hshtab[i]; np!=NULL; np=np->next)
 609:                 fprintf(stderr, "`%s'	`%s'\n", np->name, np->def);
 610: }
 611: 
 612: doerrp(ap, c)
 613: char **ap;
 614: {
 615:     if (c > 0) {
 616:         fprintf(stderr, ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]);
 617:         fprintf(stderr, "\n");
 618:     }
 619: }
 620: 
 621: 
 622: long    evalval;    /* return value from yacc stuff */
 623: char    *pe;    /* used by grammar */
 624: 
 625: doeval(ap, c)
 626: char **ap;
 627: {
 628: 
 629:     if (c > 0) {
 630:         pe = ap[1];
 631:         if (yyparse() == 0)
 632:             putnum(evalval);
 633:         else
 634:             fprintf(stderr, "m4: invalid expression in eval: %s\n", ap[1]);
 635:     }
 636: }
 637: 
 638: doincl(ap, c, noisy)
 639: char **ap;
 640: {
 641:     if (c > 0 && strlen(ap[1]) > 0) {
 642:         infptr++;
 643:         ip_stk[infptr] = cur_ip = ip;
 644:         if ((infile[infptr] = fopen(ap[1], READ))==ERROR) {
 645:             if (noisy) {
 646:                 fprintf(stderr, "m4: file not found: %s\n", ap[1]);
 647:                 delexit();
 648:             }
 649:             else
 650:                 infptr--;
 651:         }
 652:     }
 653: }
 654: 
 655: dosyscmd(ap, c)
 656: char **ap;
 657: {
 658:     if (c > 0)
 659:         system(ap[1]);
 660: }
 661: 
 662: domake(ap, c)
 663: char **ap;
 664: {
 665:     if (c > 0)
 666:         pbstr(mktemp(ap[1]));
 667: }
 668: 
 669: doincr(ap, c)
 670: char **ap;
 671: {
 672:     if (c >= 1)
 673:         putnum(ctol(ap[1])+1);
 674: }
 675: 
 676: putnum(num)
 677: long num;
 678: {
 679:     register sign;
 680: 
 681:     sign = (num < 0) ? '-' : '\0';
 682:     if (num < 0)
 683:         num = -num;
 684:     do {
 685:         putbak(num%10+'0');
 686:         num = num/10;
 687:     } while (num!=0);
 688:     if (sign == '-')
 689:         putbak('-');
 690: }
 691: 
 692: dosubstr(ap, c)
 693: char **ap;
 694: {
 695:     int nc;
 696:     register char *sp, *fc;
 697: 
 698:     if (c<2)
 699:         return;
 700:     if (c<3)
 701:         nc = TOKS;
 702:     else
 703:         nc = ctoi(ap[3]);
 704:     fc = ap[1] + max(0, min(ctoi(ap[2]), strlen(ap[1])));
 705:     sp = fc + min(nc, strlen(fc));
 706:     while (sp > fc)
 707:         putbak(*--sp);
 708: }
 709: 
 710: doindex(ap, c)
 711: char **ap;
 712: {
 713:     if (c >= 2)
 714:         putnum((long) strindex(ap[1], ap[2]));
 715: }
 716: 
 717: strindex(p1, p2)
 718: char *p1, *p2;
 719: {
 720:     register m;
 721:     register char *s, *t, *p;
 722: 
 723:     for (p=p1; *p; p++) {
 724:         s = p;
 725:         m = 1;
 726:         for (t=p2; *t; )
 727:             if (*t++ != *s++)
 728:                 m = 0;
 729:         if (m == 1)
 730:             return(p-p1);
 731:     }
 732:     return(-1);
 733: }
 734: 
 735: dotransl(ap, c)
 736: char **ap;
 737: {
 738:     register char *s, *fr, *to;
 739: 
 740:     if (c <= 1) return;
 741: 
 742:     if (c == 2) {
 743:         register int i;
 744:         to = ap[1];
 745:         for (s = ap[1]; *s; s++) {
 746:             i = 0;
 747:             for (fr = ap[2]; *fr; fr++)
 748:                 if (*s == *fr) {
 749:                     i++;
 750:                     break;
 751:                 }
 752:             if (i == 0)
 753:                 *to++ = *s;
 754:         }
 755:         *to = '\0';
 756:     }
 757: 
 758:     if (c >= 3) {
 759:         for (s = ap[1]; *s; s++)
 760:             for (fr = ap[2], to = ap[3]; *fr && *to; fr++, to++)
 761:                 if (*s == *fr)
 762:                     *s = *to;
 763:     }
 764: 
 765:     pbstr(ap[1]);
 766: }
 767: 
 768: doif(ap, c)
 769: register char **ap;
 770: {
 771:     if (c < 3)
 772:         return;
 773:     while (c >= 3) {
 774:         if (strcmp(ap[1], ap[2]) == 0) {
 775:             pbstr(ap[3]);
 776:             return;
 777:         }
 778:         c -= 3;
 779:         ap += 3;
 780:     }
 781:     if (c > 0)
 782:         pbstr(ap[1]);
 783: }
 784: 
 785: dodiv(ap, c)
 786: register char **ap;
 787: {
 788:     register int f;
 789: 
 790:     if (c<1)
 791:         f = 0;
 792:     else
 793:         f = ctoi(ap[1]);
 794:     if (f>=10 || f<0) {
 795:         curfile = NULL;
 796:         return;
 797:     }
 798:     tempname[7] = 'a' + f;
 799:     if (olist[f] || (olist[f]=fopen(tempname, WRITE))) {
 800:         curout = f;
 801:         curfile = olist[f];
 802:     }
 803: }
 804: 
 805: doundiv(ap, c)
 806: char **ap;
 807: {
 808:     register FILE *fp;
 809:     register int i, ch;
 810:     int j;
 811: 
 812:     if (c == 0) {
 813:         for (i=1; i<10; i++) {
 814:             if (i==curout || olist[i]==NULL)
 815:                 continue;
 816:             fclose(olist[i]);
 817:             tempname[7] = 'a'+i;
 818:             fp = fopen(tempname, READ);
 819:             if (curfile != NULL)
 820:                 while ((ch = getc(fp)) > 0)
 821:                     putc(ch, curfile);
 822:             fclose(fp);
 823:             unlink(tempname);
 824:             olist[i] = NULL;
 825:         }
 826: 
 827:     }
 828:     else {
 829:         for (j = 1; j <= c; j++) {
 830:             i = ctoi(*++ap);
 831:             if (i<1 || i>9 || i==curout || olist[i]==NULL)
 832:                 continue;
 833:             fclose(olist[i]);
 834:             tempname[7] = 'a'+i;
 835:             fp = fopen(tempname, READ);
 836:             if (curfile != NULL)
 837:                 while ((ch = getc(fp)) > 0)
 838:                     putc(ch, curfile);
 839:             fclose(fp);
 840:             unlink(tempname);
 841:             olist[i] = NULL;
 842:         }
 843:     }
 844: }
 845: 
 846: dodivnum(ap, c)
 847: char **ap;
 848: {
 849:     putnum((long) curout);
 850: }
 851: 
 852: dodnl(ap, c)
 853: char **ap;
 854: {
 855:     register t;
 856: 
 857:     while ((t=getchr())!='\n' && t>=0)
 858:         ;
 859: }
 860: 
 861: long ctol(str)
 862: register char *str;
 863: {
 864:     register sign;
 865:     long num;
 866: 
 867:     while (*str==' ' || *str=='\t' || *str=='\n')
 868:         str++;
 869:     num = 0;
 870:     if (*str == '-') {
 871:         sign = -1;
 872:         str++;
 873:     }
 874:     else
 875:         sign = 1;
 876:     while (*str>='0' && *str<='9')
 877:         num = num*10 + *str++ - '0';
 878:     return(sign * num);
 879: }
 880: 
 881: ctoi(s)
 882: char *s;
 883: {
 884:     return(ctol(s));
 885: }
 886: 
 887: min(a, b)
 888: {
 889:     if (a>b)
 890:         return(b);
 891:     return(a);
 892: }
 893: 
 894: max(a, b)
 895: {
 896:     if (a>b)
 897:         return(a);
 898:     return(b);
 899: }

Defined functions

catchsig defined in line 325; used 3 times
copy defined in line 522; used 4 times
ctoi defined in line 881; used 4 times
ctol defined in line 861; used 3 times
delexit defined in line 331; used 12 times
docq defined in line 569; used 1 times
dodef defined in line 536; used 1 times
dodiv defined in line 785; used 1 times
dodivnum defined in line 846; used 1 times
dodnl defined in line 852; used 1 times
dodump defined in line 595; used 1 times
doerrp defined in line 612; used 1 times
doeval defined in line 625; used 1 times
doif defined in line 768; used 1 times
doifdef defined in line 550; used 1 times
doincl defined in line 638; used 2 times
doincr defined in line 669; used 1 times
doindex defined in line 710; used 1 times
dolen defined in line 563; used 1 times
domake defined in line 662; used 1 times
doshift defined in line 589; used 1 times
dosubstr defined in line 692; used 1 times
dosyscmd defined in line 655; used 1 times
dotransl defined in line 735; used 1 times
doundef defined in line 502; used 1 times
doundiv defined in line 805; used 1 times
expand defined in line 391; used 1 times
install defined in line 480; used 51 times
lookup defined in line 459; used 6 times
main defined in line 115; never used
max defined in line 894; used 1 times
min defined in line 887; used 2 times
pbstr defined in line 375; used 7 times
putnum defined in line 676; used 5 times
puttok defined in line 358; used 3 times
strindex defined in line 717; used 1 times

Defined variables

LBRAK defined in line 18; never used
RBRAK defined in line 19; never used
cp defined in line 75; used 22 times
cqloc defined in line 82; used 3 times
cur_ip defined in line 70; used 3 times
curout defined in line 110; used 4 times
defloc defined in line 83; used 3 times
divloc defined in line 90; used 3 times
divnumloc defined in line 91; used 3 times
dnlloc defined in line 93; used 3 times
dumploc defined in line 97; used 3 times
eoa defined in line 57; used 48 times
errploc defined in line 98; used 3 times
evaloc defined in line 84; used 3 times
evalval defined in line 622; used 1 times
hshtab defined in line 64; used 6 times
hshval defined in line 107; used 8 times
ibuf defined in line 65; used 4 times
ifdefloc defined in line 78; used 3 times
ifloc defined in line 89; used 3 times
inclloc defined in line 94; used 3 times
incrloc defined in line 85; used 3 times
indexloc defined in line 87; used 3 times
infptr defined in line 113; used 13 times
ip defined in line 68; used 5 times
ip_stk defined in line 69; used 2 times
lenloc defined in line 79; used 3 times
lpar defined in line 9; used 1 times
  • in line 10
lquote defined in line 22; used 6 times
makeloc defined in line 77; used 3 times
obuf defined in line 66; used 2 times
okret defined in line 109; used 5 times
op defined in line 67; used 13 times
pe defined in line 623; used 1 times
rquote defined in line 23; used 5 times
shiftloc defined in line 81; used 3 times
sinclloc defined in line 95; used 3 times
substrloc defined in line 86; used 3 times
syscmdloc defined in line 96; used 3 times
tempname defined in line 100; used 16 times
token defined in line 56; used 3 times
transloc defined in line 88; used 3 times
type defined in line 37; used 2 times
undefloc defined in line 80; used 3 times
undivloc defined in line 92; used 3 times

Defined struct's

call defined in line 71; used 4 times
nlist defined in line 58; used 22 times

Defined macros

ACUTE defined in line 14; used 2 times
ALPH defined in line 26; used 55 times
COMMA defined in line 12; used 1 times
COMMENT defined in line 25; used 1 times
DIG defined in line 27; used 11 times
EOS defined in line 8; used 3 times
ERROR defined in line 4; used 2 times
GRAVE defined in line 13; used 2 times
HSHSIZ defined in line 29; used 3 times
LBRAK defined in line 15; used 1 times
LPAR defined in line 10; used 2 times
RBRAK defined in line 16; used 1 times
READ defined in line 5; used 5 times
RPAR defined in line 11; used 1 times
SAVS defined in line 31; used 4 times
STACKS defined in line 30; used 4 times
TOKS defined in line 32; used 4 times
WRITE defined in line 6; used 1 times
getchr defined in line 35; used 8 times
putbak defined in line 34; used 15 times
putchr defined in line 36; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2912
Valid CSS Valid XHTML 1.0 Strict