Annotation of researchv9/cmd/troff/n3.c, revision 1.1

1.1     ! root        1: /*     @(#)roff:n3.c   2.7     */
        !             2: /*
        !             3:  * troff3.c
        !             4:  * 
        !             5:  * macro and string routines, storage allocation
        !             6:  */
        !             7: 
        !             8: 
        !             9: #include "tdef.h"
        !            10: #ifdef NROFF
        !            11: #include "tw.h"
        !            12: #endif
        !            13: #include "ext.h"
        !            14: 
        !            15: #define        MHASH(x)        ((x>>6)^x)&0177
        !            16: struct contab *mhash[128];     /* 128 == the 0177 on line above */
        !            17: #define        blisti(i)       (((i)-ENV_BLK*BLK) / BLK)
        !            18: filep  blist[NBLIST];
        !            19: tchar  *argtop;
        !            20: int    pagech = '%';
        !            21: int    strflg;
        !            22: 
        !            23: #ifdef INCORE
        !            24:        tchar *wbuf;
        !            25:        tchar corebuf[(ENV_BLK + NBLIST + 1) * BLK];
        !            26: #else
        !            27:        tchar wbuf[BLK];
        !            28:        tchar rbuf[BLK];
        !            29: #endif
        !            30: 
        !            31: caseig()
        !            32: {
        !            33:        register i;
        !            34: 
        !            35:        offset = 0;
        !            36:        if ((i = copyb()) != '.')
        !            37:                control(i, 1);
        !            38: }
        !            39: 
        !            40: 
        !            41: casern()
        !            42: {
        !            43:        register i, j;
        !            44: 
        !            45:        lgf++;
        !            46:        skip();
        !            47:        if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0)
        !            48:                return;
        !            49:        skip();
        !            50:        clrmn(findmn(j = getrq()));
        !            51:        if (j) {
        !            52:                munhash(&contab[oldmn]);
        !            53:                contab[oldmn].rq = j;
        !            54:                maddhash(&contab[oldmn]);
        !            55:        }
        !            56: }
        !            57: 
        !            58: maddhash(rp)
        !            59: register struct contab *rp;
        !            60: {
        !            61:        register struct contab **hp;
        !            62: 
        !            63:        if (rp->rq == 0)
        !            64:                return;
        !            65:        hp = &mhash[MHASH(rp->rq)];
        !            66:        rp->link = *hp;
        !            67:        *hp = rp;
        !            68: }
        !            69: 
        !            70: munhash(mp)
        !            71: register struct contab *mp;
        !            72: {      
        !            73:        register struct contab *p;
        !            74:        register struct contab **lp;
        !            75: 
        !            76:        if (mp->rq == 0)
        !            77:                return;
        !            78:        lp = &mhash[MHASH(mp->rq)];
        !            79:        p = *lp;
        !            80:        while (p) {
        !            81:                if (p == mp) {
        !            82:                        *lp = p->link;
        !            83:                        p->link = 0;
        !            84:                        return;
        !            85:                }
        !            86:                lp = &p->link;
        !            87:                p = p->link;
        !            88:        }
        !            89: }
        !            90: 
        !            91: mrehash()
        !            92: {
        !            93:        register struct contab *p;
        !            94:        register i;
        !            95: 
        !            96:        for (i=0; i<128; i++)
        !            97:                mhash[i] = 0;
        !            98:        for (p=contab; p < &contab[NM]; p++)
        !            99:                p->link = 0;
        !           100:        for (p=contab; p < &contab[NM]; p++) {
        !           101:                if (p->rq == 0)
        !           102:                        continue;
        !           103:                i = MHASH(p->rq);
        !           104:                p->link = mhash[i];
        !           105:                mhash[i] = p;
        !           106:        }
        !           107: }
        !           108: 
        !           109: caserm()
        !           110: {
        !           111:        int j;
        !           112: 
        !           113:        lgf++;
        !           114:        while (!skip() && (j = getrq()) != 0)
        !           115:                clrmn(findmn(j));
        !           116:        lgf--;
        !           117: }
        !           118: 
        !           119: 
        !           120: caseas()
        !           121: {
        !           122:        app++;
        !           123:        caseds();
        !           124: }
        !           125: 
        !           126: 
        !           127: caseds()
        !           128: {
        !           129:        ds++;
        !           130:        casede();
        !           131: }
        !           132: 
        !           133: 
        !           134: caseam()
        !           135: {
        !           136:        app++;
        !           137:        casede();
        !           138: }
        !           139: 
        !           140: 
        !           141: casede()
        !           142: {
        !           143:        register i, req;
        !           144:        register filep savoff;
        !           145:        extern filep finds();
        !           146: 
        !           147:        if (dip != d)
        !           148:                wbfl();
        !           149:        req = '.';
        !           150:        lgf++;
        !           151:        skip();
        !           152:        if ((i = getrq()) == 0)
        !           153:                goto de1;
        !           154:        if ((offset = finds(i)) == 0)
        !           155:                goto de1;
        !           156:        if (ds)
        !           157:                copys();
        !           158:        else 
        !           159:                req = copyb();
        !           160:        wbfl();
        !           161:        clrmn(oldmn);
        !           162:        if (newmn) {
        !           163:                if (contab[newmn].rq)
        !           164:                        munhash(&contab[newmn]);
        !           165:                contab[newmn].rq = i;
        !           166:                maddhash(&contab[newmn]);
        !           167:        }
        !           168:        if (apptr) {
        !           169:                savoff = offset;
        !           170:                offset = apptr;
        !           171:                wbt((tchar) IMP);
        !           172:                offset = savoff;
        !           173:        }
        !           174:        offset = dip->op;
        !           175:        if (req != '.')
        !           176:                control(req, 1);
        !           177: de1:
        !           178:        ds = app = 0;
        !           179:        return;
        !           180: }
        !           181: 
        !           182: 
        !           183: findmn(i)
        !           184: register int   i;
        !           185: {
        !           186:        register struct contab *p;
        !           187: 
        !           188:        for (p = mhash[MHASH(i)]; p; p = p->link)
        !           189:                if (i == p->rq)
        !           190:                        return(p - contab);
        !           191:        return(-1);
        !           192: }
        !           193: 
        !           194: 
        !           195: clrmn(i)
        !           196: register int   i;
        !           197: {
        !           198:        if (i >= 0) {
        !           199:                if (contab[i].mx)
        !           200:                        ffree((filep)contab[i].mx);
        !           201:                munhash(&contab[i]);
        !           202:                contab[i].rq = 0;
        !           203:                contab[i].mx = 0;
        !           204:                contab[i].f = 0;
        !           205:        }
        !           206: }
        !           207: 
        !           208: 
        !           209: filep finds(mn)
        !           210: register int   mn;
        !           211: {
        !           212:        register i;
        !           213:        register filep savip;
        !           214:        extern filep alloc();
        !           215:        extern filep incoff();
        !           216: 
        !           217:        oldmn = findmn(mn);
        !           218:        newmn = 0;
        !           219:        apptr = (filep)0;
        !           220:        if (app && oldmn >= 0 && contab[oldmn].mx) {
        !           221:                savip = ip;
        !           222:                ip = (filep)contab[oldmn].mx;
        !           223:                oldmn = -1;
        !           224:                while ((i = rbf()) != 0)
        !           225:                        ;
        !           226:                apptr = ip;
        !           227:                if (!diflg)
        !           228:                        ip = incoff(ip);
        !           229:                nextb = ip;
        !           230:                ip = savip;
        !           231:        } else {
        !           232:                for (i = 0; i < NM; i++) {
        !           233:                        if (contab[i].rq == 0)
        !           234:                                break;
        !           235:                }
        !           236:                if (i == NM || (nextb = alloc()) == 0) {
        !           237:                        app = 0;
        !           238:                        if (macerr++ > 1)
        !           239:                                done2(02);
        !           240:                        errprint("Too many (%d) string/macro names", NM);
        !           241:                        edone(04);
        !           242:                        return(offset = 0);
        !           243:                }
        !           244:                contab[i].mx = (unsigned) nextb;
        !           245:                if (!diflg) {
        !           246:                        newmn = i;
        !           247:                        if (oldmn == -1)
        !           248:                                contab[i].rq = -1;
        !           249:                } else {
        !           250:                        contab[i].rq = mn;
        !           251:                        maddhash(&contab[i]);
        !           252:                }
        !           253:        }
        !           254:        app = 0;
        !           255:        return(offset = nextb);
        !           256: }
        !           257: 
        !           258: 
        !           259: skip()
        !           260: {
        !           261:        register tchar i;
        !           262: 
        !           263:        while (cbits(i = getch()) == ' ')
        !           264:                ;
        !           265:        ch = i;
        !           266:        return(nlflg);
        !           267: }
        !           268: 
        !           269: 
        !           270: copyb()
        !           271: {
        !           272:        register i, j, state;
        !           273:        register tchar ii;
        !           274:        int     req, k;
        !           275:        filep savoff;
        !           276: 
        !           277:        if (skip() || !(j = getrq()))
        !           278:                j = '.';
        !           279:        req = j;
        !           280:        k = j >> BYTE;
        !           281:        j &= BYTEMASK;
        !           282:        copyf++;
        !           283:        flushi();
        !           284:        nlflg = 0;
        !           285:        state = 1;
        !           286: 
        !           287: /* state 0     eat up
        !           288:  * state 1     look for .
        !           289:  * state 2     look for first char of end macro
        !           290:  * state 3     look for second char of end macro
        !           291:  */
        !           292: 
        !           293:        while (1) {
        !           294:                i = cbits(ii = getch());
        !           295:                if (state == 3) {
        !           296:                        if (i == k)
        !           297:                                break;
        !           298:                        if (!k) {
        !           299:                                ch = ii;
        !           300:                                i = getach();
        !           301:                                ch = ii;
        !           302:                                if (!i)
        !           303:                                        break;
        !           304:                        }
        !           305:                        state = 0;
        !           306:                        goto c0;
        !           307:                }
        !           308:                if (i == '\n') {
        !           309:                        state = 1;
        !           310:                        nlflg = 0;
        !           311:                        goto c0;
        !           312:                }
        !           313:                if (state == 1 && i == '.') {
        !           314:                        state++;
        !           315:                        savoff = offset;
        !           316:                        goto c0;
        !           317:                }
        !           318:                if ((state == 2) && (i == j)) {
        !           319:                        state++;
        !           320:                        goto c0;
        !           321:                }
        !           322:                state = 0;
        !           323: c0:
        !           324:                if (offset)
        !           325:                        wbf(ii);
        !           326:        }
        !           327:        if (offset) {
        !           328:                wbfl();
        !           329:                offset = savoff;
        !           330:                wbt((tchar)0);
        !           331:        }
        !           332:        copyf--;
        !           333:        return(req);
        !           334: }
        !           335: 
        !           336: 
        !           337: copys()
        !           338: {
        !           339:        register tchar i;
        !           340: 
        !           341:        copyf++;
        !           342:        if (skip())
        !           343:                goto c0;
        !           344:        if (cbits(i = getch()) != '"')
        !           345:                wbf(i);
        !           346:        while (cbits(i = getch()) != '\n')
        !           347:                wbf(i);
        !           348: c0:
        !           349:        wbt((tchar)0);
        !           350:        copyf--;
        !           351: }
        !           352: 
        !           353: 
        !           354: filep alloc()  /* return free blist[] block in nextb */
        !           355: {
        !           356:        register i;
        !           357:        register filep j;
        !           358: 
        !           359:        for (i = 0; i < NBLIST; i++) {
        !           360:                if (blist[i] == 0)
        !           361:                        break;
        !           362:        }
        !           363:        if (i == NBLIST) {
        !           364:                j = 0;
        !           365:        } else {
        !           366:                blist[i] = -1;
        !           367:                j = (filep)i * BLK + ENV_BLK * BLK;
        !           368:        }
        !           369:        return(nextb = j);
        !           370: }
        !           371: 
        !           372: 
        !           373: ffree(i)       /* free blist[i] and blocks pointed to */
        !           374: filep i;
        !           375: {
        !           376:        register j;
        !           377: 
        !           378:        while (blist[j = blisti(i)] != (unsigned) ~0) {
        !           379:                i = (filep) blist[j];
        !           380:                blist[j] = 0;
        !           381:        }
        !           382:        blist[j] = 0;
        !           383: }
        !           384: 
        !           385: wbt(i)
        !           386: tchar i;
        !           387: {
        !           388:        wbf(i);
        !           389:        wbfl();
        !           390: }
        !           391: 
        !           392: 
        !           393: wbf(i)         /* store i into blist[offset] */
        !           394: register tchar i;
        !           395: {
        !           396:        register j;
        !           397: 
        !           398:        if (!offset)
        !           399:                return;
        !           400:        if (!woff) {
        !           401:                woff = offset;
        !           402: #ifdef INCORE
        !           403:                wbuf = &corebuf[woff];  /* INCORE only */
        !           404: #endif
        !           405:                wbfi = 0;
        !           406:        }
        !           407:        wbuf[wbfi++] = i;
        !           408:        if (!((++offset) & (BLK - 1))) {
        !           409:                wbfl();
        !           410:                j = blisti(--offset);
        !           411:                if (j < 0 || j >= NBLIST) {
        !           412:                        errprint("Out of temp file space");
        !           413:                        done2(01);
        !           414:                }
        !           415:                if (blist[j] == (unsigned) ~0) {
        !           416:                        if (alloc() == 0) {
        !           417:                                errprint("Out of temp file space");
        !           418:                                done2(01);
        !           419:                        }
        !           420:                        blist[j] = (unsigned)(nextb);
        !           421:                }
        !           422:                offset = ((filep)blist[j]);
        !           423:        }
        !           424:        if (wbfi >= BLK)
        !           425:                wbfl();
        !           426: }
        !           427: 
        !           428: 
        !           429: wbfl()         /* flush current blist[] block */
        !           430: {
        !           431:        if (woff == 0)
        !           432:                return;
        !           433: #ifndef INCORE
        !           434:        lseek(ibf, ((long)woff) * sizeof(tchar), 0);
        !           435:        write(ibf, (char *)wbuf, wbfi * sizeof(tchar));
        !           436: #endif
        !           437:        if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1))))
        !           438:                roff = -1;
        !           439:        woff = 0;
        !           440: }
        !           441: 
        !           442: 
        !           443: tchar rbf()    /* return next char from blist[] block */
        !           444: {
        !           445:        register tchar i;
        !           446:        register filep j, p;
        !           447:        extern filep incoff();
        !           448: 
        !           449:        if (ip == NBLIST*BLK) {         /* for rdtty */
        !           450:                if (j = rdtty())
        !           451:                        return(j);
        !           452:                else
        !           453:                        return(popi());
        !           454:        }
        !           455:        /* this is an inline expansion of rbf0: dirty! */
        !           456: #ifndef INCORE
        !           457:        j = ip & ~(BLK - 1);
        !           458:        if (j != roff) {
        !           459:                roff = j;
        !           460:                lseek(ibf, (long)j * sizeof(tchar), 0);
        !           461:                if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) <= 0)
        !           462:                        i = 0;
        !           463:                else
        !           464:                        i = rbuf[ip & (BLK-1)];
        !           465:        } else
        !           466:                i = rbuf[ip & (BLK-1)];
        !           467: #else
        !           468:        i = corebuf[ip];
        !           469: #endif
        !           470:        /* end of rbf0 */
        !           471:        if (i == 0) {
        !           472:                if (!app)
        !           473:                        i = popi();
        !           474:                return(i);
        !           475:        }
        !           476:        /* this is an inline expansion of incoff: also dirty */
        !           477:        p = ++ip;
        !           478:        if ((p & (BLK - 1)) == 0) {
        !           479:                if ((ip = blist[blisti(p-1)]) == (unsigned) ~0) {
        !           480:                        ip = 0;
        !           481:                        errprint("Bad storage allocation");
        !           482:                        done2(-5);
        !           483:                }
        !           484:                /* this was meant to protect against people removing
        !           485:                /* the macro they were standing on, but it's too
        !           486:                /* sensitive to block boundaries.
        !           487:                /* if (ip == 0) {
        !           488:                /*      errprint("Block removed while in use");
        !           489:                /*      done2(-6);
        !           490:                /* }
        !           491:                */
        !           492:        }
        !           493:        return(i);
        !           494: }
        !           495: 
        !           496: 
        !           497: tchar rbf0(p)
        !           498: register filep p;
        !           499: {
        !           500: #ifndef INCORE
        !           501:        register filep i;
        !           502: 
        !           503:        if ((i = p & ~(BLK - 1)) != roff) {
        !           504:                roff = i;
        !           505:                lseek(ibf, (long)roff * sizeof(tchar), 0);
        !           506:                if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) == 0)
        !           507:                        return(0);
        !           508:        }
        !           509:        return(rbuf[p & (BLK-1)]);
        !           510: #else
        !           511:        return(corebuf[p]);
        !           512: #endif
        !           513: }
        !           514: 
        !           515: 
        !           516: filep incoff(p)                /* get next blist[] block */
        !           517: register filep p;
        !           518: {
        !           519:        p++;
        !           520:        if ((p & (BLK - 1)) == 0) {
        !           521:                if ((p = blist[blisti(p-1)]) == (unsigned) ~0) {
        !           522:                        errprint("Bad storage allocation");
        !           523:                        done2(-5);
        !           524:                }
        !           525:        }
        !           526:        return(p);
        !           527: }
        !           528: 
        !           529: 
        !           530: tchar popi()
        !           531: {
        !           532:        register struct s *p;
        !           533: 
        !           534:        if (frame == stk)
        !           535:                return(0);
        !           536:        if (strflg)
        !           537:                strflg--;
        !           538:        p = nxf = frame;
        !           539:        p->nargs = 0;
        !           540:        frame = p->pframe;
        !           541:        ip = p->pip;
        !           542:        pendt = p->ppendt;
        !           543:        lastpbp = p->lastpbp;
        !           544:        return(p->pch);
        !           545: }
        !           546: 
        !           547: /*
        !           548:  *     test that the end of the allocation is above a certain location
        !           549:  *     in memory
        !           550:  */
        !           551: #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);}
        !           552: 
        !           553: pushi(newip, mname)
        !           554: filep newip;
        !           555: int mname;
        !           556: {
        !           557:        register struct s *p;
        !           558:        extern char *setbrk();
        !           559: 
        !           560:        SPACETEST(nxf, sizeof(struct s));
        !           561:        p = nxf;
        !           562:        p->pframe = frame;
        !           563:        p->pip = ip;
        !           564:        p->ppendt = pendt;
        !           565:        p->pch = ch;
        !           566:        p->lastpbp = lastpbp;
        !           567:        p->mname = mname;
        !           568:        lastpbp = pbp;
        !           569:        pendt = ch = 0;
        !           570:        frame = nxf;
        !           571:        if (nxf->nargs == 0) 
        !           572:                nxf += 1;
        !           573:        else 
        !           574:                nxf = (struct s *)argtop;
        !           575:        return(ip = newip);
        !           576: }
        !           577: 
        !           578: 
        !           579: char   *setbrk(x)
        !           580: int    x;
        !           581: {
        !           582:        register char   *i, *k;
        !           583:        register j;
        !           584:        char    *sbrk();
        !           585: 
        !           586:        if ((i = sbrk(x)) == (char *) -1) {
        !           587:                errprint("Core limit reached");
        !           588:                edone(0100);
        !           589:        }
        !           590:        if (j = (unsigned)i % sizeof(int)) {    /*check alignment for 3B*/
        !           591:                j = sizeof(int) - j;            /*only init calls should need this*/
        !           592:                if ((k = sbrk(j)) == (char *) -1) {
        !           593:                        errprint("Core limit reached");
        !           594:                        edone(0100);
        !           595:                }
        !           596:                if (k != i + x) {       /*there must have been an intervening sbrk*/
        !           597:                        errprint ("internal error in setbrk: i=%x, j=%d, k=%x",
        !           598:                                i, j, k);
        !           599:                        edone(0100);
        !           600:                }
        !           601:                i += j;
        !           602:        }
        !           603:        enda = i + x;
        !           604:        return(i);
        !           605: }
        !           606: 
        !           607: 
        !           608: getsn()
        !           609: {
        !           610:        register i;
        !           611: 
        !           612:        if ((i = getach()) == 0)
        !           613:                return(0);
        !           614:        if (i == '(')
        !           615:                return(getrq());
        !           616:        else 
        !           617:                return(i);
        !           618: }
        !           619: 
        !           620: 
        !           621: setstr()
        !           622: {
        !           623:        register i, j;
        !           624: 
        !           625:        lgf++;
        !           626:        if ((i = getsn()) == 0 || (j = findmn(i)) == -1 || !contab[j].mx) {
        !           627:                lgf--;
        !           628:                return(0);
        !           629:        } else {
        !           630:                SPACETEST(nxf, sizeof(struct s));
        !           631:                nxf->nargs = 0;
        !           632:                strflg++;
        !           633:                lgf--;
        !           634:                return pushi((filep)contab[j].mx, i);
        !           635:        }
        !           636: }
        !           637: 
        !           638: 
        !           639: 
        !           640: collect()
        !           641: {
        !           642:        register j;
        !           643:        register tchar i;
        !           644:        register tchar *strp;
        !           645:        tchar * lim;
        !           646:        tchar * *argpp, **argppend;
        !           647:        int     quote;
        !           648:        struct s *savnxf;
        !           649: 
        !           650:        copyf++;
        !           651:        nxf->nargs = 0;
        !           652:        savnxf = nxf;
        !           653:        if (skip())
        !           654:                goto rtn;
        !           655: 
        !           656:        {
        !           657:                char *memp;
        !           658:                memp = (char *)savnxf;
        !           659:                /*
        !           660:                 *      1 s structure for the macro descriptor
        !           661:                 *      APERMAC tchar *'s for pointers into the strings
        !           662:                 *      space for the tchar's themselves
        !           663:                 */
        !           664:                memp += sizeof(struct s);
        !           665:                /*
        !           666:                 *      CPERMAC (the total # of characters for ALL arguments)
        !           667:                 *      to a macros, has been carefully chosen
        !           668:                 *      so that the distance between stack frames is < DELTA 
        !           669:                 */
        !           670: #define        CPERMAC 200
        !           671: #define        APERMAC 9
        !           672:                memp += APERMAC * sizeof(tchar *);
        !           673:                memp += CPERMAC * sizeof(tchar);
        !           674:                nxf = (struct s*)memp;
        !           675:        }
        !           676:        lim = (tchar *)nxf;
        !           677:        argpp = (tchar **)(savnxf + 1);
        !           678:        argppend = &argpp[APERMAC];
        !           679:        SPACETEST(argppend, sizeof(tchar *));
        !           680:        strp = (tchar *)argppend;
        !           681:        /*
        !           682:         *      Zero out all the string pointers before filling them in.
        !           683:         */
        !           684:        for (j = 0; j < APERMAC; j++){
        !           685:                argpp[j] = (tchar *)0;
        !           686:        }
        !           687: #if 0
        !           688:        errprint("savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x",
        !           689:                savnxf, nxf, argpp, strp, lim, enda);
        !           690: #endif 0
        !           691:        strflg = 0;
        !           692:        while (argpp != argppend && !skip()) {
        !           693:                *argpp++ = strp;
        !           694:                quote = 0;
        !           695:                if (cbits(i = getch()) == '"')
        !           696:                        quote++;
        !           697:                else 
        !           698:                        ch = i;
        !           699:                while (1) {
        !           700:                        i = getch();
        !           701:                        if (nlflg || (!quote && argpp != argppend && cbits(i) == ' '))
        !           702:                                break;  /* collects rest into $9 */
        !           703:                        if (   quote
        !           704:                            && cbits(i) == '"'
        !           705:                            && cbits(i = getch()) != '"') {
        !           706:                                ch = i;
        !           707:                                break;
        !           708:                        }
        !           709:                        *strp++ = i;
        !           710:                        if (strflg && strp >= lim) {
        !           711: #if 0
        !           712:                                errprint("strp=0x%x, lim = 0x%x",
        !           713:                                        strp, lim);
        !           714: #endif 0
        !           715:                                errprint("Macro argument too long");
        !           716:                                copyf--;
        !           717:                                edone(004);
        !           718:                        }
        !           719:                        SPACETEST(strp, 3 * sizeof(tchar));
        !           720:                }
        !           721:                *strp++ = 0;
        !           722:        }
        !           723:        nxf = savnxf;
        !           724:        nxf->nargs = argpp - (tchar **)(savnxf + 1);
        !           725:        argtop = strp;
        !           726: rtn:
        !           727:        copyf--;
        !           728: }
        !           729: 
        !           730: 
        !           731: seta()
        !           732: {
        !           733:        register i;
        !           734: 
        !           735:        i = cbits(getch()) - '0';
        !           736:        if (i > 0 && i <= APERMAC && i <= frame->nargs)
        !           737:                pushback(*(((tchar **)(frame + 1)) + i - 1));
        !           738: }
        !           739: 
        !           740: 
        !           741: caseda()
        !           742: {
        !           743:        app++;
        !           744:        casedi();
        !           745: }
        !           746: 
        !           747: 
        !           748: casedi()
        !           749: {
        !           750:        register i, j;
        !           751:        register *k;
        !           752: 
        !           753:        lgf++;
        !           754:        if (skip() || (i = getrq()) == 0) {
        !           755:                if (dip != d)
        !           756:                        wbt((tchar)0);
        !           757:                if (dilev > 0) {
        !           758:                        numtab[DN].val = dip->dnl;
        !           759:                        numtab[DL].val = dip->maxl;
        !           760:                        dip = &d[--dilev];
        !           761:                        offset = dip->op;
        !           762:                }
        !           763:                goto rtn;
        !           764:        }
        !           765:        if (++dilev == NDI) {
        !           766:                --dilev;
        !           767:                errprint("Diversions nested too deep");
        !           768:                edone(02);
        !           769:        }
        !           770:        if (dip != d)
        !           771:                wbt((tchar)0);
        !           772:        diflg++;
        !           773:        dip = &d[dilev];
        !           774:        dip->op = finds(i);
        !           775:        dip->curd = i;
        !           776:        clrmn(oldmn);
        !           777:        k = (int *) & dip->dnl;
        !           778:        for (j = 0; j < 10; j++)
        !           779:                k[j] = 0;       /*not op and curd*/
        !           780: rtn:
        !           781:        app = 0;
        !           782:        diflg = 0;
        !           783: }
        !           784: 
        !           785: 
        !           786: casedt()
        !           787: {
        !           788:        lgf++;
        !           789:        dip->dimac = dip->ditrap = dip->ditf = 0;
        !           790:        skip();
        !           791:        dip->ditrap = vnumb((int *)0);
        !           792:        if (nonumb)
        !           793:                return;
        !           794:        skip();
        !           795:        dip->dimac = getrq();
        !           796: }
        !           797: 
        !           798: 
        !           799: casetl()
        !           800: {
        !           801:        register j;
        !           802:        int w[3];
        !           803:        tchar buf[LNSIZE];
        !           804:        register tchar *tp;
        !           805:        tchar i, delim;
        !           806: 
        !           807:        /*
        !           808:         * bug fix
        !           809:         *
        !           810:         * if .tl is the first thing in the file, the p1
        !           811:         * doesn't come out, also the pagenumber will be 0
        !           812:         *
        !           813:         * tends too confuse the device filter (and the user as well)
        !           814:         */
        !           815:        if (dip == d && numtab[NL].val == -1)
        !           816:                newline(1);
        !           817:        dip->nls = 0;
        !           818:        skip();
        !           819:        if (ismot(delim = getch())) {
        !           820:                ch = delim;
        !           821:                delim = '\'';
        !           822:        } else 
        !           823:                delim = cbits(delim);
        !           824:        tp = buf;
        !           825:        numtab[HP].val = 0;
        !           826:        w[0] = w[1] = w[2] = 0;
        !           827:        j = 0;
        !           828:        while (cbits(i = getch()) != '\n') {
        !           829:                if (cbits(i) == cbits(delim)) {
        !           830:                        if (j < 3)
        !           831:                                w[j] = numtab[HP].val;
        !           832:                        numtab[HP].val = 0;
        !           833:                        j++;
        !           834:                        *tp++ = 0;
        !           835:                } else {
        !           836:                        if (cbits(i) == pagech) {
        !           837:                                setn1(numtab[PN].val, numtab[findr('%')].fmt,
        !           838:                                      i&SFMASK);
        !           839:                                continue;
        !           840:                        }
        !           841:                        numtab[HP].val += width(i);
        !           842:                        if (tp < &buf[LNSIZE-10])
        !           843:                                *tp++ = i;
        !           844:                }
        !           845:        }
        !           846:        if (j<3)
        !           847:                w[j] = numtab[HP].val;
        !           848:        *tp++ = 0;
        !           849:        *tp++ = 0;
        !           850:        *tp++ = 0;
        !           851:        tp = buf;
        !           852: #ifdef NROFF
        !           853:        horiz(po);
        !           854: #endif
        !           855:        while (i = *tp++)
        !           856:                pchar(i);
        !           857:        if (w[1] || w[2])
        !           858:                horiz(j = quant((lt - w[1]) / 2 - w[0], HOR));
        !           859:        while (i = *tp++)
        !           860:                pchar(i);
        !           861:        if (w[2]) {
        !           862:                horiz(lt - w[0] - w[1] - w[2] - j);
        !           863:                while (i = *tp++)
        !           864:                        pchar(i);
        !           865:        }
        !           866:        newline(0);
        !           867:        if (dip != d) {
        !           868:                if (dip->dnl > dip->hnl)
        !           869:                        dip->hnl = dip->dnl;
        !           870:        } else {
        !           871:                if (numtab[NL].val > dip->hnl)
        !           872:                        dip->hnl = numtab[NL].val;
        !           873:        }
        !           874: }
        !           875: 
        !           876: 
        !           877: casepc()
        !           878: {
        !           879:        pagech = chget(IMP);
        !           880: }
        !           881: 
        !           882: 
        !           883: casepm()
        !           884: {
        !           885:        register i, k;
        !           886:        register char   *p;
        !           887:        int     xx, cnt, tcnt, kk, tot;
        !           888:        filep j;
        !           889:        char    pmline[10];
        !           890: 
        !           891:        kk = cnt = tcnt = 0;
        !           892:        tot = !skip();
        !           893:        for (i = 0; i < NM; i++) {
        !           894:                if ((xx = contab[i].rq) == 0 || contab[i].mx == 0)
        !           895:                        continue;
        !           896:                tcnt++;
        !           897:                p = pmline;
        !           898:                j = (filep) contab[i].mx;
        !           899:                k = 1;
        !           900:                while ((j = blist[blisti(j)]) != (unsigned) ~0) {
        !           901:                        k++; 
        !           902:                }
        !           903:                cnt++;
        !           904:                kk += k;
        !           905:                if (!tot) {
        !           906:                        *p++ = xx & 0177;
        !           907:                        if (!(*p++ = (xx >> BYTE) & 0177))
        !           908:                                *(p - 1) = ' ';
        !           909:                        *p++ = 0;
        !           910:                        fdprintf(stderr, "%s %d\n", pmline, k);
        !           911:                }
        !           912:        }
        !           913:        fdprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk);
        !           914: }
        !           915: 
        !           916: stackdump()    /* dumps stack of macros in process */
        !           917: {
        !           918:        struct s *p;
        !           919: 
        !           920:        if (frame != stk) {
        !           921:                fdprintf(stderr, "stack: ");
        !           922:                for (p = frame; p != stk; p = p->pframe)
        !           923:                        fdprintf(stderr, "%c%c ", p->mname&0177, (p->mname>>BYTE)&0177);
        !           924:                fdprintf(stderr, "\n");
        !           925:        }
        !           926: }

unix.superglobalmegacorp.com

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