Annotation of 3BSD/cmd/troff/n3.c, revision 1.1

1.1     ! root        1: #include "tdef.h"
        !             2: extern
        !             3: #include "d.h"
        !             4: extern
        !             5: #include "v.h"
        !             6: #ifdef NROFF
        !             7: extern
        !             8: #include "tw.h"
        !             9: #endif
        !            10: #include "s.h"
        !            11: 
        !            12: /*
        !            13: troff3.c
        !            14: 
        !            15: macro and string routines, storage allocation
        !            16: */
        !            17: 
        !            18: unsigned blist[NBLIST];
        !            19: extern struct s *frame, *stk, *nxf;
        !            20: extern filep ip;
        !            21: extern filep offset;
        !            22: extern filep nextb;
        !            23: extern char *enda;
        !            24: 
        !            25: extern int ch;
        !            26: extern int ibf;
        !            27: extern int lgf;
        !            28: extern int copyf;
        !            29: extern int ch0;
        !            30: extern int app;
        !            31: extern int ds;
        !            32: extern int nlflg;
        !            33: extern int *argtop;
        !            34: extern int *ap;
        !            35: extern int nchar;
        !            36: extern int pendt;
        !            37: extern int rchar;
        !            38: extern int dilev;
        !            39: extern int nonumb;
        !            40: extern int lt;
        !            41: extern int nrbits;
        !            42: extern int nform;
        !            43: extern int fmt[];
        !            44: extern int oldmn;
        !            45: extern int newmn;
        !            46: extern int macerr;
        !            47: extern filep apptr;
        !            48: extern int diflg;
        !            49: extern filep woff;
        !            50: extern filep roff;
        !            51: extern int wbfi;
        !            52: extern int po;
        !            53: extern int *cp;
        !            54: extern int xxx;
        !            55: int pagech = '%';
        !            56: int strflg;
        !            57: extern struct contab {
        !            58:        int rq;
        !            59:        union {
        !            60:                int (*f)();
        !            61:                unsigned mx;
        !            62:        }x;
        !            63: }contab[NM];
        !            64: #ifndef VMUNIX
        !            65: int wbuf[BLK];
        !            66: int rbuf[BLK];
        !            67: #else
        !            68: int *wbuf;
        !            69: int *rbuf;
        !            70: int Buf[NBLIST*BLK];
        !            71: #endif
        !            72: 
        !            73: caseig(){
        !            74:        register i;
        !            75: 
        !            76:        offset = 0;
        !            77:        if((i = copyb()) != '.')control(i,1);
        !            78: }
        !            79: casern(){
        !            80:        register i,j;
        !            81: 
        !            82:        lgf++;
        !            83:        skip();
        !            84:        if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return;
        !            85:        skip();
        !            86:        clrmn(findmn(j=getrq()));
        !            87:        if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
        !            88: }
        !            89: caserm(){
        !            90:        lgf++;
        !            91:        while(!skip()){
        !            92:                clrmn(findmn(getrq()));
        !            93:        }
        !            94: }
        !            95: caseas(){
        !            96:        app++;
        !            97:        caseds();
        !            98: }
        !            99: caseds(){
        !           100:        ds++;
        !           101:        casede();
        !           102: }
        !           103: caseam(){
        !           104:        app++;
        !           105:        casede();
        !           106: }
        !           107: casede(){
        !           108:        register i, req;
        !           109:        register filep savoff;
        !           110:        extern filep finds();
        !           111: 
        !           112:        if(dip != d)wbfl();
        !           113:        req = '.';
        !           114:        lgf++;
        !           115:        skip();
        !           116:        if((i=getrq())==0)goto de1;
        !           117:        if((offset=finds(i)) == 0)goto de1;
        !           118:        if(ds)copys();
        !           119:                else req = copyb();
        !           120:        wbfl();
        !           121:        clrmn(oldmn);
        !           122:        if(newmn)contab[newmn].rq = i | MMASK;
        !           123:        if(apptr){
        !           124:                savoff = offset;
        !           125:                offset = apptr;
        !           126:                wbt(IMP);
        !           127:                offset = savoff;
        !           128:        }
        !           129:        offset = dip->op;
        !           130:        if(req != '.')control(req,1);
        !           131: de1:
        !           132:        ds = app = 0;
        !           133:        return;
        !           134: }
        !           135: findmn(i)
        !           136: int i;
        !           137: {
        !           138:        register j;
        !           139: 
        !           140:        for(j=0;j<NM;j++){
        !           141:                if(i == (contab[j].rq & ~MMASK))break;
        !           142:        }
        !           143:        if(j==NM)j = -1;
        !           144:        return(j);
        !           145: }
        !           146: clrmn(i)
        !           147: int i;
        !           148: {
        !           149:        extern filep boff();
        !           150:        if(i >= 0){
        !           151:                if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS);
        !           152:                contab[i].rq = 0;
        !           153:                contab[i].x.mx = 0;
        !           154:        }
        !           155: }
        !           156: filep finds(mn)
        !           157: int mn;
        !           158: {
        !           159:        register i;
        !           160:        extern filep boff();
        !           161:        register filep savip;
        !           162:        extern filep alloc();
        !           163:        extern filep incoff();
        !           164: 
        !           165:        oldmn = findmn(mn);
        !           166:        newmn = 0;
        !           167:        apptr = (filep)0;
        !           168:        if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){
        !           169:                        savip = ip;
        !           170:                        ip = (((filep)contab[oldmn].x.mx)<<BLKBITS);
        !           171:                        oldmn = -1;
        !           172:                        while((i=rbf()) != 0);
        !           173:                        apptr = ip;
        !           174:                        if(!diflg)ip = incoff(ip);
        !           175:                        nextb = ip;
        !           176:                        ip = savip;
        !           177:        }else{
        !           178:                for(i=0;i<NM;i++){
        !           179:                        if(contab[i].rq == 0)break;
        !           180:                }
        !           181:                if((i==NM) ||
        !           182:                   (nextb = alloc()) == 0){
        !           183:                        app = 0;
        !           184:                        if(macerr++ > 1)done2(02);
        !           185:                        prstr("Too many string/macro names.\n");
        !           186:                        edone(04);
        !           187:                        return(offset = 0);
        !           188:                }
        !           189:                        contab[i].x.mx = (unsigned)(nextb>>BLKBITS);
        !           190:                if(!diflg){
        !           191:                        newmn = i;
        !           192:                        if(oldmn == -1)contab[i].rq = -1;
        !           193:                }else{
        !           194:                        contab[i].rq = mn | MMASK;
        !           195:                }
        !           196:        }
        !           197: 
        !           198:        app = 0;
        !           199:        return(offset = nextb);
        !           200: }
        !           201: skip(){
        !           202:        register i;
        !           203: 
        !           204:        while(((i=getch()) & CMASK) == ' ');
        !           205:        ch=i;
        !           206:        return(nlflg);
        !           207: }
        !           208: copyb()
        !           209: {
        !           210:        register i, j, k;
        !           211:        int ii, req, state;
        !           212:        filep savoff;
        !           213: 
        !           214:        if(skip() || !(j=getrq()))j = '.';
        !           215:        req = j;
        !           216:        k = j>>BYTE;
        !           217:        j &= BMASK;
        !           218:        copyf++;
        !           219:        flushi();
        !           220:        nlflg = 0;
        !           221:        state = 1;
        !           222:        while(1){
        !           223:                i = (ii = getch()) & CMASK;
        !           224:                if(state == 3){
        !           225:                        if(i == k)break;
        !           226:                        if(!k){
        !           227:                                ch = ii;
        !           228:                                i = getach();
        !           229:                                ch = ii;
        !           230:                                if(!i)break;
        !           231:                        }
        !           232:                        state = 0;
        !           233:                        goto c0;
        !           234:                }
        !           235:                if(i == '\n'){
        !           236:                        state = 1;
        !           237:                        nlflg = 0;
        !           238:                        goto c0;
        !           239:                }
        !           240:                if((state == 1) && (i == '.')){
        !           241:                        state++;
        !           242:                        savoff = offset;
        !           243:                        goto c0;
        !           244:                }
        !           245:                if((state == 2) && (i == j)){
        !           246:                        state++;
        !           247:                        goto c0;
        !           248:                }
        !           249:                state = 0;
        !           250: c0:
        !           251:                if(offset)wbf(ii);
        !           252:        }
        !           253:        if(offset){
        !           254:                wbfl();
        !           255:                offset = savoff;
        !           256:                wbt(0);
        !           257:        }
        !           258:        copyf--;
        !           259:        return(req);
        !           260: }
        !           261: copys()
        !           262: {
        !           263:        register i;
        !           264: 
        !           265:        copyf++;
        !           266:        if(skip())goto c0;
        !           267:        if(((i=getch()) & CMASK) != '"')wbf(i);
        !           268:        while(((i=getch()) & CMASK) != '\n')wbf(i);
        !           269: c0:
        !           270:        wbt(0);
        !           271:        copyf--;
        !           272: }
        !           273: filep alloc()
        !           274: {
        !           275:        register i;
        !           276:        extern filep boff();
        !           277:        filep j;
        !           278: 
        !           279:        for(i=0;i<NBLIST;i++){
        !           280:                if(blist[i] == 0)break;
        !           281:        }
        !           282:        if(i==NBLIST){
        !           283:                j = 0;
        !           284:        }else{
        !           285:                blist[i] = -1;
        !           286:                if((j = boff(i)) < NEV*EVS)j = 0;
        !           287:        }
        !           288:        return(nextb = j);
        !           289: }
        !           290: ffree(i)
        !           291: filep i;
        !           292: {
        !           293:        register j;
        !           294: 
        !           295:        while((blist[j = blisti(i)]) != -1){
        !           296:                i = ((filep)blist[j])<<BLKBITS;
        !           297:                blist[j] = 0;
        !           298:        }
        !           299:        blist[j] = 0;
        !           300: }
        !           301: filep boff(i)
        !           302: int i;
        !           303: {
        !           304:        return(((filep)i)*BLK + NEV*EVS);
        !           305: }
        !           306: wbt(i)
        !           307: int i;
        !           308: {
        !           309:        wbf(i);
        !           310:        wbfl();
        !           311: }
        !           312: wbf(i)
        !           313: int i;
        !           314: {
        !           315:        register j;
        !           316: 
        !           317:        if(!offset)return;
        !           318:        if(!woff){
        !           319:                woff = offset;
        !           320: #ifdef VMUNIX
        !           321:                wbuf = &Buf[woff];
        !           322: #endif
        !           323:                wbfi = 0;
        !           324:        }
        !           325:        wbuf[wbfi++] = i;
        !           326:        if(!((++offset) & (BLK-1))){
        !           327:                wbfl();
        !           328:                if(blist[j = blisti(--offset)] == -1){
        !           329:                        if(alloc() == 0){
        !           330:                                prstr("Out of temp file space.\n");
        !           331:                                done2(01);
        !           332:                        }
        !           333:                        blist[j] = (unsigned)(nextb>>BLKBITS);
        !           334:                }
        !           335:                offset = ((filep)blist[j])<<BLKBITS;
        !           336:        }
        !           337:        if(wbfi >= BLK)wbfl();
        !           338: }
        !           339: wbfl(){
        !           340:        if(woff == 0)return;
        !           341: #ifndef VMUNIX
        !           342:        lseek(ibf, ((long)woff) * sizeof(int), 0);
        !           343:        write(ibf, (char *)wbuf, wbfi * sizeof(int));
        !           344: #endif
        !           345:        if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1;
        !           346:        woff = 0;
        !           347: }
        !           348: blisti(i)
        !           349: filep i;
        !           350: {
        !           351:        return((i-NEV*EVS)/(BLK));
        !           352: }
        !           353: rbf(){
        !           354:        register i;
        !           355:        extern filep incoff();
        !           356: 
        !           357:        if((i=rbf0(ip)) == 0){
        !           358:                if(!app)i = popi();
        !           359:        }else{
        !           360:                ip = incoff(ip);
        !           361:        }
        !           362:        return(i);
        !           363: }
        !           364: rbf0(p)
        !           365: filep p;
        !           366: {
        !           367:        register filep i;
        !           368: 
        !           369:        if((i = (p & (~(BLK-1)))) != roff){
        !           370:                roff = i;
        !           371: #ifndef VMUNIX
        !           372:                lseek(ibf, ((long)roff) * sizeof(int), 0);
        !           373:                if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0);
        !           374: #else
        !           375:                rbuf = &Buf[roff];
        !           376: #endif
        !           377:        }
        !           378:        return(rbuf[p & (BLK-1)]);
        !           379: }
        !           380: filep incoff(p)
        !           381: filep p;
        !           382: {
        !           383:        register i;
        !           384:        register filep j;
        !           385:        if(!((j = (++p)) & (BLK-1))){
        !           386:                if((i = blist[blisti(--p)]) == -1){
        !           387:                        prstr("Bad storage allocation.\n");
        !           388:                        done2(-5);
        !           389:                }
        !           390:                j = ((filep)i)<<BLKBITS;
        !           391:        }
        !           392:        return(j);
        !           393: }
        !           394: popi(){
        !           395:        register struct s *p;
        !           396: 
        !           397:        if(frame == stk)return(0);
        !           398:        if(strflg)strflg--;
        !           399:        p = nxf = frame;
        !           400:        p->nargs = 0;
        !           401:        frame = p->pframe;
        !           402:        ip = p->pip;
        !           403:        nchar = p->pnchar;
        !           404:        rchar = p->prchar;
        !           405:        pendt = p->ppendt;
        !           406:        ap = p->pap;
        !           407:        cp = p->pcp;
        !           408:        ch0 = p->pch0;
        !           409:        return(p->pch);
        !           410: }
        !           411: pushi(newip)
        !           412: filep newip;
        !           413: {
        !           414:        register struct s *p;
        !           415:        extern char *setbrk();
        !           416: 
        !           417:        if((enda - sizeof(struct s)) < (char *)nxf)setbrk(DELTA);
        !           418:        p = nxf;
        !           419:        p->pframe = frame;
        !           420:        p->pip = ip;
        !           421:        p->pnchar = nchar;
        !           422:        p->prchar = rchar;
        !           423:        p->ppendt = pendt;
        !           424:        p->pap = ap;
        !           425:        p->pcp = cp;
        !           426:        p->pch0 = ch0;
        !           427:        p->pch = ch;
        !           428:        cp = ap = 0;
        !           429:        nchar = rchar = pendt = ch0 = ch = 0;
        !           430:        frame = nxf;
        !           431:        if(nxf->nargs == 0) nxf += 1;
        !           432:                else nxf = (struct s *)argtop;
        !           433:        return(ip = newip);
        !           434: }
        !           435: char *setbrk(x)
        !           436: int x;
        !           437: {
        !           438:        register char *i;
        !           439:        char *sbrk();
        !           440: 
        !           441:        if((i = sbrk(x)) == MAXPTR){
        !           442:                prstrfl("Core limit reached.\n");
        !           443:                edone(0100);
        !           444:        }else{
        !           445:                enda = i + x;
        !           446:        }
        !           447:        return(i);
        !           448: }
        !           449: getsn(){
        !           450:        register i;
        !           451: 
        !           452:        if((i=getach()) == 0)return(0);
        !           453:        if(i == '(')return(getrq());
        !           454:                else return(i);
        !           455: }
        !           456: setstr(){
        !           457:        register i;
        !           458: 
        !           459:        lgf++;
        !           460:        if(((i=getsn()) == 0) ||
        !           461:           ((i=findmn(i)) == -1) ||
        !           462:           !(contab[i].rq & MMASK)){
        !           463:                lgf--;
        !           464:                return(0);
        !           465:        }else{
        !           466:                if((enda-2) < (char *)nxf)setbrk(DELTA);
        !           467:                nxf->nargs = 0;
        !           468:                strflg++;
        !           469:                lgf--;
        !           470:                return(pushi(((filep)contab[i].x.mx)<<BLKBITS));
        !           471:        }
        !           472: }
        !           473: collect()
        !           474: {
        !           475:        register i;
        !           476:        register int *strp;
        !           477:        int *lim;
        !           478:        int **argpp, **argppend;
        !           479:        int quote;
        !           480:        struct s *savnxf;
        !           481: 
        !           482:        copyf++;
        !           483:        nxf->nargs = 0;
        !           484:        savnxf = nxf;
        !           485:        if(skip())goto rtn;
        !           486:        lim = (int *)(nxf = savnxf + sizeof(struct s)/sizeof(savnxf));
        !           487:        strflg = 0;
        !           488:        if((argppend =
        !           489:                (argpp = (int **)savnxf+(sizeof(struct s)/sizeof(int **))) + 9)
        !           490:                > (int **)enda)setbrk(DELTA);
        !           491:        strp = (int *)argppend;
        !           492:        for(i=8; i>=0; i--)argpp[i] = 0;
        !           493:        while((argpp != argppend) && (!skip())){
        !           494:                *argpp++ = strp;
        !           495:                quote = 0;
        !           496:                if(((i = getch()) & CMASK) == '"')quote++;
        !           497:                        else ch = i;
        !           498:                while(1){
        !           499:                        i = getch();
        !           500:                        if( nlflg ||
        !           501:                          ((!quote) && ((i & CMASK) == ' ')))break;
        !           502:                        if(quote && ((i & CMASK) == '"') &&
        !           503:                          (((i=getch()) & CMASK) != '"')){
        !           504:                                ch = i;
        !           505:                                break;
        !           506:                        }
        !           507:                        *strp++ = i;
        !           508:                        if(strflg && (strp >= lim)){
        !           509:                                prstrfl("Macro argument too long.\n");
        !           510:                                copyf--;
        !           511:                                edone(004);
        !           512:                        }
        !           513:                        if((enda-4) <= (char *)strp)setbrk(DELTA);
        !           514:                }
        !           515:                *strp++ = 0;
        !           516:        }
        !           517:        nxf = savnxf;
        !           518:        nxf->nargs = argpp -(int **)(nxf + 1);
        !           519:        argtop = strp;
        !           520: rtn:
        !           521:        copyf--;
        !           522: }
        !           523: seta()
        !           524: {
        !           525:        register i;
        !           526: 
        !           527:        if(((i = (getch() & CMASK) - '0') > 0) &&
        !           528:                (i <= 9) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **)));
        !           529: }
        !           530: caseda(){
        !           531:        app++;
        !           532:        casedi();
        !           533: }
        !           534: casedi(){
        !           535:        register i, j;
        !           536:        register *k;
        !           537: 
        !           538:        lgf++;
        !           539:        if(skip() || ((i=getrq()) == 0)){
        !           540:                if(dip != d)wbt(0);
        !           541:                if(dilev > 0){
        !           542:                        v.dn = dip->dnl;
        !           543:                        v.dl = dip->maxl;
        !           544:                        dip = &d[--dilev];
        !           545:                        offset = dip->op;
        !           546:                }
        !           547:                goto rtn;
        !           548:        }
        !           549:        if(++dilev == NDI){
        !           550:                --dilev;
        !           551:                prstr("Cannot divert.\n");
        !           552:                edone(02);
        !           553:        }
        !           554:        if(dip != d)wbt(0);
        !           555:        diflg++;
        !           556:        dip = &d[dilev];
        !           557:        dip->op = finds(i);
        !           558:        dip->curd = i;
        !           559:        clrmn(oldmn);
        !           560:        k = (int *)&dip->dnl;
        !           561:        for(j=0; j<10; j++)k[j] = 0;    /*not op and curd*/
        !           562: rtn:
        !           563:        app = 0;
        !           564:        diflg = 0;
        !           565: }
        !           566: casedt(){
        !           567:        lgf++;
        !           568:        dip->dimac = dip->ditrap = dip->ditf = 0;
        !           569:        skip();
        !           570:        dip->ditrap = vnumb((int *)0);
        !           571:        if(nonumb)return;
        !           572:        skip();
        !           573:        dip->dimac = getrq();
        !           574: }
        !           575: casetl(){
        !           576:        register i, j;
        !           577:        int w1, w2, w3, delim;
        !           578:        filep begin;
        !           579:        extern width(), pchar();
        !           580: 
        !           581:        dip->nls = 0;
        !           582:        skip();
        !           583:        if(dip != d)wbfl();
        !           584:        if((offset = begin = alloc()) == 0)return;
        !           585:        if((delim = getch()) & MOT){
        !           586:                ch = delim;
        !           587:                delim = '\'';
        !           588:        }else delim &= CMASK;
        !           589:        if(!nlflg)
        !           590:                while(((i = getch()) & CMASK) != '\n'){
        !           591:                        if((i & CMASK) == delim)i = IMP;
        !           592:                        wbf(i);
        !           593:                }
        !           594:        wbf(IMP);wbf(IMP);wbt(0);
        !           595: 
        !           596:        w1 = hseg(width,begin);
        !           597:        w2 = hseg(width,(filep)0);
        !           598:        w3 = hseg(width,(filep)0);
        !           599:        offset = dip->op;
        !           600: #ifdef NROFF
        !           601:        if(!offset)horiz(po);
        !           602: #endif
        !           603:        hseg(pchar,begin);
        !           604:        if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR));
        !           605:        hseg(pchar,(filep)0);
        !           606:        if(w3){
        !           607:                horiz(lt-w1-w2-w3-j);
        !           608:                hseg(pchar,(filep)0);
        !           609:        }
        !           610:        newline(0);
        !           611:        if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;}
        !           612:        else{if(v.nl > dip->hnl)dip->hnl = v.nl;}
        !           613:        ffree(begin);
        !           614: }
        !           615: casepc(){
        !           616:        pagech = chget(IMP);
        !           617: }
        !           618: hseg(f,p)
        !           619: int (*f)();
        !           620: filep p;
        !           621: {
        !           622:        register acc, i;
        !           623:        static filep q;
        !           624: 
        !           625:        acc = 0;
        !           626:        if(p)q = p;
        !           627:        while(1){
        !           628:                i = rbf0(q);
        !           629:                q = incoff(q);
        !           630:                if(!i || (i == IMP))return(acc);
        !           631:                if((i & CMASK) == pagech){
        !           632:                        nrbits = i & ~CMASK;
        !           633:                        nform = fmt[findr('%')];
        !           634:                        acc += fnumb(v.pn,f);
        !           635:                }else acc += (*f)(i);
        !           636:        }
        !           637: }
        !           638: casepm(){
        !           639:        register i, k;
        !           640:        register char *p;
        !           641:        int xx, cnt, kk, tot;
        !           642:        filep j;
        !           643:        char *kvt();
        !           644:        char pmline[10];
        !           645: 
        !           646:        kk = cnt = 0;
        !           647:        tot = !skip();
        !           648:        for(i = 0; i<NM; i++){
        !           649:                if(!((xx = contab[i].rq) & MMASK))continue;
        !           650:                p = pmline;
        !           651:                j = (((filep)contab[i].x.mx)<<BLKBITS);
        !           652:                k = 1;
        !           653:                while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;}
        !           654:                cnt++;
        !           655:                kk += k;
        !           656:                if(!tot){
        !           657:                        *p++ = xx & 0177;
        !           658:                        if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' ';
        !           659:                        *p++ = ' ';
        !           660:                        kvt(k,p);
        !           661:                        prstr(pmline);
        !           662:                }
        !           663:        }
        !           664:        if(tot || (cnt > 1)){
        !           665:                kvt(kk,pmline);
        !           666:                prstr(pmline);
        !           667:        }
        !           668: }
        !           669: char *kvt(k,p)
        !           670: int k;
        !           671: char *p;
        !           672: {
        !           673:        if(k>=100)*p++ = k/100 + '0';
        !           674:        if(k>=10)*p++ = (k%100)/10 + '0';
        !           675:        *p++ = k%10 + '0';
        !           676:        *p++ = '\n';
        !           677:        *p = 0;
        !           678:        return(p);
        !           679: }
        !           680: dummy(){}

unix.superglobalmegacorp.com

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