Annotation of 43BSD/usr.bin/m4/m4.c, revision 1.1.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.