Annotation of 40BSD/cmd/troff/n3.c, revision 1.1.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 + NEV*EVS];
                     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.