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

unix.superglobalmegacorp.com

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