Annotation of researchv10dc/cmd/m4/m4.c, revision 1.1.1.1

1.1       root        1: #include       <stdio.h>
                      2: #include       <signal.h>
                      3: #include       "m4.h"
                      4: 
                      5: #define match(c,s)     (c==*s && (!s[1] || inpmatch(s+1)))
                      6: 
                      7: char   *xcalloc();
                      8: 
                      9: 
                     10: main(argc,argv)
                     11: char   **argv;
                     12: {
                     13:        register t;
                     14: 
                     15:        {
                     16:        static  sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0};
                     17:        for (t=0; sigs[t]; ++t)
                     18:                if (signal(sigs[t], SIG_IGN) != SIG_IGN)
                     19:                        signal(sigs[t],catchsig);
                     20:        }
                     21: 
                     22:        tempname = mktemp("/tmp/m4aXXXXXX");
                     23:        close(creat(tempname,0));
                     24: 
                     25:        procnam = argv[0];
                     26:        getflags(&argc,&argv);
                     27:        initalloc();
                     28: 
                     29:        setfname("-");
                     30:        if (argc>1) {
                     31:                --argc;
                     32:                ++argv;
                     33:                if (strcmp(argv[0],"-")) {
                     34:                        ifile[ifx] = xfopen(argv[0],"r");
                     35:                        setfname(argv[0]);
                     36:                }
                     37:        }
                     38: 
                     39:        for (;;) {
                     40:                token[0] = t = getchr();
                     41:                token[1] = EOS;
                     42: 
                     43:                if (t==EOF) {
                     44:                        if (ifx > 0) {
                     45:                                fclose(ifile[ifx]);
                     46:                                ipflr = ipstk[--ifx];
                     47:                                continue;
                     48:                        }
                     49: 
                     50:                        getflags(&argc,&argv);
                     51: 
                     52:                        if (argc<=1)
                     53:                                if (Wrapstr) {
                     54:                                        pbstr(Wrapstr);
                     55:                                        Wrapstr = NULL;
                     56:                                        continue;
                     57:                                } else
                     58:                                        break;
                     59: 
                     60:                        --argc;
                     61:                        ++argv;
                     62: 
                     63:                        if (ifile[ifx]!=stdin)
                     64:                                fclose(ifile[ifx]);
                     65: 
                     66:                        if (*argv[0]=='-')
                     67:                                ifile[ifx] = stdin;
                     68:                        else
                     69:                                ifile[ifx] = xfopen(argv[0],"r");
                     70: 
                     71:                        setfname(argv[0]);
                     72:                        continue;
                     73:                }
                     74: 
                     75:                if (isalpha(t)) {
                     76:                        register char   *tp = token+1;
                     77:                        register        tlim = toksize;
                     78: 
                     79:                        while (alphanum(*tp++=getchr()))
                     80:                                if (--tlim<=0)
                     81:                                        error2("more than %d chars in word",
                     82:                                                        toksize);
                     83: 
                     84:                        putbak(*--tp);
                     85:                        *tp = EOS;
                     86: 
                     87:                        if (((struct nlist *)(*((struct nlist **)Ap)=lookup(token)))->def) {
                     88:                                if (++Ap >= astklm) {
                     89:                                        --Ap;
                     90:                                        error2(astkof,stksize);
                     91:                                }
                     92: 
                     93:                                if (Cp++==NULL)
                     94:                                        Cp = callst;
                     95: 
                     96:                                Cp->argp = Ap;
                     97:                                *Ap++ = op;
                     98:                                puttok(token);
                     99:                                stkchr(EOS);
                    100:                                t = getchr();
                    101:                                putbak(t);
                    102: 
                    103:                                if (t!='(')
                    104:                                        pbstr("()");
                    105:                                else    /* try to fix arg count */
                    106:                                        *Ap++ = op;
                    107: 
                    108:                                Cp->plev = 0;
                    109:                        } else {
                    110:                                puttok(token);
                    111:                        }
                    112:                } else if (match(t,lquote)) {
                    113:                        register        qlev = 1;
                    114: 
                    115:                        for (;;) {
                    116:                                token[0] = t = getchr();
                    117:                                token[1] = EOS;
                    118: 
                    119:                                if (match(t,rquote)) {
                    120:                                        if (--qlev > 0)
                    121:                                                puttok(token);
                    122:                                        else
                    123:                                                break;
                    124:                                } else if (match(t,lquote)) {
                    125:                                        ++qlev;
                    126:                                        puttok(token);
                    127:                                } else {
                    128:                                        if (t==EOF)
                    129:                                                error("EOF in quote");
                    130: 
                    131:                                        putchr(t);
                    132:                                }
                    133:                        }
                    134:                } else if (match(t,lcom)) {
                    135:                        puttok(token);
                    136: 
                    137:                        for (;;) {
                    138:                                token[0] = t = getchr();
                    139:                                token[1] = EOS;
                    140: 
                    141:                                if (match(t,rcom)) {
                    142:                                        puttok(token);
                    143:                                        break;
                    144:                                } else {
                    145:                                        if (t==EOF)
                    146:                                                error("EOF in comment");
                    147:                                        putchr(t);
                    148:                                }
                    149:                        }
                    150:                } else if (Cp==NULL) {
                    151:                        putchr(t);
                    152:                } else if (t=='(') {
                    153:                        if (Cp->plev)
                    154:                                stkchr(t);
                    155:                        else {
                    156:                                /* skip white before arg */
                    157:                                while (isspace(t=getchr()))
                    158:                                        ;
                    159: 
                    160:                                putbak(t);
                    161:                        }
                    162: 
                    163:                        ++Cp->plev;
                    164:                } else if (t==')') {
                    165:                        --Cp->plev;
                    166: 
                    167:                        if (Cp->plev==0) {
                    168:                                stkchr(EOS);
                    169:                                expand(Cp->argp,Ap-Cp->argp-1);
                    170:                                op = *Cp->argp;
                    171:                                Ap = Cp->argp-1;
                    172: 
                    173:                                if (--Cp < callst)
                    174:                                        Cp = NULL;
                    175:                        } else
                    176:                                stkchr(t);
                    177:                } else if (t==',' && Cp->plev<=1) {
                    178:                        stkchr(EOS);
                    179:                        *Ap = op;
                    180: 
                    181:                        if (++Ap >= astklm) {
                    182:                                --Ap;
                    183:                                error2(astkof,stksize);
                    184:                        }
                    185: 
                    186:                        while (isspace(t=getchr()))
                    187:                                ;
                    188: 
                    189:                        putbak(t);
                    190:                } else
                    191:                        stkchr(t);
                    192:        }
                    193: 
                    194:        if (Cp!=NULL)
                    195:                error("EOF in argument list");
                    196: 
                    197:        delexit(OK);
                    198: }
                    199: 
                    200: char *
                    201: inpmatch(s)
                    202: register char  *s;
                    203: {
                    204:        register char   *tp = token+1;
                    205: 
                    206:        while (*s) {
                    207:                *tp = getchr();
                    208: 
                    209:                if (*tp++ != *s++) {
                    210:                        *tp = EOS;
                    211:                        pbstr(token+1);
                    212:                        return 0;
                    213:                }
                    214:        }
                    215: 
                    216:        *tp = EOS;
                    217:        return token;
                    218: }
                    219: 
                    220: getflags(xargc,xargv)
                    221: register int   *xargc;
                    222: register char  ***xargv;
                    223: {
                    224:        while (*xargc > 1) {
                    225:                register char   *arg = (*xargv)[1];
                    226: 
                    227:                if (arg[0]!='-' || arg[1]==EOS)
                    228:                        break;
                    229: 
                    230:                switch (arg[1]) {
                    231:                case 'B':
                    232:                        bufsize = atoi(&arg[2]);
                    233:                        break;
                    234:                case 'D':
                    235:                        {
                    236:                        register char *t;
                    237:                        char *s[2];
                    238: 
                    239:                        initalloc();
                    240: 
                    241:                        for (t = s[0] = &arg[2]; *t; t++)
                    242:                                if (*t=='=') {
                    243:                                        *t++ = EOS;
                    244:                                        break;
                    245:                                }
                    246: 
                    247:                        s[1] = t;
                    248:                        dodef(&s[-1],2);
                    249:                        break;
                    250:                        }
                    251:                case 'H':
                    252:                        hshsize = atoi(&arg[2]);
                    253:                        break;
                    254:                case 'S':
                    255:                        stksize = atoi(&arg[2]);
                    256:                        break;
                    257:                case 'T':
                    258:                        toksize = atoi(&arg[2]);
                    259:                        break;
                    260:                case 'U':
                    261:                        {
                    262:                        char *s[1];
                    263: 
                    264:                        initalloc();
                    265:                        s[0] = &arg[2];
                    266:                        doundef(&s[-1],1);
                    267:                        break;
                    268:                        }
                    269:                case 'e':
                    270:                        setbuf(stdout,NULL);
                    271:                        signal(SIGINT,SIG_IGN);
                    272:                        break;
                    273:                case 's':
                    274:                        /* turn on line sync */
                    275:                        sflag = 1;
                    276:                        break;
                    277:                default:
                    278:                        fprintf(stderr,"%s: bad option: %s\n",
                    279:                                procnam,arg);
                    280:                        delexit(NOT_OK);
                    281:                }
                    282: 
                    283:                (*xargv)++;
                    284:                --(*xargc);
                    285:        }
                    286: 
                    287:        return;
                    288: }
                    289: 
                    290: initalloc()
                    291: {
                    292:        static  done = 0;
                    293:        register        t;
                    294: 
                    295:        if (done++)
                    296:                return;
                    297: 
                    298:        hshtab = (struct nlist **)xcalloc(hshsize,sizeof(struct nlist *));
                    299:        callst = (struct call *)xcalloc(stksize/3+1,sizeof(struct call));
                    300:        Ap = argstk = (char **)xcalloc(stksize+3,sizeof(char *));
                    301:        ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1,sizeof(char));
                    302:        op = obuf = xcalloc(bufsize+1,sizeof(char));
                    303:        token = xcalloc(toksize+1,sizeof(char));
                    304: 
                    305:        astklm = &argstk[stksize];
                    306:        ibuflm = &ibuf[bufsize];
                    307:        obuflm = &obuf[bufsize];
                    308:        toklm = &token[toksize];
                    309: 
                    310:        for (t=0; barray[t].bname; ++t) {
                    311:                static char     p[2] = {0, EOS};
                    312: 
                    313:                p[0] = t|~LOW7;
                    314:                install(barray[t].bname,p,NOPUSH);
                    315:        }
                    316: 
                    317:        install("unix",nullstr,NOPUSH);
                    318: }
                    319: 
                    320: /*struct nlist * */
                    321: install(nam,val,mode)
                    322: char   *nam;
                    323: register char  *val;
                    324: {
                    325:        register struct nlist *np;
                    326:        register char   *cp;
                    327:        int             l;
                    328: 
                    329:        if (mode==PUSH)
                    330:                lookup(nam);    /* lookup sets hshval */
                    331:        else
                    332:                while (undef(nam))      /* undef calls lookup */
                    333:                        ;
                    334: 
                    335:        np = (struct nlist *)xcalloc(1,sizeof(*np));
                    336:        np->name = copy(nam);
                    337:        np->next = hshtab[hshval];
                    338:        hshtab[hshval] = np;
                    339: 
                    340:        cp = xcalloc((l=strlen(val))+1,sizeof(*val));
                    341:        np->def = cp;
                    342:        cp = &cp[l];
                    343: 
                    344:        while (*val)
                    345:                *--cp = *val++;
                    346: }
                    347: 
                    348: struct nlist   *
                    349: lookup(str)
                    350: char   *str;
                    351: {
                    352:        register char           *s1, *s2;
                    353:        register struct nlist   *np;
                    354:        static struct nlist     nodef;
                    355: 
                    356:        s1 = str;
                    357: 
                    358:        for (hshval = 0; *s1; )
                    359:                hshval += *s1++;
                    360: 
                    361:        hshval %= hshsize;
                    362: 
                    363:        for (np = hshtab[hshval]; np!=NULL; np = np->next) {
                    364:                s1 = str;
                    365:                s2 = np->name;
                    366:                while (*s1++==*s2)
                    367:                        if (*s2++==EOS)
                    368:                                return(np);
                    369:        }
                    370: 
                    371:        return(&nodef);
                    372: }
                    373: 
                    374: expand(a1,c)
                    375: char   **a1;
                    376: {
                    377:        register char   *dp;
                    378:        register struct nlist   *sp;
                    379: 
                    380:        sp = (struct nlist *)a1[-1];
                    381: 
                    382:        if (sp->tflag || trace) {
                    383:                int     i;
                    384: 
                    385:                fprintf(stderr,"Trace(%d): %s",Cp-callst,a1[0]);
                    386: 
                    387:                if (c > 0) {
                    388:                        fprintf(stderr,"(%s",chkbltin(a1[1]));
                    389:                        for (i=2; i<=c; ++i)
                    390:                                fprintf(stderr,",%s",chkbltin(a1[i]));
                    391:                        fprintf(stderr,")");
                    392:                }
                    393: 
                    394:                fprintf(stderr,"\n");
                    395:        }
                    396: 
                    397:        dp = sp->def;
                    398: 
                    399:        for (; *dp; ++dp) {
                    400:                if (*dp&~LOW7) {
                    401:                        (*barray[*dp&LOW7].bfunc)(a1,c);
                    402:                } else if (dp[1]=='$') {
                    403:                        if (isdigit(*dp)) {
                    404:                                register        n;
                    405:                                if ((n = *dp-'0') <= c)
                    406:                                        pbstr(a1[n]);
                    407:                                ++dp;
                    408:                        } else if (*dp=='#') {
                    409:                                pbnum((long) c);
                    410:                                ++dp;
                    411:                        } else if (*dp=='*' || *dp=='@') {
                    412:                                register i = c;
                    413:                                char **a = a1;
                    414: 
                    415:                                if (i > 0)
                    416:                                        for (;;) {
                    417:                                                if (*dp=='@')
                    418:                                                        pbstr(rquote);
                    419: 
                    420:                                                pbstr(a[i--]);
                    421: 
                    422:                                                if (*dp=='@')
                    423:                                                        pbstr(lquote);
                    424: 
                    425:                                                if (i <= 0)
                    426:                                                        break;
                    427: 
                    428:                                                pbstr(",");
                    429:                                        }
                    430:                                ++dp;
                    431:                        } else
                    432:                                putbak(*dp);
                    433:                } else
                    434:                        putbak(*dp);
                    435:        }
                    436: }
                    437: 
                    438: setfname(s)
                    439: register char  *s;
                    440: {
                    441:        strcpy(fname[ifx],s);
                    442:        fname[ifx+1] = fname[ifx]+strlen(s)+1;
                    443:        fline[ifx] = 1;
                    444:        nflag = 1;
                    445:        lnsync(stdout);
                    446: }
                    447: 
                    448: lnsync(iop)
                    449: register FILE  *iop;
                    450: {
                    451:        static int cline = 0;
                    452:        static int cfile = 0;
                    453: 
                    454:        if (!sflag || iop!=stdout)
                    455:                return;
                    456: 
                    457:        if (nflag || ifx!=cfile) {
                    458:                nflag = 0;
                    459:                cfile = ifx;
                    460:                fprintf(iop,"#line %d \"",cline = fline[ifx]);
                    461:                fpath(iop);
                    462:                fprintf(iop,"\"\n");
                    463:        } else if (++cline != fline[ifx])
                    464:                fprintf(iop,"#line %d\n",cline = fline[ifx]);
                    465: }
                    466: 
                    467: fpath(iop)
                    468: register FILE  *iop;
                    469: {
                    470:        register        i;
                    471: 
                    472:        fprintf(iop,"%s",fname[0]);
                    473: 
                    474:        for (i=1; i<=ifx; ++i)
                    475:                fprintf(iop,":%s",fname[i]);
                    476: }
                    477: 
                    478: catchsig()
                    479: {
                    480:        signal(SIGHUP,SIG_IGN);
                    481:        signal(SIGINT,SIG_IGN);
                    482: 
                    483:        delexit(NOT_OK);
                    484: }
                    485: 
                    486: delexit(code)
                    487: {
                    488:        register i;
                    489: 
                    490:        cf = stdout;
                    491: 
                    492: /*     if (ofx != 0) { /* quitting in middle of diversion */
                    493: /*             ofx = 0;
                    494: /*             code = NOT_OK;
                    495: /*     }
                    496: */
                    497:        ofx = 0;        /* ensure that everything comes out */
                    498:        for (i=1; i<10; i++)
                    499:                undiv(i,code);
                    500: 
                    501:        tempname[7] = 'a';
                    502:        unlink(tempname);
                    503: 
                    504:        if (code==OK)
                    505:                exit(code);
                    506: 
                    507:        _exit(code);
                    508: }
                    509: 
                    510: puttok(tp)
                    511: register char *tp;
                    512: {
                    513:        if (Cp) {
                    514:                while (*tp)
                    515:                        stkchr(*tp++);
                    516:        } else if (cf)
                    517:                while (*tp)
                    518:                        sputchr(*tp++,cf);
                    519: }
                    520: 
                    521: pbstr(str)
                    522: register char *str;
                    523: {
                    524:        register char *p;
                    525: 
                    526:        p = str;
                    527: 
                    528:        while (*p++)
                    529:                ;
                    530: 
                    531:        --p;
                    532: 
                    533:        while (p > str)
                    534:                putbak(*--p);
                    535: }
                    536: 
                    537: undiv(i,code)
                    538: register       i;
                    539: {
                    540:        register FILE *fp;
                    541:        register        c;
                    542: 
                    543:        if (i<1 || i>9 || i==ofx || !ofile[i])
                    544:                return;
                    545: 
                    546:        fclose(ofile[i]);
                    547:        tempname[7] = 'a'+i;
                    548: 
                    549:        if (code==OK && cf) {
                    550:                fp = xfopen(tempname,"r");
                    551: 
                    552:                while ((c=getc(fp)) != EOF)
                    553:                        sputchr(c,cf);
                    554: 
                    555:                fclose(fp);
                    556:        }
                    557: 
                    558:        unlink(tempname);
                    559:        ofile[i] = NULL;
                    560: }
                    561: 
                    562: char   *copy(s)
                    563: register char *s;
                    564: {
                    565:        register char *p, *s1;
                    566: 
                    567:        p = s1 = xcalloc(strlen(s)+1,1);
                    568: 
                    569:        while (*s1++ = *s++)
                    570:                ;
                    571: 
                    572:        return(p);
                    573: }
                    574: 
                    575: pbnum(num)
                    576: long num;
                    577: {
                    578:        pbnbr(num,10,1);
                    579: }
                    580: 
                    581: pbnbr(nbr,base,len)
                    582: long   nbr;
                    583: register       base, len;
                    584: {
                    585:        register        neg = 0;
                    586: 
                    587:        if (base<=0)
                    588:                return;
                    589: 
                    590:        if (nbr<0) {
                    591:                neg = 1;
                    592:                nbr = -nbr;
                    593:        }
                    594: 
                    595:        while (nbr>0) {
                    596:                int     i;
                    597:                if (base>1) {
                    598:                        i = nbr%base;
                    599:                        nbr /= base;
                    600:                } else {
                    601:                        i = 1;
                    602:                        --nbr;
                    603:                }
                    604:                putbak(itochr(i));
                    605:                --len;
                    606:        }
                    607: 
                    608:        while (--len >= 0)
                    609:                putbak('0');
                    610: 
                    611:        if (neg)
                    612:                putbak('-');
                    613: }
                    614: 
                    615: itochr(i)
                    616: register       i;
                    617: {
                    618:        if (i>9)
                    619:                return i-10+'A';
                    620:        else
                    621:                return i+'0';
                    622: }
                    623: 
                    624: long ctol(str)
                    625: register char *str;
                    626: {
                    627:        register sign;
                    628:        long num;
                    629: 
                    630:        while (isspace(*str))
                    631:                ++str;
                    632:        num = 0;
                    633:        if (*str=='-') {
                    634:                sign = -1;
                    635:                ++str;
                    636:        }
                    637:        else
                    638:                sign = 1;
                    639:        while (isdigit(*str))
                    640:                num = num*10 + *str++ - '0';
                    641:        return(sign * num);
                    642: }
                    643: 
                    644: min(a,b)
                    645: {
                    646:        if (a>b)
                    647:                return(b);
                    648:        return(a);
                    649: }
                    650: 
                    651: FILE   *
                    652: xfopen(name,mode)
                    653: char   *name,
                    654:        *mode;
                    655: {
                    656:        FILE    *fp;
                    657: 
                    658:        if ((fp=fopen(name,mode))==NULL)
                    659:                error(badfile);
                    660: 
                    661:        return fp;
                    662: }
                    663: 
                    664: char *
                    665: xcalloc(nbr,size)
                    666: {
                    667:        register char   *ptr;
                    668: 
                    669:        if ((ptr=calloc(nbr,size)) == NULL)
                    670:                error(nocore);
                    671: 
                    672:        return ptr;
                    673: }
                    674: 
                    675: error(str)
                    676:        char *str;
                    677: {
                    678:        fprintf(stderr,"\n%s:",procnam);
                    679:        fpath(stderr);
                    680:        fprintf(stderr,":%d %s\n",fline[ifx],str);
                    681:        if (Cp) {
                    682:                register struct call    *mptr;
                    683: 
                    684:                /* fix limit */
                    685:                *op = EOS;
                    686:                (Cp+1)->argp = Ap+1;
                    687: 
                    688:                for (mptr=callst; mptr<=Cp; ++mptr) {
                    689:                        register char   **aptr, **lim;
                    690: 
                    691:                        aptr = mptr->argp;
                    692:                        lim = (mptr+1)->argp-1;
                    693:                        if (mptr==callst)
                    694:                                fputs(*aptr,stderr);
                    695:                        ++aptr;
                    696:                        fputs("(",stderr);
                    697:                        if (aptr < lim)
                    698:                                for (;;) {
                    699:                                        fputs(*aptr++,stderr);
                    700:                                        if (aptr >= lim)
                    701:                                                break;
                    702:                                        fputs(",",stderr);
                    703:                                }
                    704:                }
                    705:                while (--mptr >= callst)
                    706:                        fputs(")",stderr);
                    707: 
                    708:                fputs("\n",stderr);
                    709:        }
                    710:        delexit(NOT_OK);
                    711: }
                    712: 
                    713: error2(str,num)
                    714:        char *str;
                    715:        int num;
                    716: {
                    717:        char buf[500];
                    718: 
                    719:        fprintf(buf,str,num);
                    720:        error(buf);
                    721: }
                    722: 
                    723: char *
                    724: chkbltin(s)
                    725: char   *s;
                    726: {
                    727:        static char     buf[24];
                    728: 
                    729:        if (*s&~LOW7) {
                    730:                sprintf(buf,"<%s>",barray[*s&LOW7].bname);
                    731:                return buf;
                    732:        }
                    733:        return s;
                    734: }

unix.superglobalmegacorp.com

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