Annotation of 40BSD/cmd/m4/m4.c, revision 1.1

1.1     ! root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.