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

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

unix.superglobalmegacorp.com

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