Annotation of 43BSD/usr.bin/m4/m4.c, revision 1.1

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

unix.superglobalmegacorp.com

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