Annotation of researchv10dc/cmd/m4/buns, revision 1.1.1.1

1.1       root        1: # To unbundle, sh this file
                      2: echo unbundling makefile 1>&2
                      3: cat >makefile <<'//GO.SYSIN DD *'
                      4: CFLAGS = -d2
                      5: 
                      6: a.out: m4.o m4ext.o m4macs.o m4y.o
                      7:        cc m4.o m4ext.o m4macs.o m4y.o
                      8: 
                      9: m4.o m4ext.o m4macs.o :        m4.h
                     10: 
                     11: list:
                     12:        pr m4.h m4.c m4ext.c m4macs.c m4y.y makefile
                     13: 
                     14: gcos:
                     15:        yacc m4y.y
                     16:        mv y.tab.c m4.tab.c
                     17:        fsend m4*.c m4.test*
                     18: 
                     19: install:       a.out
                     20:        strip a.out
                     21:        mv a.out /usr/bin/m4
                     22: 
                     23: clean:
                     24:        rm -f a.out *.o
                     25: //GO.SYSIN DD *
                     26: echo unbundling m4.c 1>&2
                     27: cat >m4.c <<'//GO.SYSIN DD *'
                     28: #include       <stdio.h>
                     29: #include       <signal.h>
                     30: #include       "m4.h"
                     31: 
                     32: #define match(c,s)     (c==*s && (!s[1] || inpmatch(s+1)))
                     33: 
                     34: char   *xcalloc();
                     35: 
                     36: 
                     37: main(argc,argv)
                     38: char   **argv;
                     39: {
                     40:        register t;
                     41: 
                     42:        {
                     43:        static  sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0};
                     44:        for (t=0; sigs[t]; ++t)
                     45:                if (signal(sigs[t], SIG_IGN) != SIG_IGN)
                     46:                        signal(sigs[t],catchsig);
                     47:        }
                     48: 
                     49:        tempname = mktemp("/tmp/m4aXXXXXX");
                     50:        close(creat(tempname,0));
                     51: 
                     52:        procnam = argv[0];
                     53:        getflags(&argc,&argv);
                     54:        initalloc();
                     55: 
                     56:        setfname("-");
                     57:        if (argc>1) {
                     58:                --argc;
                     59:                ++argv;
                     60:                if (strcmp(argv[0],"-")) {
                     61:                        ifile[ifx] = xfopen(argv[0],"r");
                     62:                        setfname(argv[0]);
                     63:                }
                     64:        }
                     65: 
                     66:        for (;;) {
                     67:                token[0] = t = getchr();
                     68:                token[1] = EOS;
                     69: 
                     70:                if (t==EOF) {
                     71:                        if (ifx > 0) {
                     72:                                fclose(ifile[ifx]);
                     73:                                ipflr = ipstk[--ifx];
                     74:                                continue;
                     75:                        }
                     76: 
                     77:                        getflags(&argc,&argv);
                     78: 
                     79:                        if (argc<=1)
                     80:                                if (Wrapstr) {
                     81:                                        pbstr(Wrapstr);
                     82:                                        Wrapstr = NULL;
                     83:                                        continue;
                     84:                                } else
                     85:                                        break;
                     86: 
                     87:                        --argc;
                     88:                        ++argv;
                     89: 
                     90:                        if (ifile[ifx]!=stdin)
                     91:                                fclose(ifile[ifx]);
                     92: 
                     93:                        if (*argv[0]=='-')
                     94:                                ifile[ifx] = stdin;
                     95:                        else
                     96:                                ifile[ifx] = xfopen(argv[0],"r");
                     97: 
                     98:                        setfname(argv[0]);
                     99:                        continue;
                    100:                }
                    101: 
                    102:                if (isalpha(t)) {
                    103:                        register char   *tp = token+1;
                    104:                        register        tlim = toksize;
                    105: 
                    106:                        while (alphanum(*tp++=getchr()))
                    107:                                if (--tlim<=0)
                    108:                                        error2("more than %d chars in word",
                    109:                                                        toksize);
                    110: 
                    111:                        putbak(*--tp);
                    112:                        *tp = EOS;
                    113: 
                    114:                        if (((struct nlist *)(*((struct nlist **)Ap)=lookup(token)))->def) {
                    115:                                if (++Ap >= astklm) {
                    116:                                        --Ap;
                    117:                                        error2(astkof,stksize);
                    118:                                }
                    119: 
                    120:                                if (Cp++==NULL)
                    121:                                        Cp = callst;
                    122: 
                    123:                                Cp->argp = Ap;
                    124:                                *Ap++ = op;
                    125:                                puttok(token);
                    126:                                stkchr(EOS);
                    127:                                t = getchr();
                    128:                                putbak(t);
                    129: 
                    130:                                if (t!='(')
                    131:                                        pbstr("()");
                    132:                                else    /* try to fix arg count */
                    133:                                        *Ap++ = op;
                    134: 
                    135:                                Cp->plev = 0;
                    136:                        } else {
                    137:                                puttok(token);
                    138:                        }
                    139:                } else if (match(t,lquote)) {
                    140:                        register        qlev = 1;
                    141: 
                    142:                        for (;;) {
                    143:                                token[0] = t = getchr();
                    144:                                token[1] = EOS;
                    145: 
                    146:                                if (match(t,rquote)) {
                    147:                                        if (--qlev > 0)
                    148:                                                puttok(token);
                    149:                                        else
                    150:                                                break;
                    151:                                } else if (match(t,lquote)) {
                    152:                                        ++qlev;
                    153:                                        puttok(token);
                    154:                                } else {
                    155:                                        if (t==EOF)
                    156:                                                error("EOF in quote");
                    157: 
                    158:                                        putchr(t);
                    159:                                }
                    160:                        }
                    161:                } else if (match(t,lcom)) {
                    162:                        puttok(token);
                    163: 
                    164:                        for (;;) {
                    165:                                token[0] = t = getchr();
                    166:                                token[1] = EOS;
                    167: 
                    168:                                if (match(t,rcom)) {
                    169:                                        puttok(token);
                    170:                                        break;
                    171:                                } else {
                    172:                                        if (t==EOF)
                    173:                                                error("EOF in comment");
                    174:                                        putchr(t);
                    175:                                }
                    176:                        }
                    177:                } else if (Cp==NULL) {
                    178:                        putchr(t);
                    179:                } else if (t=='(') {
                    180:                        if (Cp->plev)
                    181:                                stkchr(t);
                    182:                        else {
                    183:                                /* skip white before arg */
                    184:                                while (isspace(t=getchr()))
                    185:                                        ;
                    186: 
                    187:                                putbak(t);
                    188:                        }
                    189: 
                    190:                        ++Cp->plev;
                    191:                } else if (t==')') {
                    192:                        --Cp->plev;
                    193: 
                    194:                        if (Cp->plev==0) {
                    195:                                stkchr(EOS);
                    196:                                expand(Cp->argp,Ap-Cp->argp-1);
                    197:                                op = *Cp->argp;
                    198:                                Ap = Cp->argp-1;
                    199: 
                    200:                                if (--Cp < callst)
                    201:                                        Cp = NULL;
                    202:                        } else
                    203:                                stkchr(t);
                    204:                } else if (t==',' && Cp->plev<=1) {
                    205:                        stkchr(EOS);
                    206:                        *Ap = op;
                    207: 
                    208:                        if (++Ap >= astklm) {
                    209:                                --Ap;
                    210:                                error2(astkof,stksize);
                    211:                        }
                    212: 
                    213:                        while (isspace(t=getchr()))
                    214:                                ;
                    215: 
                    216:                        putbak(t);
                    217:                } else
                    218:                        stkchr(t);
                    219:        }
                    220: 
                    221:        if (Cp!=NULL)
                    222:                error("EOF in argument list");
                    223: 
                    224:        delexit(OK);
                    225: }
                    226: 
                    227: char *
                    228: inpmatch(s)
                    229: register char  *s;
                    230: {
                    231:        register char   *tp = token+1;
                    232: 
                    233:        while (*s) {
                    234:                *tp = getchr();
                    235: 
                    236:                if (*tp++ != *s++) {
                    237:                        *tp = EOS;
                    238:                        pbstr(token+1);
                    239:                        return 0;
                    240:                }
                    241:        }
                    242: 
                    243:        *tp = EOS;
                    244:        return token;
                    245: }
                    246: 
                    247: getflags(xargc,xargv)
                    248: register int   *xargc;
                    249: register char  ***xargv;
                    250: {
                    251:        while (*xargc > 1) {
                    252:                register char   *arg = (*xargv)[1];
                    253: 
                    254:                if (arg[0]!='-' || arg[1]==EOS)
                    255:                        break;
                    256: 
                    257:                switch (arg[1]) {
                    258:                case 'B':
                    259:                        bufsize = atoi(&arg[2]);
                    260:                        break;
                    261:                case 'D':
                    262:                        {
                    263:                        register char *t;
                    264:                        char *s[2];
                    265: 
                    266:                        initalloc();
                    267: 
                    268:                        for (t = s[0] = &arg[2]; *t; t++)
                    269:                                if (*t=='=') {
                    270:                                        *t++ = EOS;
                    271:                                        break;
                    272:                                }
                    273: 
                    274:                        s[1] = t;
                    275:                        dodef(&s[-1],2);
                    276:                        break;
                    277:                        }
                    278:                case 'H':
                    279:                        hshsize = atoi(&arg[2]);
                    280:                        break;
                    281:                case 'S':
                    282:                        stksize = atoi(&arg[2]);
                    283:                        break;
                    284:                case 'T':
                    285:                        toksize = atoi(&arg[2]);
                    286:                        break;
                    287:                case 'U':
                    288:                        {
                    289:                        char *s[1];
                    290: 
                    291:                        initalloc();
                    292:                        s[0] = &arg[2];
                    293:                        doundef(&s[-1],1);
                    294:                        break;
                    295:                        }
                    296:                case 'e':
                    297:                        setbuf(stdout,NULL);
                    298:                        signal(SIGINT,SIG_IGN);
                    299:                        break;
                    300:                case 's':
                    301:                        /* turn on line sync */
                    302:                        sflag = 1;
                    303:                        break;
                    304:                default:
                    305:                        fprintf(stderr,"%s: bad option: %s\n",
                    306:                                procnam,arg);
                    307:                        delexit(NOT_OK);
                    308:                }
                    309: 
                    310:                (*xargv)++;
                    311:                --(*xargc);
                    312:        }
                    313: 
                    314:        return;
                    315: }
                    316: 
                    317: initalloc()
                    318: {
                    319:        static  done = 0;
                    320:        register        t;
                    321: 
                    322:        if (done++)
                    323:                return;
                    324: 
                    325:        hshtab = (struct nlist **)xcalloc(hshsize,sizeof(struct nlist *));
                    326:        callst = (struct call *)xcalloc(stksize/3+1,sizeof(struct call));
                    327:        Ap = argstk = (char **)xcalloc(stksize+3,sizeof(char *));
                    328:        ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1,sizeof(char));
                    329:        op = obuf = xcalloc(bufsize+1,sizeof(char));
                    330:        token = xcalloc(toksize+1,sizeof(char));
                    331: 
                    332:        astklm = &argstk[stksize];
                    333:        ibuflm = &ibuf[bufsize];
                    334:        obuflm = &obuf[bufsize];
                    335:        toklm = &token[toksize];
                    336: 
                    337:        for (t=0; barray[t].bname; ++t) {
                    338:                static char     p[2] = {0, EOS};
                    339: 
                    340:                p[0] = t|~LOW7;
                    341:                install(barray[t].bname,p,NOPUSH);
                    342:        }
                    343: 
                    344:        install("unix",nullstr,NOPUSH);
                    345: }
                    346: 
                    347: /*struct nlist * */
                    348: install(nam,val,mode)
                    349: char   *nam;
                    350: register char  *val;
                    351: {
                    352:        register struct nlist *np;
                    353:        register char   *cp;
                    354:        int             l;
                    355: 
                    356:        if (mode==PUSH)
                    357:                lookup(nam);    /* lookup sets hshval */
                    358:        else
                    359:                while (undef(nam))      /* undef calls lookup */
                    360:                        ;
                    361: 
                    362:        np = (struct nlist *)xcalloc(1,sizeof(*np));
                    363:        np->name = copy(nam);
                    364:        np->next = hshtab[hshval];
                    365:        hshtab[hshval] = np;
                    366: 
                    367:        cp = xcalloc((l=strlen(val))+1,sizeof(*val));
                    368:        np->def = cp;
                    369:        cp = &cp[l];
                    370: 
                    371:        while (*val)
                    372:                *--cp = *val++;
                    373: }
                    374: 
                    375: struct nlist   *
                    376: lookup(str)
                    377: char   *str;
                    378: {
                    379:        register char           *s1, *s2;
                    380:        register struct nlist   *np;
                    381:        static struct nlist     nodef;
                    382: 
                    383:        s1 = str;
                    384: 
                    385:        for (hshval = 0; *s1; )
                    386:                hshval += *s1++;
                    387: 
                    388:        hshval %= hshsize;
                    389: 
                    390:        for (np = hshtab[hshval]; np!=NULL; np = np->next) {
                    391:                s1 = str;
                    392:                s2 = np->name;
                    393:                while (*s1++==*s2)
                    394:                        if (*s2++==EOS)
                    395:                                return(np);
                    396:        }
                    397: 
                    398:        return(&nodef);
                    399: }
                    400: 
                    401: expand(a1,c)
                    402: char   **a1;
                    403: {
                    404:        register char   *dp;
                    405:        register struct nlist   *sp;
                    406: 
                    407:        sp = (struct nlist *)a1[-1];
                    408: 
                    409:        if (sp->tflag || trace) {
                    410:                int     i;
                    411: 
                    412:                fprintf(stderr,"Trace(%d): %s",Cp-callst,a1[0]);
                    413: 
                    414:                if (c > 0) {
                    415:                        fprintf(stderr,"(%s",chkbltin(a1[1]));
                    416:                        for (i=2; i<=c; ++i)
                    417:                                fprintf(stderr,",%s",chkbltin(a1[i]));
                    418:                        fprintf(stderr,")");
                    419:                }
                    420: 
                    421:                fprintf(stderr,"\n");
                    422:        }
                    423: 
                    424:        dp = sp->def;
                    425: 
                    426:        for (; *dp; ++dp) {
                    427:                if (*dp&~LOW7) {
                    428:                        (*barray[*dp&LOW7].bfunc)(a1,c);
                    429:                } else if (dp[1]=='$') {
                    430:                        if (isdigit(*dp)) {
                    431:                                register        n;
                    432:                                if ((n = *dp-'0') <= c)
                    433:                                        pbstr(a1[n]);
                    434:                                ++dp;
                    435:                        } else if (*dp=='#') {
                    436:                                pbnum((long) c);
                    437:                                ++dp;
                    438:                        } else if (*dp=='*' || *dp=='@') {
                    439:                                register i = c;
                    440:                                char **a = a1;
                    441: 
                    442:                                if (i > 0)
                    443:                                        for (;;) {
                    444:                                                if (*dp=='@')
                    445:                                                        pbstr(rquote);
                    446: 
                    447:                                                pbstr(a[i--]);
                    448: 
                    449:                                                if (*dp=='@')
                    450:                                                        pbstr(lquote);
                    451: 
                    452:                                                if (i <= 0)
                    453:                                                        break;
                    454: 
                    455:                                                pbstr(",");
                    456:                                        }
                    457:                                ++dp;
                    458:                        } else
                    459:                                putbak(*dp);
                    460:                } else
                    461:                        putbak(*dp);
                    462:        }
                    463: }
                    464: 
                    465: setfname(s)
                    466: register char  *s;
                    467: {
                    468:        strcpy(fname[ifx],s);
                    469:        fname[ifx+1] = fname[ifx]+strlen(s)+1;
                    470:        fline[ifx] = 1;
                    471:        nflag = 1;
                    472:        lnsync(stdout);
                    473: }
                    474: 
                    475: lnsync(iop)
                    476: register FILE  *iop;
                    477: {
                    478:        static int cline = 0;
                    479:        static int cfile = 0;
                    480: 
                    481:        if (!sflag || iop!=stdout)
                    482:                return;
                    483: 
                    484:        if (nflag || ifx!=cfile) {
                    485:                nflag = 0;
                    486:                cfile = ifx;
                    487:                fprintf(iop,"#line %d \"",cline = fline[ifx]);
                    488:                fpath(iop);
                    489:                fprintf(iop,"\"\n");
                    490:        } else if (++cline != fline[ifx])
                    491:                fprintf(iop,"#line %d\n",cline = fline[ifx]);
                    492: }
                    493: 
                    494: fpath(iop)
                    495: register FILE  *iop;
                    496: {
                    497:        register        i;
                    498: 
                    499:        fprintf(iop,"%s",fname[0]);
                    500: 
                    501:        for (i=1; i<=ifx; ++i)
                    502:                fprintf(iop,":%s",fname[i]);
                    503: }
                    504: 
                    505: catchsig()
                    506: {
                    507:        signal(SIGHUP,SIG_IGN);
                    508:        signal(SIGINT,SIG_IGN);
                    509: 
                    510:        delexit(NOT_OK);
                    511: }
                    512: 
                    513: delexit(code)
                    514: {
                    515:        register i;
                    516: 
                    517:        cf = stdout;
                    518: 
                    519: /*     if (ofx != 0) { /* quitting in middle of diversion */
                    520: /*             ofx = 0;
                    521: /*             code = NOT_OK;
                    522: /*     }
                    523: */
                    524:        ofx = 0;        /* ensure that everything comes out */
                    525:        for (i=1; i<10; i++)
                    526:                undiv(i,code);
                    527: 
                    528:        tempname[7] = 'a';
                    529:        unlink(tempname);
                    530: 
                    531:        if (code==OK)
                    532:                exit(code);
                    533: 
                    534:        _exit(code);
                    535: }
                    536: 
                    537: puttok(tp)
                    538: register char *tp;
                    539: {
                    540:        if (Cp) {
                    541:                while (*tp)
                    542:                        stkchr(*tp++);
                    543:        } else if (cf)
                    544:                while (*tp)
                    545:                        sputchr(*tp++,cf);
                    546: }
                    547: 
                    548: pbstr(str)
                    549: register char *str;
                    550: {
                    551:        register char *p;
                    552: 
                    553:        p = str;
                    554: 
                    555:        while (*p++)
                    556:                ;
                    557: 
                    558:        --p;
                    559: 
                    560:        while (p > str)
                    561:                putbak(*--p);
                    562: }
                    563: 
                    564: undiv(i,code)
                    565: register       i;
                    566: {
                    567:        register FILE *fp;
                    568:        register        c;
                    569: 
                    570:        if (i<1 || i>9 || i==ofx || !ofile[i])
                    571:                return;
                    572: 
                    573:        fclose(ofile[i]);
                    574:        tempname[7] = 'a'+i;
                    575: 
                    576:        if (code==OK && cf) {
                    577:                fp = xfopen(tempname,"r");
                    578: 
                    579:                while ((c=getc(fp)) != EOF)
                    580:                        sputchr(c,cf);
                    581: 
                    582:                fclose(fp);
                    583:        }
                    584: 
                    585:        unlink(tempname);
                    586:        ofile[i] = NULL;
                    587: }
                    588: 
                    589: char   *copy(s)
                    590: register char *s;
                    591: {
                    592:        register char *p, *s1;
                    593: 
                    594:        p = s1 = xcalloc(strlen(s)+1,1);
                    595: 
                    596:        while (*s1++ = *s++)
                    597:                ;
                    598: 
                    599:        return(p);
                    600: }
                    601: 
                    602: pbnum(num)
                    603: long num;
                    604: {
                    605:        pbnbr(num,10,1);
                    606: }
                    607: 
                    608: pbnbr(nbr,base,len)
                    609: long   nbr;
                    610: register       base, len;
                    611: {
                    612:        register        neg = 0;
                    613: 
                    614:        if (base<=0)
                    615:                return;
                    616: 
                    617:        if (nbr<0) {
                    618:                neg = 1;
                    619:                nbr = -nbr;
                    620:        }
                    621: 
                    622:        while (nbr>0) {
                    623:                int     i;
                    624:                if (base>1) {
                    625:                        i = nbr%base;
                    626:                        nbr /= base;
                    627:                } else {
                    628:                        i = 1;
                    629:                        --nbr;
                    630:                }
                    631:                putbak(itochr(i));
                    632:                --len;
                    633:        }
                    634: 
                    635:        while (--len >= 0)
                    636:                putbak('0');
                    637: 
                    638:        if (neg)
                    639:                putbak('-');
                    640: }
                    641: 
                    642: itochr(i)
                    643: register       i;
                    644: {
                    645:        if (i>9)
                    646:                return i-10+'A';
                    647:        else
                    648:                return i+'0';
                    649: }
                    650: 
                    651: long ctol(str)
                    652: register char *str;
                    653: {
                    654:        register sign;
                    655:        long num;
                    656: 
                    657:        while (isspace(*str))
                    658:                ++str;
                    659:        num = 0;
                    660:        if (*str=='-') {
                    661:                sign = -1;
                    662:                ++str;
                    663:        }
                    664:        else
                    665:                sign = 1;
                    666:        while (isdigit(*str))
                    667:                num = num*10 + *str++ - '0';
                    668:        return(sign * num);
                    669: }
                    670: 
                    671: min(a,b)
                    672: {
                    673:        if (a>b)
                    674:                return(b);
                    675:        return(a);
                    676: }
                    677: 
                    678: FILE   *
                    679: xfopen(name,mode)
                    680: char   *name,
                    681:        *mode;
                    682: {
                    683:        FILE    *fp;
                    684: 
                    685:        if ((fp=fopen(name,mode))==NULL)
                    686:                error(badfile);
                    687: 
                    688:        return fp;
                    689: }
                    690: 
                    691: char *
                    692: xcalloc(nbr,size)
                    693: {
                    694:        register char   *ptr;
                    695: 
                    696:        if ((ptr=calloc(nbr,size)) == NULL)
                    697:                error(nocore);
                    698: 
                    699:        return ptr;
                    700: }
                    701: 
                    702: error(str)
                    703:        char *str;
                    704: {
                    705:        fprintf(stderr,"\n%s:",procnam);
                    706:        fpath(stderr);
                    707:        fprintf(stderr,":%d %s\n",fline[ifx],str);
                    708:        if (Cp) {
                    709:                register struct call    *mptr;
                    710: 
                    711:                /* fix limit */
                    712:                *op = EOS;
                    713:                (Cp+1)->argp = Ap+1;
                    714: 
                    715:                for (mptr=callst; mptr<=Cp; ++mptr) {
                    716:                        register char   **aptr, **lim;
                    717: 
                    718:                        aptr = mptr->argp;
                    719:                        lim = (mptr+1)->argp-1;
                    720:                        if (mptr==callst)
                    721:                                fputs(*aptr,stderr);
                    722:                        ++aptr;
                    723:                        fputs("(",stderr);
                    724:                        if (aptr < lim)
                    725:                                for (;;) {
                    726:                                        fputs(*aptr++,stderr);
                    727:                                        if (aptr >= lim)
                    728:                                                break;
                    729:                                        fputs(",",stderr);
                    730:                                }
                    731:                }
                    732:                while (--mptr >= callst)
                    733:                        fputs(")",stderr);
                    734: 
                    735:                fputs("\n",stderr);
                    736:        }
                    737:        delexit(NOT_OK);
                    738: }
                    739: 
                    740: error2(str,num)
                    741:        char *str;
                    742:        int num;
                    743: {
                    744:        char buf[500];
                    745: 
                    746:        fprintf(buf,str,num);
                    747:        error(buf);
                    748: }
                    749: 
                    750: char *
                    751: chkbltin(s)
                    752: char   *s;
                    753: {
                    754:        static char     buf[24];
                    755: 
                    756:        if (*s&~LOW7) {
                    757:                sprintf(buf,"<%s>",barray[*s&LOW7].bname);
                    758:                return buf;
                    759:        }
                    760:        return s;
                    761: }
                    762: //GO.SYSIN DD *
                    763: echo unbundling m4.h 1>&2
                    764: cat >m4.h <<'//GO.SYSIN DD *'
                    765: #define EOS    '\0'
                    766: #define LOW7   0177
                    767: #define MAXSYM 5
                    768: #define PUSH   1
                    769: #define NOPUSH 0
                    770: #define OK     0
                    771: #define NOT_OK 1
                    772: 
                    773: #define SPACE  1
                    774: #define DIG    2
                    775: #define ALPH   4
                    776: #define isspace(c)     (type[c]&SPACE)
                    777: #define isdigit(c)     (type[c]&DIG)
                    778: #define isalpha(c)     (type[c]&ALPH)
                    779: #define alphanum(c)    (type[c]&(ALPH|DIG))
                    780: 
                    781: #define        getchr()        (ip>ipflr?*--ip:\
                    782:        ((C=(feof(ifile[ifx])?EOF:getc(ifile[ifx])))=='\n'?(fline[ifx]++,C):C))
                    783: #define        putbak(c)       (ip < ibuflm? (*ip++ = (c)): error(pbmsg,bufsize))
                    784: #define        stkchr(c)       (op < obuflm? (*op++ = (c)): error(aofmsg,bufsize))
                    785: #define sputchr(c,f)   (putc(c,f)=='\n'? lnsync(f): 0)
                    786: #define putchr(c)      (Cp?stkchr(c):cf?(sflag?sputchr(c,cf):putc(c,cf)):0)
                    787: 
                    788: struct bs {
                    789:        int     (*bfunc)();
                    790:        char    *bname;
                    791: };
                    792: 
                    793: struct call {
                    794:        char    **argp;
                    795:        int     plev;
                    796: };
                    797: 
                    798: struct nlist {
                    799:        char    *name;
                    800:        char    *def;
                    801:        char    tflag;
                    802:        struct  nlist *next;
                    803: };
                    804: 
                    805: extern FILE    *cf;
                    806: extern FILE    *ifile[];
                    807: extern FILE    *ofile[];
                    808: extern FILE    *xfopen();
                    809: extern char    **Ap;
                    810: extern char    **argstk;
                    811: extern char    *Wrapstr;
                    812: extern char    **astklm;
                    813: extern char    *calloc();
                    814: extern char    *copy();
                    815: extern char    *fname[];
                    816: extern char    *ibuf;
                    817: extern char    *ibuflm;
                    818: extern char    *ip;
                    819: extern char    *ipflr;
                    820: extern char    *ipstk[10];
                    821: extern char    *obuf;
                    822: extern char    *obuflm;
                    823: extern char    *op;
                    824: extern char    *procnam;
                    825: extern char    *tempname;
                    826: extern char    *token;
                    827: extern char    *toklm;
                    828: extern char    aofmsg[];
                    829: extern char    astkof[];
                    830: extern char    badfile[];
                    831: extern char    fnbuf[];
                    832: extern char    lcom[];
                    833: extern char    lquote[];
                    834: extern char    nocore[];
                    835: extern char    nullstr[];
                    836: extern char    pbmsg[];
                    837: extern char    rcom[];
                    838: extern char    rquote[];
                    839: extern char    type[];
                    840: extern int     C;
                    841: extern int     bufsize;
                    842: extern int     catchsig();
                    843: extern int     fline[];
                    844: extern int     hshsize;
                    845: extern int     hshval;
                    846: extern int     ifx;
                    847: extern int     nflag;
                    848: extern int     ofx;
                    849: extern int     pid;
                    850: extern int     sflag;
                    851: extern int     stksize;
                    852: extern int     sysrval;
                    853: extern int     toksize;
                    854: extern int     trace;
                    855: extern long    ctol();
                    856: extern struct bs       barray[];
                    857: extern struct call     *Cp;
                    858: extern struct call     *callst;
                    859: extern struct nlist    **hshtab;
                    860: /*extern struct nlist  *install(); */
                    861: extern struct nlist    *lookup();
                    862: extern char            *inpmatch();
                    863: extern char            *chkbltin();
                    864: extern char            *mktemp();
                    865: //GO.SYSIN DD *
                    866: echo unbundling m4ext.c 1>&2
                    867: cat >m4ext.c <<'//GO.SYSIN DD *'
                    868: #include       <stdio.h>
                    869: #include       "m4.h"
                    870: 
                    871: 
                    872: /* storage params */
                    873: int    hshsize         = 199;          /* hash table size (prime) */
                    874: int    bufsize         = 4096;         /* pushback & arg text buffers */
                    875: int    stksize         = 100;          /* call stack */
                    876: int    toksize         = 512;          /* biggest word ([a-z_][a-z0-9_]*) */
                    877: 
                    878: 
                    879: /* pushback buffer */
                    880: char   *ibuf;                          /* buffer */
                    881: char   *ibuflm;                        /* highest buffer addr */
                    882: char   *ip;                            /* current position */
                    883: char   *ipflr;                         /* buffer floor */
                    884: char   *ipstk[10];                     /* stack for "ipflr"s */
                    885: 
                    886: 
                    887: /* arg collection buffer */
                    888: char   *obuf;                          /* buffer */
                    889: char   *obuflm;                        /* high address */
                    890: char   *op;                            /* current position */
                    891: 
                    892: 
                    893: /* call stack */
                    894: struct call    *callst;                /* stack */
                    895: struct call    *Cp     = NULL;         /* position */
                    896: 
                    897: 
                    898: /* token storage */
                    899: char   *token;                         /* buffer */
                    900: char   *toklm;                         /* high addr */
                    901: 
                    902: 
                    903: /* file name and current line storage for line sync and diagnostics */
                    904: char   fnbuf[200];                     /* holds file name strings */
                    905: char   *fname[11]      = {fnbuf};      /* file name ptr stack */
                    906: int    fline[10];                      /* current line nbr stack */
                    907: 
                    908: 
                    909: /* input file stuff for "include"s */
                    910: FILE   *ifile[10]      = {stdin};      /* stack */
                    911: int    ifx;                            /* stack index */
                    912: 
                    913: 
                    914: /* stuff for output diversions */
                    915: FILE   *cf     = stdout;               /* current output file */
                    916: FILE   *ofile[11]      = {stdout};     /* output file stack */
                    917: int    ofx;                            /* stack index */
                    918: 
                    919: 
                    920: /* comment markers */
                    921: char   lcom[MAXSYM+1]  = "#";
                    922: char   rcom[MAXSYM+1]  = "\n";
                    923: 
                    924: 
                    925: /* quote markers */
                    926: char   lquote[MAXSYM+1]        = "`";
                    927: char   rquote[MAXSYM+1]        = "'";
                    928: 
                    929: 
                    930: /* argument ptr stack */
                    931: char   **argstk;
                    932: char   **astklm;                       /* high address */
                    933: char   **Ap;                           /* current position */
                    934: 
                    935: 
                    936: /* symbol table */
                    937: struct nlist   **hshtab;               /* hash table */
                    938: int    hshval;                         /* last hash val */
                    939: 
                    940: 
                    941: /* misc */
                    942: char   *procnam;                       /* argv[0] */
                    943: char   *tempname;                      /* used for diversion files */
                    944: char   *Wrapstr;                       /* last pushback string for "m4wrap" */
                    945: char   nullstr[]       = "";
                    946: int    C;                              /* see "m4.h" macros */
                    947: int    nflag   = 1;                    /* name flag, used for line sync code */
                    948: int    sflag;                          /* line sync flag */
                    949: int    sysrval;                        /* return val from syscmd */
                    950: int    trace;                          /* global trace flag */
                    951: 
                    952: 
                    953: char   aofmsg[]        = "more than %d chars of argument text";
                    954: char   astkof[]        = "more than %d items on argument stack";
                    955: char   badfile[]       = "can't open file";
                    956: char   nocore[]        = "out of storage";
                    957: char   pbmsg[]         = "pushed back more than %d chars";
                    958: 
                    959: 
                    960: /* char map */
                    961: char   type[]  = {
                    962:        0,      0,      0,      0,      0,      0,      0,      0,
                    963:        0,      SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  0,      0,
                    964:        0,      0,      0,      0,      0,      0,      0,      0,
                    965:        0,      0,      0,      0,      0,      0,      0,      0,
                    966:        SPACE,  0,      0,      0,      0,      0,      0,      0,
                    967:        0,      0,      0,      0,      0,      0,      0,      0,
                    968:        DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,
                    969:        DIG,    DIG,    0,      0,      0,      0,      0,      0,
                    970:        0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                    971:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                    972:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                    973:        ALPH,   ALPH,   ALPH,   0,      0,      0,      0,      ALPH,
                    974:        0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                    975:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                    976:        ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
                    977:        ALPH,   ALPH,   ALPH,   0,      0,      0,      0,      0,
                    978: };
                    979: //GO.SYSIN DD *
                    980: echo unbundling m4macs.c 1>&2
                    981: cat >m4macs.c <<'//GO.SYSIN DD *'
                    982: #include       <stdio.h>
                    983: #include       <sys/types.h>
                    984: #include       <sys/stat.h>
                    985: #include       "m4.h"
                    986: 
                    987: #define arg(n) (c<(n)? nullstr: ap[n])
                    988: 
                    989: dochcom(ap,c)
                    990: char   **ap;
                    991: {
                    992:        register char   *l = arg(1);
                    993:        register char   *r = arg(2);
                    994: 
                    995:        if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
                    996:                error2("comment marker longer than %d chars",MAXSYM);
                    997:        strcpy(lcom,l);
                    998:        strcpy(rcom,*r?r:"\n");
                    999: }
                   1000: 
                   1001: docq(ap,c)
                   1002: register char  **ap;
                   1003: {
                   1004:        register char   *l = arg(1);
                   1005:        register char   *r = arg(2);
                   1006: 
                   1007:        if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
                   1008:                error2("quote marker longer than %d chars", MAXSYM);
                   1009: 
                   1010:        if (c<=1 && !*l) {
                   1011:                l = "`";
                   1012:                r = "'";
                   1013:        } else if (c==1) {
                   1014:                r = l;
                   1015:        }
                   1016: 
                   1017:        strcpy(lquote,l);
                   1018:        strcpy(rquote,r);
                   1019: }
                   1020: 
                   1021: dodecr(ap,c)
                   1022: char   **ap;
                   1023: {
                   1024:        pbnum(ctol(arg(1))-1);
                   1025: }
                   1026: 
                   1027: dodef(ap,c)
                   1028: char   **ap;
                   1029: {
                   1030:        def(ap,c,NOPUSH);
                   1031: }
                   1032: 
                   1033: def(ap,c,mode)
                   1034: register char  **ap;
                   1035: {
                   1036:        register char   *s;
                   1037: 
                   1038:        if (c<1)
                   1039:                return;
                   1040: 
                   1041:        s = ap[1];
                   1042:        if (isalpha(*s))
                   1043:                while (alphanum(*++s))
                   1044:                        ;
                   1045:        if (*s || s==ap[1])
                   1046:                error("bad macro name");
                   1047: 
                   1048:        if (strcmp(ap[1],ap[2])==0)
                   1049:                error("macro defined as itself");
                   1050:        install(ap[1],arg(2),mode);
                   1051: }
                   1052: 
                   1053: dodefn(ap,c)
                   1054: register char  **ap;
                   1055: register c;
                   1056: {
                   1057:        register char *d;
                   1058: 
                   1059:        while (c > 0)
                   1060:                if ((d = lookup(ap[c--])->def) != NULL) {
                   1061:                        putbak(*rquote);
                   1062:                        while (*d)
                   1063:                                putbak(*d++);
                   1064:                        putbak(*lquote);
                   1065:                }
                   1066: }
                   1067: 
                   1068: dodiv(ap,c)
                   1069: register char **ap;
                   1070: {
                   1071:        register int f;
                   1072: 
                   1073:        f = atoi(arg(1));
                   1074:        if (f>=10 || f<0) {
                   1075:                cf = NULL;
                   1076:                ofx = f;
                   1077:                return;
                   1078:        }
                   1079:        tempname[7] = 'a'+f;
                   1080:        if (ofile[f] || (ofile[f]=xfopen(tempname,"w"))) {
                   1081:                ofx = f;
                   1082:                cf = ofile[f];
                   1083:        }
                   1084: }
                   1085: 
                   1086: dodivnum(ap,c)
                   1087: {
                   1088:        pbnum((long) ofx);
                   1089: }
                   1090: 
                   1091: dodnl(ap,c)
                   1092: char   *ap;
                   1093: {
                   1094:        register t;
                   1095: 
                   1096:        while ((t=getchr())!='\n' && t!=EOF)
                   1097:                ;
                   1098: }
                   1099: 
                   1100: dodump(ap,c)
                   1101: char   **ap;
                   1102: {
                   1103:        register struct nlist *np;
                   1104:        register        i;
                   1105: 
                   1106:        if (c > 0)
                   1107:                while (c--) {
                   1108:                        if ((np = lookup(*++ap))->name != NULL)
                   1109:                                dump(np->name,np->def);
                   1110:                }
                   1111:        else
                   1112:                for (i=0; i<hshsize; i++)
                   1113:                        for (np=hshtab[i]; np!=NULL; np=np->next)
                   1114:                                dump(np->name,np->def);
                   1115: }
                   1116: 
                   1117: dump(name,def)
                   1118: register char  *name,
                   1119:                *def;
                   1120: {
                   1121:        register char   *s = def;
                   1122: 
                   1123:        fprintf(stderr,"%s:\t",name);
                   1124: 
                   1125:        while (*s++)
                   1126:                ;
                   1127:        --s;
                   1128: 
                   1129:        while (s>def)
                   1130:                if (*--s&~LOW7)
                   1131:                        fprintf(stderr,"<%s>",barray[*s&LOW7].bname);
                   1132:                else
                   1133:                        fputc(*s,stderr);
                   1134: 
                   1135:        fputc('\n',stderr);
                   1136: }
                   1137: 
                   1138: doerrp(ap,c)
                   1139: char   **ap;
                   1140: {
                   1141:        if (c > 0)
                   1142:                fprintf(stderr,"%s",ap[1]);
                   1143: }
                   1144: 
                   1145: long   evalval;        /* return value from yacc stuff */
                   1146: char   *pe;    /* used by grammar */
                   1147: doeval(ap,c)
                   1148: char   **ap;
                   1149: {
                   1150:        register        base = atoi(arg(2));
                   1151:        register        pad = atoi(arg(3));
                   1152: 
                   1153:        evalval = 0;
                   1154:        if (c > 0) {
                   1155:                pe = ap[1];
                   1156:                if (yyparse()!=0)
                   1157:                        error("invalid expression");
                   1158:        }
                   1159:        pbnbr(evalval, base>0?base:10, pad>0?pad:1);
                   1160: }
                   1161: 
                   1162: doexit(ap,c)
                   1163: char   **ap;
                   1164: {
                   1165:        delexit(atoi(arg(1)));
                   1166: }
                   1167: 
                   1168: doif(ap,c)
                   1169: register char **ap;
                   1170: {
                   1171:        if (c < 3)
                   1172:                return;
                   1173:        while (c >= 3) {
                   1174:                if (strcmp(ap[1],ap[2])==0) {
                   1175:                        pbstr(ap[3]);
                   1176:                        return;
                   1177:                }
                   1178:                c -= 3;
                   1179:                ap += 3;
                   1180:        }
                   1181:        if (c > 0)
                   1182:                pbstr(ap[1]);
                   1183: }
                   1184: 
                   1185: doifdef(ap,c)
                   1186: char   **ap;
                   1187: {
                   1188:        if (c < 2)
                   1189:                return;
                   1190: 
                   1191:        while (c >= 2) {
                   1192:                if (lookup(ap[1])->name != NULL) {
                   1193:                        pbstr(ap[2]);
                   1194:                        return;
                   1195:                }
                   1196:                c -= 2;
                   1197:                ap += 2;
                   1198:        }
                   1199: 
                   1200:        if (c > 0)
                   1201:                pbstr(ap[1]);
                   1202: }
                   1203: 
                   1204: doincl(ap,c)
                   1205: char   **ap;
                   1206: {
                   1207:        incl(ap,c,1);
                   1208: }
                   1209: 
                   1210: incl(ap,c,noisy)
                   1211: register char  **ap;
                   1212: {
                   1213:        if (c>0 && strlen(ap[1])>0) {
                   1214:                if (ifx >= 9)
                   1215:                        error("input file nesting too deep (9)");
                   1216:                if ((ifile[++ifx]=fopen(ap[1],"r"))==NULL){
                   1217:                        --ifx;
                   1218:                        if (noisy)
                   1219:                                error(badfile);
                   1220:                } else {
                   1221:                        ipstk[ifx] = ipflr = ip;
                   1222:                        setfname(ap[1]);
                   1223:                }
                   1224:        }
                   1225: }
                   1226: 
                   1227: doincr(ap,c)
                   1228: char   **ap;
                   1229: {
                   1230:        pbnum(ctol(arg(1))+1);
                   1231: }
                   1232: 
                   1233: doindex(ap,c)
                   1234: char   **ap;
                   1235: {
                   1236:        register char   *subj = arg(1);
                   1237:        register char   *obj  = arg(2);
                   1238:        register        i;
                   1239: 
                   1240:        for (i=0; *subj; ++i)
                   1241:                if (leftmatch(subj++,obj)) {
                   1242:                        pbnum( (long) i );
                   1243:                        return;
                   1244:                }
                   1245: 
                   1246:        pbnum( (long) -1 );
                   1247: }
                   1248: 
                   1249: leftmatch(str,substr)
                   1250: register char  *str;
                   1251: register char  *substr;
                   1252: {
                   1253:        while (*substr)
                   1254:                if (*str++ != *substr++)
                   1255:                        return (0);
                   1256: 
                   1257:        return (1);
                   1258: }
                   1259: 
                   1260: dolen(ap,c)
                   1261: char   **ap;
                   1262: {
                   1263:        pbnum((long) strlen(arg(1)));
                   1264: }
                   1265: 
                   1266: domake(ap,c)
                   1267: char   **ap;
                   1268: {
                   1269:        if (c > 0)
                   1270:                pbstr(mktemp(ap[1]));
                   1271: }
                   1272: 
                   1273: dopopdef(ap,c)
                   1274: char   **ap;
                   1275: {
                   1276:        register        i;
                   1277: 
                   1278:        for (i=1; i<=c; ++i)
                   1279:                undef(ap[i]);
                   1280: }
                   1281: 
                   1282: dopushdef(ap,c)
                   1283: char   **ap;
                   1284: {
                   1285:        def(ap,c,PUSH);
                   1286: }
                   1287: 
                   1288: doshift(ap,c)
                   1289: register char  **ap;
                   1290: register c;
                   1291: {
                   1292:        if (c <= 1)
                   1293:                return;
                   1294: 
                   1295:        for (;;) {
                   1296:                pbstr(rquote);
                   1297:                pbstr(ap[c--]);
                   1298:                pbstr(lquote);
                   1299: 
                   1300:                if (c <= 1)
                   1301:                        break;
                   1302: 
                   1303:                pbstr(",");
                   1304:        }
                   1305: }
                   1306: 
                   1307: dosincl(ap,c)
                   1308: char   **ap;
                   1309: {
                   1310:        incl(ap,c,0);
                   1311: }
                   1312: 
                   1313: dosubstr(ap,c)
                   1314: register char  **ap;
                   1315: {
                   1316:        char    *str;
                   1317:        int     inlen, outlen;
                   1318:        register        offset, ix;
                   1319: 
                   1320:        inlen = strlen(str=arg(1));
                   1321:        offset = atoi(arg(2));
                   1322: 
                   1323:        if (offset<0 || offset>=inlen)
                   1324:                return;
                   1325: 
                   1326:        outlen = c>=3? atoi(ap[3]): inlen;
                   1327:        ix = min(offset+outlen,inlen);
                   1328: 
                   1329:        while (ix > offset)
                   1330:                putbak(str[--ix]);
                   1331: }
                   1332: 
                   1333: dosyscmd(ap,c)
                   1334: char   **ap;
                   1335: {
                   1336:        sysrval = 0;
                   1337:        if (c > 0) {
                   1338:                fflush(stdout);
                   1339:                sysrval = system(ap[1]);
                   1340:        }
                   1341: }
                   1342: 
                   1343: dosysval(ap,c)
                   1344: char   **ap;
                   1345: {
                   1346:        pbnum((long) (sysrval>>8));
                   1347: }
                   1348: 
                   1349: dotransl(ap,c)
                   1350: char   **ap;
                   1351: {
                   1352:        char    *sink, *fr, *sto;
                   1353:        register char   *source, *to;
                   1354: 
                   1355:        if (c<1)
                   1356:                return;
                   1357: 
                   1358:        sink = ap[1];
                   1359:        fr = arg(2);
                   1360:        sto = arg(3);
                   1361: 
                   1362:        for (source = ap[1]; *source; source++) {
                   1363:                register char   *i;
                   1364:                to = sto;
                   1365:                for (i = fr; *i; ++i) {
                   1366:                        if (*source==*i)
                   1367:                                break;
                   1368:                        if (*to)
                   1369:                                ++to;
                   1370:                }
                   1371:                if (*i) {
                   1372:                        if (*to)
                   1373:                                *sink++ = *to;
                   1374:                } else
                   1375:                        *sink++ = *source;
                   1376:        }
                   1377:        *sink = EOS;
                   1378:        pbstr(ap[1]);
                   1379: }
                   1380: 
                   1381: dotroff(ap,c)
                   1382: register char  **ap;
                   1383: {
                   1384:        register struct nlist   *np;
                   1385: 
                   1386:        trace = 0;
                   1387: 
                   1388:        while (c > 0)
                   1389:                if ((np=lookup(ap[c--]))->name)
                   1390:                        np->tflag = 0;
                   1391: }
                   1392: 
                   1393: dotron(ap,c)
                   1394: register char  **ap;
                   1395: {
                   1396:        register struct nlist   *np;
                   1397: 
                   1398:        trace = !*arg(1);
                   1399: 
                   1400:        while (c > 0)
                   1401:                if ((np=lookup(ap[c--]))->name)
                   1402:                        np->tflag = 1;
                   1403: }
                   1404: 
                   1405: doundef(ap,c)
                   1406: char   **ap;
                   1407: {
                   1408:        register        i;
                   1409: 
                   1410:        for (i=1; i<=c; ++i)
                   1411:                while (undef(ap[i]))
                   1412:                        ;
                   1413: }
                   1414: 
                   1415: undef(nam)
                   1416: char   *nam;
                   1417: {
                   1418:        register struct nlist *np, *tnp;
                   1419: 
                   1420:        if ((np=lookup(nam))->name==NULL)
                   1421:                return 0;
                   1422:        tnp = hshtab[hshval];   /* lookup sets hshval */
                   1423:        if (tnp==np)    /* it's in first place */
                   1424:                hshtab[hshval] = tnp->next;
                   1425:        else {
                   1426:                while (tnp->next != np)
                   1427:                        tnp = tnp->next;
                   1428: 
                   1429:                tnp->next = np->next;
                   1430:        }
                   1431:        cfree(np->name);
                   1432:        cfree(np->def);
                   1433:        cfree((char *)np);
                   1434:        return 1;
                   1435: }
                   1436: 
                   1437: doundiv(ap,c)
                   1438: register char  **ap;
                   1439: {
                   1440:        register int i;
                   1441: 
                   1442:        if (c<=0)
                   1443:                for (i=1; i<10; i++)
                   1444:                        undiv(i,OK);
                   1445:        else
                   1446:                while (--c >= 0)
                   1447:                        undiv(atoi(*++ap),OK);
                   1448: }
                   1449: 
                   1450: dowrap(ap,c)
                   1451: char   **ap;
                   1452: {
                   1453:        register char   *a = arg(1);
                   1454:        extern char *xcalloc();
                   1455: 
                   1456:        if (Wrapstr)
                   1457:                cfree(Wrapstr);
                   1458: 
                   1459:        Wrapstr = xcalloc(strlen(a)+1,sizeof(char));
                   1460:        strcpy(Wrapstr,a);
                   1461: }
                   1462: 
                   1463: struct bs      barray[] = {
                   1464:        dochcom,        "changecom",
                   1465:        docq,           "changequote",
                   1466:        dodecr,         "decr",
                   1467:        dodef,          "define",
                   1468:        dodefn,         "defn",
                   1469:        dodiv,          "divert",
                   1470:        dodivnum,       "divnum",
                   1471:        dodnl,          "dnl",
                   1472:        dodump,         "dumpdef",
                   1473:        doerrp,         "errprint",
                   1474:        doeval,         "eval",
                   1475:        doexit,         "m4exit",
                   1476:        doif,           "ifelse",
                   1477:        doifdef,        "ifdef",
                   1478:        doincl,         "include",
                   1479:        doincr,         "incr",
                   1480:        doindex,        "index",
                   1481:        dolen,          "len",
                   1482:        domake,         "maketemp",
                   1483:        dopopdef,       "popdef",
                   1484:        dopushdef,      "pushdef",
                   1485:        doshift,        "shift",
                   1486:        dosincl,        "sinclude",
                   1487:        dosubstr,       "substr",
                   1488:        dosyscmd,       "syscmd",
                   1489:        dosysval,       "sysval",
                   1490:        dotransl,       "translit",
                   1491:        dotroff,        "traceoff",
                   1492:        dotron,         "traceon",
                   1493:        doundef,        "undefine",
                   1494:        doundiv,        "undivert",
                   1495:        dowrap,         "m4wrap",
                   1496:        0,              0
                   1497: };
                   1498: //GO.SYSIN DD *
                   1499: echo unbundling y.tab.c 1>&2
                   1500: cat >y.tab.c <<'//GO.SYSIN DD *'
                   1501: 
                   1502: # line 2 "m4y.y"
                   1503: extern long    evalval;
                   1504: #define        YYSTYPE long
                   1505: # define DIGITS 257
                   1506: # define OROR 258
                   1507: # define ANDAND 259
                   1508: # define GT 260
                   1509: # define GE 261
                   1510: # define LT 262
                   1511: # define LE 263
                   1512: # define NE 264
                   1513: # define EQ 265
                   1514: # define POWER 266
                   1515: # define UMINUS 267
                   1516: #define yyclearin yychar = -1
                   1517: #define yyerrok yyerrflag = 0
                   1518: extern int yychar;
                   1519: extern short yyerrflag;
                   1520: #ifndef YYMAXDEPTH
                   1521: #define YYMAXDEPTH 150
                   1522: #endif
                   1523: #ifndef YYSTYPE
                   1524: #define YYSTYPE int
                   1525: #endif
                   1526: YYSTYPE yylval, yyval;
                   1527: # define YYERRCODE 256
                   1528: 
                   1529: # line 48 "m4y.y"
                   1530: 
                   1531: 
                   1532: extern char *pe;
                   1533: 
                   1534: yylex() {
                   1535: 
                   1536:        while (*pe==' ' || *pe=='\t' || *pe=='\n')
                   1537:                pe++;
                   1538:        switch(*pe) {
                   1539:        case '\0':
                   1540:        case '+':
                   1541:        case '-':
                   1542:        case '/':
                   1543:        case '%':
                   1544:        case '^':
                   1545:        case '~':
                   1546:        case '(':
                   1547:        case ')':
                   1548:                return(*pe++);
                   1549:        case '*':
                   1550:                return(peek('*', POWER, '*'));
                   1551:        case '>':
                   1552:                return(peek('=', GE, GT));
                   1553:        case '<':
                   1554:                return(peek('=', LE, LT));
                   1555:        case '=':
                   1556:                return(peek('=', EQ, EQ));
                   1557:        case '|':
                   1558:                return(peek('|', OROR, '|'));
                   1559:        case '&':
                   1560:                return(peek('&', ANDAND, '&'));
                   1561:        case '!':
                   1562:                return(peek('=', NE, '!'));
                   1563:        default: {
                   1564:                register        base;
                   1565: 
                   1566:                evalval = 0;
                   1567: 
                   1568:                if (*pe == '0') {
                   1569:                        if (*++pe=='x' || *pe=='X') {
                   1570:                                base = 16;
                   1571:                                ++pe;
                   1572:                        } else
                   1573:                                base = 8;
                   1574:                } else
                   1575:                        base = 10;
                   1576: 
                   1577:                for (;;) {
                   1578:                        register        c, dig;
                   1579: 
                   1580:                        c = *pe;
                   1581: 
                   1582:                        if (c>='0' && c<='9')
                   1583:                                dig = c - '0';
                   1584:                        else if (c>='a' && c<='f')
                   1585:                                dig = c - 'a' + 10;
                   1586:                        else if (c>='A' && c<='F')
                   1587:                                dig = c - 'A' + 10;
                   1588:                        else
                   1589:                                break;
                   1590: 
                   1591:                        evalval = evalval*base + dig;
                   1592:                        ++pe;
                   1593:                }
                   1594: 
                   1595:                return(DIGITS);
                   1596:        }
                   1597:        }
                   1598: }
                   1599: 
                   1600: peek(c, r1, r2)
                   1601: {
                   1602:        if (*++pe != c)
                   1603:                return(r2);
                   1604:        ++pe;
                   1605:        return(r1);
                   1606: }
                   1607: 
                   1608: yyerror() {;}
                   1609: short yyexca[] ={
                   1610: -1, 1,
                   1611:        0, -1,
                   1612:        -2, 0,
                   1613: -1, 33,
                   1614:        260, 0,
                   1615:        261, 0,
                   1616:        262, 0,
                   1617:        263, 0,
                   1618:        264, 0,
                   1619:        265, 0,
                   1620:        -2, 7,
                   1621: -1, 34,
                   1622:        260, 0,
                   1623:        261, 0,
                   1624:        262, 0,
                   1625:        263, 0,
                   1626:        264, 0,
                   1627:        265, 0,
                   1628:        -2, 8,
                   1629: -1, 35,
                   1630:        260, 0,
                   1631:        261, 0,
                   1632:        262, 0,
                   1633:        263, 0,
                   1634:        264, 0,
                   1635:        265, 0,
                   1636:        -2, 9,
                   1637: -1, 36,
                   1638:        260, 0,
                   1639:        261, 0,
                   1640:        262, 0,
                   1641:        263, 0,
                   1642:        264, 0,
                   1643:        265, 0,
                   1644:        -2, 10,
                   1645: -1, 37,
                   1646:        260, 0,
                   1647:        261, 0,
                   1648:        262, 0,
                   1649:        263, 0,
                   1650:        264, 0,
                   1651:        265, 0,
                   1652:        -2, 11,
                   1653: -1, 38,
                   1654:        260, 0,
                   1655:        261, 0,
                   1656:        262, 0,
                   1657:        263, 0,
                   1658:        264, 0,
                   1659:        265, 0,
                   1660:        -2, 12,
                   1661:        };
                   1662: # define YYNPROD 26
                   1663: # define YYLAST 294
                   1664: short yyact[]={
                   1665: 
                   1666:   24,  18,  25,   1,  48,  22,  20,   0,  21,   0,
                   1667:   23,  24,  18,   0,   0,   0,  22,  20,   0,  21,
                   1668:    0,  23,  24,  18,   0,   0,  24,  22,  20,   0,
                   1669:   21,  22,  23,  24,  18,   0,  23,   0,  22,  20,
                   1670:    0,  21,   0,  23,  24,  18,   0,   0,   0,  22,
                   1671:   20,   0,  21,  24,  23,   0,   0,  19,  22,  20,
                   1672:    0,  21,   0,  23,  24,   0,   3,   0,  19,  22,
                   1673:   20,   0,  21,   5,  23,   0,   7,   0,   6,  19,
                   1674:    0,   0,   0,   0,   0,   0,   0,  17,   0,   0,
                   1675:   19,   0,   0,   0,   0,   0,   0,   0,  17,   0,
                   1676:    0,   0,   0,   0,   0,   0,   0,   0,   0,  17,
                   1677:    0,   2,   0,   0,   0,  26,  27,  28,  29,  30,
                   1678:   17,  31,  32,  33,  34,  35,  36,  37,  38,  39,
                   1679:   40,  41,  42,  43,  44,  45,  46,  47,   0,   0,
                   1680:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1681:    0,   0,   0,   0,   0,   0,   0,   0,   0,   4,
                   1682:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1683:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1684:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1685:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1686:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1687:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1688:    0,   9,  10,  13,  14,  15,  16,  12,  11,  25,
                   1689:    0,   0,   9,  10,  13,  14,  15,  16,  12,  11,
                   1690:   25,   0,   0,   0,  10,  13,  14,  15,  16,  12,
                   1691:   11,  25,   0,   0,   0,  25,  13,  14,  15,  16,
                   1692:   12,  11,  25,   0,   0,   0,   0,  13,  14,  15,
                   1693:   16,  12,  11,  25,   0,   0,  13,  14,  15,  16,
                   1694:   12,  11,  25,   0,   0,   0,   0,   0,   0,   0,
                   1695:    8,   0,   0,  25 };
                   1696: short yypact[]={
                   1697: 
                   1698:   33,-1000, -26,  33,  33,  33,  33,  33,-1000,  33,
                   1699:   33,  33,  33,  33,  33,  33,  33,  33,  33,  33,
                   1700:   33,  33,  33,  33,  33,  33,  16,  16, -37,-1000,
                   1701: -1000, -15,  -4,  27,  27,  27,  27,  27,  27,   7,
                   1702:   16,   7, -11, -11,-264,-264,-264,-264,-1000 };
                   1703: short yypgo[]={
                   1704: 
                   1705:    0,   3, 111 };
                   1706: short yyr1[]={
                   1707: 
                   1708:    0,   1,   1,   2,   2,   2,   2,   2,   2,   2,
                   1709:    2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
                   1710:    2,   2,   2,   2,   2,   2 };
                   1711: short yyr2[]={
                   1712: 
                   1713:    0,   1,   0,   3,   3,   2,   2,   3,   3,   3,
                   1714:    3,   3,   3,   3,   3,   3,   3,   3,   3,   3,
                   1715:    3,   3,   3,   2,   2,   1 };
                   1716: short yychk[]={
                   1717: 
                   1718: -1000,  -1,  -2,  33, 126,  40,  45,  43, 257, 258,
                   1719:  259, 265, 264, 260, 261, 262, 263, 124,  38,  94,
                   1720:   43,  45,  42,  47,  37, 266,  -2,  -2,  -2,  -2,
                   1721:   -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,
                   1722:   -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  41 };
                   1723: short yydef[]={
                   1724: 
                   1725:    2,  -2,   1,   0,   0,   0,   0,   0,  25,   0,
                   1726:    0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
                   1727:    0,   0,   0,   0,   0,   0,   5,   6,   0,  23,
                   1728:   24,   3,   4,  -2,  -2,  -2,  -2,  -2,  -2,  13,
                   1729:   14,  15,  16,  17,  18,  19,  20,  22,  21 };
                   1730: # ifdef YYDEBUG
                   1731: # include "y.debug"
                   1732: # endif
                   1733: 
                   1734: # define YYFLAG -1000
                   1735: # define YYERROR goto yyerrlab
                   1736: # define YYACCEPT return(0)
                   1737: # define YYABORT return(1)
                   1738: 
                   1739: /*     parser for yacc output  */
                   1740: 
                   1741: #ifdef YYDEBUG
                   1742: int yydebug = 0; /* 1 for debugging */
                   1743: #endif
                   1744: YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
                   1745: int yychar = -1; /* current input token number */
                   1746: int yynerrs = 0;  /* number of errors */
                   1747: short yyerrflag = 0;  /* error recovery flag */
                   1748: 
                   1749: yyparse()
                   1750: {      short yys[YYMAXDEPTH];
                   1751:        int yyj, yym;
                   1752:        register YYSTYPE *yypvt;
                   1753:        register int yystate, yyn;
                   1754:        register short *yyps;
                   1755:        register YYSTYPE *yypv;
                   1756:        register short *yyxi;
                   1757: 
                   1758:        yystate = 0;
                   1759:        yychar = -1;
                   1760:        yynerrs = 0;
                   1761:        yyerrflag = 0;
                   1762:        yyps= &yys[-1];
                   1763:        yypv= &yyv[-1];
                   1764: 
                   1765: yystack:    /* put a state and value onto the stack */
                   1766: #ifdef YYDEBUG
                   1767:        if(yydebug >= 3)
                   1768:                if(yychar < 0 || yytoknames[yychar] == 0)
                   1769:                        printf("char %d in %s", yychar, yystates[yystate]);
                   1770:                else
                   1771:                        printf("%s in %s", yytoknames[yychar], yystates[yystate]);
                   1772: #endif
                   1773:        if( ++yyps >= &yys[YYMAXDEPTH] ) { 
                   1774:                yyerror( "yacc stack overflow" ); 
                   1775:                return(1); 
                   1776:        }
                   1777:        *yyps = yystate;
                   1778:        ++yypv;
                   1779:        *yypv = yyval;
                   1780: yynewstate:
                   1781:        yyn = yypact[yystate];
                   1782:        if(yyn <= YYFLAG) goto yydefault; /* simple state */
                   1783:        if(yychar<0) {
                   1784:                yychar = yylex();
                   1785: #ifdef YYDEBUG
                   1786:                if(yydebug >= 2) {
                   1787:                        if(yychar <= 0)
                   1788:                                printf("lex EOF\n");
                   1789:                        else if(yytoknames[yychar])
                   1790:                                printf("lex %s\n", yytoknames[yychar]);
                   1791:                        else
                   1792:                                printf("lex (%c)\n", yychar);
                   1793:                }
                   1794: #endif
                   1795:                if(yychar < 0)
                   1796:                        yychar = 0;
                   1797:        }
                   1798:        if((yyn += yychar) < 0 || yyn >= YYLAST)
                   1799:                goto yydefault;
                   1800:        if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */
                   1801:                yychar = -1;
                   1802:                yyval = yylval;
                   1803:                yystate = yyn;
                   1804:                if( yyerrflag > 0 ) --yyerrflag;
                   1805:                goto yystack;
                   1806:        }
                   1807: yydefault:
                   1808:        /* default state action */
                   1809:        if( (yyn=yydef[yystate]) == -2 ) {
                   1810:                if(yychar < 0) {
                   1811:                        yychar = yylex();
                   1812: #ifdef YYDEBUG
                   1813:                        if(yydebug >= 2)
                   1814:                                if(yychar < 0)
                   1815:                                        printf("lex EOF\n");
                   1816:                                else
                   1817:                                        printf("lex %s\n", yytoknames[yychar]);
                   1818: #endif
                   1819:                        if(yychar < 0)
                   1820:                                yychar = 0;
                   1821:                }
                   1822:                /* look through exception table */
                   1823:                for(yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate);
                   1824:                        yyxi += 2 ) ; /* VOID */
                   1825:                while( *(yyxi+=2) >= 0 ){
                   1826:                        if( *yyxi == yychar ) break;
                   1827:                }
                   1828:                if( (yyn = yyxi[1]) < 0 ) return(0);   /* accept */
                   1829:        }
                   1830:        if( yyn == 0 ){ /* error */
                   1831:                /* error ... attempt to resume parsing */
                   1832:                switch( yyerrflag ){
                   1833:                case 0:   /* brand new error */
                   1834: #ifdef YYDEBUG
                   1835:                        yyerror("syntax error\n%s", yystates[yystate]);
                   1836:                        if(yytoknames[yychar])
                   1837:                                yyerror("saw %s\n", yytoknames[yychar]);
                   1838:                        else if(yychar >= ' ' && yychar < '\177')
                   1839:                                yyerror("saw `%c'\n", yychar);
                   1840:                        else if(yychar == 0)
                   1841:                                yyerror("saw EOF\n");
                   1842:                        else
                   1843:                                yyerror("saw char 0%o\n", yychar);
                   1844: #else
                   1845:                        yyerror( "syntax error" );
                   1846: #endif
                   1847: yyerrlab:
                   1848:                        ++yynerrs;
                   1849:                case 1:
                   1850:                case 2: /* incompletely recovered error ... try again */
                   1851:                        yyerrflag = 3;
                   1852:                        /* find a state where "error" is a legal shift action */
                   1853:                        while ( yyps >= yys ) {
                   1854:                                yyn = yypact[*yyps] + YYERRCODE;
                   1855:                                if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){
                   1856:                                        yystate = yyact[yyn];  /* simulate a shift of "error" */
                   1857:                                        goto yystack;
                   1858:                                }
                   1859:                                yyn = yypact[*yyps];
                   1860:                                /* the current yyps has no shift onn "error", pop stack */
                   1861: #ifdef YYDEBUG
                   1862:                                if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );
                   1863: #endif
                   1864:                                --yyps;
                   1865:                                --yypv;
                   1866:                        }
                   1867:                        /* there is no state on the stack with an error shift ... abort */
                   1868: yyabort:
                   1869:                        return(1);
                   1870:                case 3:  /* no shift yet; clobber input char */
                   1871: #ifdef YYDEBUG
                   1872:                        if( yydebug ) {
                   1873:                                printf("error recovery discards ");
                   1874:                                if(yytoknames[yychar])
                   1875:                                        printf("%s\n", yytoknames[yychar]);
                   1876:                                else if(yychar >= ' ' && yychar < '\177')
                   1877:                                        printf("`%c'\n", yychar);
                   1878:                                else if(yychar == 0)
                   1879:                                        printf("EOF\n");
                   1880:                                else
                   1881:                                        printf("char 0%o\n", yychar);
                   1882:                        }
                   1883: #endif
                   1884:                        if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
                   1885:                        yychar = -1;
                   1886:                        goto yynewstate;   /* try again in the same state */
                   1887:                }
                   1888:        }
                   1889:        /* reduction by production yyn */
                   1890: #ifdef YYDEBUG
                   1891:        if(yydebug) {   char *s;
                   1892:                printf("reduce %d in:\n\t", yyn);
                   1893:                for(s = yystates[yystate]; *s; s++) {
                   1894:                        putchar(*s);
                   1895:                        if(*s == '\n' && *(s+1))
                   1896:                                putchar('\t');
                   1897:                }
                   1898:        }
                   1899: #endif
                   1900:        yyps -= yyr2[yyn];
                   1901:        yypvt = yypv;
                   1902:        yypv -= yyr2[yyn];
                   1903:        yyval = yypv[1];
                   1904:        yym=yyn;
                   1905:        /* consult goto table to find next state */
                   1906:        yyn = yyr1[yyn];
                   1907:        yyj = yypgo[yyn] + *yyps + 1;
                   1908:        if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];
                   1909:        switch(yym){
                   1910:                
                   1911: case 1:
                   1912: # line 19 "m4y.y"
                   1913: { evalval = yypvt[-0]; } break;
                   1914: case 2:
                   1915: # line 20 "m4y.y"
                   1916: { evalval = 0; } break;
                   1917: case 3:
                   1918: # line 23 "m4y.y"
                   1919: { yyval = (yypvt[-2]!=0 || yypvt[-0]!=0) ? 1 : 0; } break;
                   1920: case 4:
                   1921: # line 24 "m4y.y"
                   1922: { yyval = (yypvt[-2]!=0 && yypvt[-0]!=0) ? 1 : 0; } break;
                   1923: case 5:
                   1924: # line 25 "m4y.y"
                   1925: { yyval = yypvt[-0] == 0; } break;
                   1926: case 6:
                   1927: # line 26 "m4y.y"
                   1928: { yyval = ~yypvt[-0]; } break;
                   1929: case 7:
                   1930: # line 27 "m4y.y"
                   1931: { yyval = yypvt[-2] == yypvt[-0]; } break;
                   1932: case 8:
                   1933: # line 28 "m4y.y"
                   1934: { yyval = yypvt[-2] != yypvt[-0]; } break;
                   1935: case 9:
                   1936: # line 29 "m4y.y"
                   1937: { yyval = yypvt[-2] > yypvt[-0]; } break;
                   1938: case 10:
                   1939: # line 30 "m4y.y"
                   1940: { yyval = yypvt[-2] >= yypvt[-0]; } break;
                   1941: case 11:
                   1942: # line 31 "m4y.y"
                   1943: { yyval = yypvt[-2] < yypvt[-0]; } break;
                   1944: case 12:
                   1945: # line 32 "m4y.y"
                   1946: { yyval = yypvt[-2] <= yypvt[-0]; } break;
                   1947: case 13:
                   1948: # line 33 "m4y.y"
                   1949: { yyval = (yypvt[-2]|yypvt[-0]); } break;
                   1950: case 14:
                   1951: # line 34 "m4y.y"
                   1952: { yyval = (yypvt[-2]&yypvt[-0]); } break;
                   1953: case 15:
                   1954: # line 35 "m4y.y"
                   1955: { yyval = (yypvt[-2]^yypvt[-0]); } break;
                   1956: case 16:
                   1957: # line 36 "m4y.y"
                   1958: { yyval = (yypvt[-2]+yypvt[-0]); } break;
                   1959: case 17:
                   1960: # line 37 "m4y.y"
                   1961: { yyval = (yypvt[-2]-yypvt[-0]); } break;
                   1962: case 18:
                   1963: # line 38 "m4y.y"
                   1964: { yyval = (yypvt[-2]*yypvt[-0]); } break;
                   1965: case 19:
                   1966: # line 39 "m4y.y"
                   1967: { yyval = (yypvt[-2]/yypvt[-0]); } break;
                   1968: case 20:
                   1969: # line 40 "m4y.y"
                   1970: { yyval = (yypvt[-2]%yypvt[-0]); } break;
                   1971: case 21:
                   1972: # line 41 "m4y.y"
                   1973: { yyval = (yypvt[-1]); } break;
                   1974: case 22:
                   1975: # line 42 "m4y.y"
                   1976: { for (yyval=1; yypvt[-0]-->0; yyval *= yypvt[-2]); } break;
                   1977: case 23:
                   1978: # line 43 "m4y.y"
                   1979: { yyval = yypvt[-0]-1; yyval = -yypvt[-0]; } break;
                   1980: case 24:
                   1981: # line 44 "m4y.y"
                   1982: { yyval = yypvt[-0]-1; yyval = yypvt[-0]; } break;
                   1983: case 25:
                   1984: # line 45 "m4y.y"
                   1985: { yyval = evalval; } break;
                   1986:        }
                   1987:        goto yystack;  /* stack new state and value */
                   1988: }
                   1989: //GO.SYSIN DD *

unix.superglobalmegacorp.com

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