17067Srrh #ifndef lint 2*8921Srrh static char sccsid[] = "@(#)n3.c 4.2 10/28/82"; 37067Srrh #endif lint 47067Srrh 57067Srrh #include "tdef.h" 67067Srrh extern 77067Srrh #include "d.h" 87067Srrh extern 97067Srrh #include "v.h" 107067Srrh #ifdef NROFF 117067Srrh extern 127067Srrh #include "tw.h" 137067Srrh #endif 147067Srrh #include "sdef.h" 157067Srrh 167067Srrh /* 177067Srrh troff3.c 187067Srrh 197067Srrh macro and string routines, storage allocation 207067Srrh */ 217067Srrh 227067Srrh unsigned blist[NBLIST]; 237067Srrh extern struct s *frame, *stk, *nxf; 247067Srrh extern filep ip; 257067Srrh extern filep offset; 267067Srrh extern filep nextb; 277067Srrh extern char *enda; 287067Srrh 297067Srrh extern int ch; 307067Srrh extern int ibf; 317067Srrh extern int lgf; 327067Srrh extern int copyf; 337067Srrh extern int ch0; 347067Srrh extern int app; 357067Srrh extern int ds; 367067Srrh extern int nlflg; 377067Srrh extern int *argtop; 387067Srrh extern int *ap; 397067Srrh extern int nchar; 407067Srrh extern int pendt; 417067Srrh extern int rchar; 427067Srrh extern int dilev; 437067Srrh extern int nonumb; 447067Srrh extern int lt; 457067Srrh extern int nrbits; 467067Srrh extern int nform; 477067Srrh extern int fmt[]; 487067Srrh extern int oldmn; 497067Srrh extern int newmn; 507067Srrh extern int macerr; 517067Srrh extern filep apptr; 527067Srrh extern int diflg; 537067Srrh extern filep woff; 547067Srrh extern filep roff; 557067Srrh extern int wbfi; 567067Srrh extern int po; 577067Srrh extern int *cp; 587067Srrh extern int xxx; 597067Srrh int pagech = '%'; 607067Srrh int strflg; 617067Srrh extern struct contab { 627067Srrh int rq; 637067Srrh union { 647067Srrh int (*f)(); 657067Srrh unsigned mx; 667067Srrh }x; 677067Srrh }contab[NM]; 687067Srrh #ifndef VMUNIX 697067Srrh int wbuf[BLK]; 707067Srrh int rbuf[BLK]; 717067Srrh #else 727067Srrh int *wbuf; 737067Srrh int *rbuf; 747067Srrh int Buf[NBLIST*BLK + NEV*EVS]; 757067Srrh #endif 767067Srrh 777067Srrh caseig(){ 787067Srrh register i; 797067Srrh 807067Srrh offset = 0; 817067Srrh if((i = copyb()) != '.')control(i,1); 827067Srrh } 837067Srrh casern(){ 847067Srrh register i,j; 857067Srrh 867067Srrh lgf++; 877067Srrh skip(); 887067Srrh if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return; 897067Srrh skip(); 907067Srrh clrmn(findmn(j=getrq())); 917067Srrh if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j; 927067Srrh } 937067Srrh caserm(){ 947067Srrh lgf++; 957067Srrh while(!skip()){ 967067Srrh clrmn(findmn(getrq())); 977067Srrh } 987067Srrh } 997067Srrh caseas(){ 1007067Srrh app++; 1017067Srrh caseds(); 1027067Srrh } 1037067Srrh caseds(){ 1047067Srrh ds++; 1057067Srrh casede(); 1067067Srrh } 1077067Srrh caseam(){ 1087067Srrh app++; 1097067Srrh casede(); 1107067Srrh } 1117067Srrh casede(){ 1127067Srrh register i, req; 1137067Srrh register filep savoff; 1147067Srrh extern filep finds(); 1157067Srrh 1167067Srrh if(dip != d)wbfl(); 1177067Srrh req = '.'; 1187067Srrh lgf++; 1197067Srrh skip(); 1207067Srrh if((i=getrq())==0)goto de1; 1217067Srrh if((offset=finds(i)) == 0)goto de1; 1227067Srrh if(ds)copys(); 1237067Srrh else req = copyb(); 1247067Srrh wbfl(); 1257067Srrh clrmn(oldmn); 1267067Srrh if(newmn)contab[newmn].rq = i | MMASK; 1277067Srrh if(apptr){ 1287067Srrh savoff = offset; 1297067Srrh offset = apptr; 1307067Srrh wbt(IMP); 1317067Srrh offset = savoff; 1327067Srrh } 1337067Srrh offset = dip->op; 1347067Srrh if(req != '.')control(req,1); 1357067Srrh de1: 1367067Srrh ds = app = 0; 1377067Srrh return; 1387067Srrh } 1397067Srrh findmn(i) 1407067Srrh int i; 1417067Srrh { 1427067Srrh register j; 1437067Srrh 1447067Srrh for(j=0;j<NM;j++){ 1457067Srrh if(i == (contab[j].rq & ~MMASK))break; 1467067Srrh } 1477067Srrh if(j==NM)j = -1; 1487067Srrh return(j); 1497067Srrh } 1507067Srrh clrmn(i) 1517067Srrh int i; 1527067Srrh { 1537067Srrh extern filep boff(); 1547067Srrh if(i >= 0){ 1557067Srrh if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS); 1567067Srrh contab[i].rq = 0; 1577067Srrh contab[i].x.mx = 0; 1587067Srrh } 1597067Srrh } 1607067Srrh filep finds(mn) 1617067Srrh int mn; 1627067Srrh { 1637067Srrh register i; 1647067Srrh extern filep boff(); 1657067Srrh register filep savip; 1667067Srrh extern filep alloc(); 1677067Srrh extern filep incoff(); 1687067Srrh 1697067Srrh oldmn = findmn(mn); 1707067Srrh newmn = 0; 1717067Srrh apptr = (filep)0; 1727067Srrh if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){ 1737067Srrh savip = ip; 1747067Srrh ip = (((filep)contab[oldmn].x.mx)<<BLKBITS); 1757067Srrh oldmn = -1; 1767067Srrh while((i=rbf()) != 0); 1777067Srrh apptr = ip; 1787067Srrh if(!diflg)ip = incoff(ip); 1797067Srrh nextb = ip; 1807067Srrh ip = savip; 1817067Srrh }else{ 1827067Srrh for(i=0;i<NM;i++){ 1837067Srrh if(contab[i].rq == 0)break; 1847067Srrh } 1857067Srrh if((i==NM) || 1867067Srrh (nextb = alloc()) == 0){ 1877067Srrh app = 0; 1887067Srrh if(macerr++ > 1)done2(02); 1897067Srrh prstr("Too many string/macro names.\n"); 1907067Srrh edone(04); 1917067Srrh return(offset = 0); 1927067Srrh } 1937067Srrh contab[i].x.mx = (unsigned)(nextb>>BLKBITS); 1947067Srrh if(!diflg){ 1957067Srrh newmn = i; 1967067Srrh if(oldmn == -1)contab[i].rq = -1; 1977067Srrh }else{ 1987067Srrh contab[i].rq = mn | MMASK; 1997067Srrh } 2007067Srrh } 2017067Srrh 2027067Srrh app = 0; 2037067Srrh return(offset = nextb); 2047067Srrh } 2057067Srrh skip(){ 2067067Srrh register i; 2077067Srrh 2087067Srrh while(((i=getch()) & CMASK) == ' '); 2097067Srrh ch=i; 2107067Srrh return(nlflg); 2117067Srrh } 2127067Srrh copyb() 2137067Srrh { 2147067Srrh register i, j, k; 2157067Srrh int ii, req, state; 2167067Srrh filep savoff; 2177067Srrh 2187067Srrh if(skip() || !(j=getrq()))j = '.'; 2197067Srrh req = j; 2207067Srrh k = j>>BYTE; 2217067Srrh j &= BMASK; 2227067Srrh copyf++; 2237067Srrh flushi(); 2247067Srrh nlflg = 0; 2257067Srrh state = 1; 2267067Srrh while(1){ 2277067Srrh i = (ii = getch()) & CMASK; 2287067Srrh if(state == 3){ 2297067Srrh if(i == k)break; 2307067Srrh if(!k){ 2317067Srrh ch = ii; 2327067Srrh i = getach(); 2337067Srrh ch = ii; 2347067Srrh if(!i)break; 2357067Srrh } 2367067Srrh state = 0; 2377067Srrh goto c0; 2387067Srrh } 2397067Srrh if(i == '\n'){ 2407067Srrh state = 1; 2417067Srrh nlflg = 0; 2427067Srrh goto c0; 2437067Srrh } 2447067Srrh if((state == 1) && (i == '.')){ 2457067Srrh state++; 2467067Srrh savoff = offset; 2477067Srrh goto c0; 2487067Srrh } 2497067Srrh if((state == 2) && (i == j)){ 2507067Srrh state++; 2517067Srrh goto c0; 2527067Srrh } 2537067Srrh state = 0; 2547067Srrh c0: 2557067Srrh if(offset)wbf(ii); 2567067Srrh } 2577067Srrh if(offset){ 2587067Srrh wbfl(); 2597067Srrh offset = savoff; 2607067Srrh wbt(0); 2617067Srrh } 2627067Srrh copyf--; 2637067Srrh return(req); 2647067Srrh } 2657067Srrh copys() 2667067Srrh { 2677067Srrh register i; 2687067Srrh 2697067Srrh copyf++; 2707067Srrh if(skip())goto c0; 2717067Srrh if(((i=getch()) & CMASK) != '"')wbf(i); 2727067Srrh while(((i=getch()) & CMASK) != '\n')wbf(i); 2737067Srrh c0: 2747067Srrh wbt(0); 2757067Srrh copyf--; 2767067Srrh } 2777067Srrh filep alloc() 2787067Srrh { 2797067Srrh register i; 2807067Srrh extern filep boff(); 2817067Srrh filep j; 2827067Srrh 2837067Srrh for(i=0;i<NBLIST;i++){ 2847067Srrh if(blist[i] == 0)break; 2857067Srrh } 2867067Srrh if(i==NBLIST){ 2877067Srrh j = 0; 2887067Srrh }else{ 2897067Srrh blist[i] = -1; 2907067Srrh if((j = boff(i)) < NEV*EVS)j = 0; 2917067Srrh } 2927067Srrh return(nextb = j); 2937067Srrh } 2947067Srrh ffree(i) 2957067Srrh filep i; 2967067Srrh { 2977067Srrh register j; 2987067Srrh 2997067Srrh while((blist[j = blisti(i)]) != -1){ 3007067Srrh i = ((filep)blist[j])<<BLKBITS; 3017067Srrh blist[j] = 0; 3027067Srrh } 3037067Srrh blist[j] = 0; 3047067Srrh } 3057067Srrh filep boff(i) 3067067Srrh int i; 3077067Srrh { 3087067Srrh return(((filep)i)*BLK + NEV*EVS); 3097067Srrh } 3107067Srrh wbt(i) 3117067Srrh int i; 3127067Srrh { 3137067Srrh wbf(i); 3147067Srrh wbfl(); 3157067Srrh } 3167067Srrh wbf(i) 3177067Srrh int i; 3187067Srrh { 3197067Srrh register j; 3207067Srrh 3217067Srrh if(!offset)return; 3227067Srrh if(!woff){ 3237067Srrh woff = offset; 3247067Srrh #ifdef VMUNIX 3257067Srrh wbuf = &Buf[woff]; 3267067Srrh #endif 3277067Srrh wbfi = 0; 3287067Srrh } 3297067Srrh wbuf[wbfi++] = i; 3307067Srrh if(!((++offset) & (BLK-1))){ 3317067Srrh wbfl(); 3327067Srrh if(blist[j = blisti(--offset)] == -1){ 3337067Srrh if(alloc() == 0){ 3347067Srrh prstr("Out of temp file space.\n"); 3357067Srrh done2(01); 3367067Srrh } 3377067Srrh blist[j] = (unsigned)(nextb>>BLKBITS); 3387067Srrh } 3397067Srrh offset = ((filep)blist[j])<<BLKBITS; 3407067Srrh } 3417067Srrh if(wbfi >= BLK)wbfl(); 3427067Srrh } 3437067Srrh wbfl(){ 3447067Srrh if(woff == 0)return; 3457067Srrh #ifndef VMUNIX 3467067Srrh lseek(ibf, ((long)woff) * sizeof(int), 0); 3477067Srrh write(ibf, (char *)wbuf, wbfi * sizeof(int)); 3487067Srrh #endif 3497067Srrh if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1; 3507067Srrh woff = 0; 3517067Srrh } 3527067Srrh blisti(i) 3537067Srrh filep i; 3547067Srrh { 3557067Srrh return((i-NEV*EVS)/(BLK)); 3567067Srrh } 3577067Srrh rbf(){ 3587067Srrh register i; 3597067Srrh extern filep incoff(); 3607067Srrh 3617067Srrh if((i=rbf0(ip)) == 0){ 3627067Srrh if(!app)i = popi(); 3637067Srrh }else{ 3647067Srrh ip = incoff(ip); 3657067Srrh } 3667067Srrh return(i); 3677067Srrh } 3687067Srrh rbf0(p) 3697067Srrh filep p; 3707067Srrh { 3717067Srrh register filep i; 3727067Srrh 3737067Srrh if((i = (p & (~(BLK-1)))) != roff){ 3747067Srrh roff = i; 3757067Srrh #ifndef VMUNIX 3767067Srrh lseek(ibf, ((long)roff) * sizeof(int), 0); 3777067Srrh if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0); 3787067Srrh #else 3797067Srrh rbuf = &Buf[roff]; 3807067Srrh #endif 3817067Srrh } 3827067Srrh return(rbuf[p & (BLK-1)]); 3837067Srrh } 3847067Srrh filep incoff(p) 3857067Srrh filep p; 3867067Srrh { 3877067Srrh register i; 3887067Srrh register filep j; 3897067Srrh if(!((j = (++p)) & (BLK-1))){ 3907067Srrh if((i = blist[blisti(--p)]) == -1){ 3917067Srrh prstr("Bad storage allocation.\n"); 3927067Srrh done2(-5); 3937067Srrh } 3947067Srrh j = ((filep)i)<<BLKBITS; 3957067Srrh } 3967067Srrh return(j); 3977067Srrh } 3987067Srrh popi(){ 3997067Srrh register struct s *p; 4007067Srrh 4017067Srrh if(frame == stk)return(0); 4027067Srrh if(strflg)strflg--; 4037067Srrh p = nxf = frame; 4047067Srrh p->nargs = 0; 4057067Srrh frame = p->pframe; 4067067Srrh ip = p->pip; 4077067Srrh nchar = p->pnchar; 4087067Srrh rchar = p->prchar; 4097067Srrh pendt = p->ppendt; 4107067Srrh ap = p->pap; 4117067Srrh cp = p->pcp; 4127067Srrh ch0 = p->pch0; 4137067Srrh return(p->pch); 4147067Srrh } 415*8921Srrh 416*8921Srrh /* 417*8921Srrh * test that the end of the allocation is above a certain location 418*8921Srrh * in memory 419*8921Srrh */ 420*8921Srrh #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);} 421*8921Srrh 4227067Srrh pushi(newip) 4237067Srrh filep newip; 4247067Srrh { 4257067Srrh register struct s *p; 426*8921Srrh extern char *setbrk(); 4277067Srrh 428*8921Srrh SPACETEST(nxf, sizeof(struct s)); 4297067Srrh p = nxf; 4307067Srrh p->pframe = frame; 4317067Srrh p->pip = ip; 4327067Srrh p->pnchar = nchar; 4337067Srrh p->prchar = rchar; 4347067Srrh p->ppendt = pendt; 4357067Srrh p->pap = ap; 4367067Srrh p->pcp = cp; 4377067Srrh p->pch0 = ch0; 4387067Srrh p->pch = ch; 4397067Srrh cp = ap = 0; 4407067Srrh nchar = rchar = pendt = ch0 = ch = 0; 4417067Srrh frame = nxf; 442*8921Srrh if (nxf->nargs == 0) 443*8921Srrh nxf += 1; 444*8921Srrh else 445*8921Srrh nxf = (struct s *)argtop; 4467067Srrh return(ip = newip); 4477067Srrh } 448*8921Srrh 449*8921Srrh 450*8921Srrh char *setbrk(x) 451*8921Srrh int x; 4527067Srrh { 453*8921Srrh register char *i; 454*8921Srrh char *sbrk(); 4557067Srrh 456*8921Srrh /* ought to be rounded up by sizeof(int) */ 457*8921Srrh if (x % 2 == 1) 458*8921Srrh x++; 459*8921Srrh if ( (i = sbrk(x)) >= (char *)MAXPTR) { 4607067Srrh prstrfl("Core limit reached.\n"); 4617067Srrh edone(0100); 462*8921Srrh } else { 4637067Srrh enda = i + x; 4647067Srrh } 4657067Srrh return(i); 4667067Srrh } 467*8921Srrh 468*8921Srrh 469*8921Srrh getsn() 470*8921Srrh { 4717067Srrh register i; 4727067Srrh 473*8921Srrh if ((i = getach()) == 0) 474*8921Srrh return(0); 475*8921Srrh if (i == '(') 476*8921Srrh return(getrq()); 477*8921Srrh else 478*8921Srrh return(i); 4797067Srrh } 480*8921Srrh 481*8921Srrh 482*8921Srrh setstr() 483*8921Srrh { 4847067Srrh register i; 4857067Srrh 4867067Srrh lgf++; 487*8921Srrh if ( ((i = getsn()) == 0) 488*8921Srrh || ((i = findmn(i)) == -1) 489*8921Srrh || !(contab[i].rq & MMASK)) { 4907067Srrh lgf--; 4917067Srrh return(0); 492*8921Srrh } else { 493*8921Srrh SPACETEST(nxf, sizeof(struct s)); 4947067Srrh nxf->nargs = 0; 4957067Srrh strflg++; 4967067Srrh lgf--; 4977067Srrh return(pushi(((filep)contab[i].x.mx)<<BLKBITS)); 4987067Srrh } 4997067Srrh } 500*8921Srrh 501*8921Srrh typedef int tchar; 502*8921Srrh #define cbits(x) ((x) & CMASK) 503*8921Srrh 5047067Srrh collect() 5057067Srrh { 506*8921Srrh register j; 507*8921Srrh tchar i; 508*8921Srrh register tchar *strp; 509*8921Srrh tchar * lim; 510*8921Srrh tchar * *argpp, **argppend; 511*8921Srrh int quote; 5127067Srrh struct s *savnxf; 5137067Srrh 5147067Srrh copyf++; 5157067Srrh nxf->nargs = 0; 5167067Srrh savnxf = nxf; 517*8921Srrh if (skip()) 518*8921Srrh goto rtn; 519*8921Srrh 520*8921Srrh { 521*8921Srrh char *memp; 522*8921Srrh memp = (char *)savnxf; 523*8921Srrh /* 524*8921Srrh * 1 s structure for the macro descriptor 525*8921Srrh * APERMAC tchar *'s for pointers into the strings 526*8921Srrh * space for the tchar's themselves 527*8921Srrh */ 528*8921Srrh memp += sizeof(struct s); 529*8921Srrh /* 530*8921Srrh * CPERMAC (the total # of characters for ALL arguments) 531*8921Srrh * to a macros, has been carefully chosen 532*8921Srrh * so that the distance between stack frames is < DELTA 533*8921Srrh */ 534*8921Srrh #define CPERMAC 200 535*8921Srrh #define APERMAC 9 536*8921Srrh memp += APERMAC * sizeof(tchar *); 537*8921Srrh memp += CPERMAC * sizeof(tchar); 538*8921Srrh nxf = (struct s*)memp; 539*8921Srrh } 540*8921Srrh lim = (tchar *)nxf; 541*8921Srrh argpp = (tchar **)(savnxf + 1); 542*8921Srrh argppend = &argpp[APERMAC]; 543*8921Srrh SPACETEST(argppend, sizeof(tchar *)); 544*8921Srrh strp = (tchar *)argppend; 545*8921Srrh /* 546*8921Srrh * Zero out all the string pointers before filling them in. 547*8921Srrh */ 548*8921Srrh for (j = 0; j < APERMAC; j++){ 549*8921Srrh argpp[j] = (tchar *)0; 550*8921Srrh } 551*8921Srrh #if 0 552*8921Srrh fprintf(stderr, "savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x\n", 553*8921Srrh savnxf, nxf, argpp, strp, lim, enda); 554*8921Srrh #endif 0 5557067Srrh strflg = 0; 556*8921Srrh while ((argpp != argppend) && (!skip())) { 5577067Srrh *argpp++ = strp; 5587067Srrh quote = 0; 559*8921Srrh if (cbits(i = getch()) == '"') 560*8921Srrh quote++; 561*8921Srrh else 562*8921Srrh ch = i; 563*8921Srrh while (1) { 5647067Srrh i = getch(); 565*8921Srrh if ( nlflg || (!quote && cbits(i) == ' ')) 566*8921Srrh break; 567*8921Srrh if ( quote 568*8921Srrh && (cbits(i) == '"') 569*8921Srrh && (cbits(i = getch()) != '"')) { 5707067Srrh ch = i; 5717067Srrh break; 5727067Srrh } 5737067Srrh *strp++ = i; 574*8921Srrh if (strflg && (strp >= lim)) { 575*8921Srrh #if 0 576*8921Srrh fprintf(stderr, "strp=0x%x, lim = 0x%x\n", 577*8921Srrh strp, lim); 578*8921Srrh #endif 0 5797067Srrh prstrfl("Macro argument too long.\n"); 5807067Srrh copyf--; 5817067Srrh edone(004); 5827067Srrh } 583*8921Srrh SPACETEST(strp, 3 * sizeof(tchar)); 5847067Srrh } 5857067Srrh *strp++ = 0; 5867067Srrh } 5877067Srrh nxf = savnxf; 588*8921Srrh nxf->nargs = argpp - (tchar **)(savnxf + 1); 5897067Srrh argtop = strp; 5907067Srrh rtn: 5917067Srrh copyf--; 5927067Srrh } 593*8921Srrh 594*8921Srrh 5957067Srrh seta() 5967067Srrh { 5977067Srrh register i; 5987067Srrh 5997067Srrh if(((i = (getch() & CMASK) - '0') > 0) && 600*8921Srrh (i <= APERMAC) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **))); 6017067Srrh } 6027067Srrh caseda(){ 6037067Srrh app++; 6047067Srrh casedi(); 6057067Srrh } 6067067Srrh casedi(){ 6077067Srrh register i, j; 6087067Srrh register *k; 6097067Srrh 6107067Srrh lgf++; 6117067Srrh if(skip() || ((i=getrq()) == 0)){ 6127067Srrh if(dip != d)wbt(0); 6137067Srrh if(dilev > 0){ 6147067Srrh v.dn = dip->dnl; 6157067Srrh v.dl = dip->maxl; 6167067Srrh dip = &d[--dilev]; 6177067Srrh offset = dip->op; 6187067Srrh } 6197067Srrh goto rtn; 6207067Srrh } 6217067Srrh if(++dilev == NDI){ 6227067Srrh --dilev; 6237067Srrh prstr("Cannot divert.\n"); 6247067Srrh edone(02); 6257067Srrh } 6267067Srrh if(dip != d)wbt(0); 6277067Srrh diflg++; 6287067Srrh dip = &d[dilev]; 6297067Srrh dip->op = finds(i); 6307067Srrh dip->curd = i; 6317067Srrh clrmn(oldmn); 6327067Srrh k = (int *)&dip->dnl; 6337067Srrh for(j=0; j<10; j++)k[j] = 0; /*not op and curd*/ 6347067Srrh rtn: 6357067Srrh app = 0; 6367067Srrh diflg = 0; 6377067Srrh } 6387067Srrh casedt(){ 6397067Srrh lgf++; 6407067Srrh dip->dimac = dip->ditrap = dip->ditf = 0; 6417067Srrh skip(); 6427067Srrh dip->ditrap = vnumb((int *)0); 6437067Srrh if(nonumb)return; 6447067Srrh skip(); 6457067Srrh dip->dimac = getrq(); 6467067Srrh } 6477067Srrh casetl(){ 6487067Srrh register i, j; 6497067Srrh int w1, w2, w3, delim; 6507067Srrh filep begin; 6517067Srrh extern width(), pchar(); 6527067Srrh 6537067Srrh dip->nls = 0; 6547067Srrh skip(); 6557067Srrh if(dip != d)wbfl(); 6567067Srrh if((offset = begin = alloc()) == 0)return; 6577067Srrh if((delim = getch()) & MOT){ 6587067Srrh ch = delim; 6597067Srrh delim = '\''; 6607067Srrh }else delim &= CMASK; 6617067Srrh if(!nlflg) 6627067Srrh while(((i = getch()) & CMASK) != '\n'){ 6637067Srrh if((i & CMASK) == delim)i = IMP; 6647067Srrh wbf(i); 6657067Srrh } 6667067Srrh wbf(IMP);wbf(IMP);wbt(0); 6677067Srrh 6687067Srrh w1 = hseg(width,begin); 6697067Srrh w2 = hseg(width,(filep)0); 6707067Srrh w3 = hseg(width,(filep)0); 6717067Srrh offset = dip->op; 6727067Srrh #ifdef NROFF 6737067Srrh if(!offset)horiz(po); 6747067Srrh #endif 6757067Srrh hseg(pchar,begin); 6767067Srrh if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR)); 6777067Srrh hseg(pchar,(filep)0); 6787067Srrh if(w3){ 6797067Srrh horiz(lt-w1-w2-w3-j); 6807067Srrh hseg(pchar,(filep)0); 6817067Srrh } 6827067Srrh newline(0); 6837067Srrh if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} 6847067Srrh else{if(v.nl > dip->hnl)dip->hnl = v.nl;} 6857067Srrh ffree(begin); 6867067Srrh } 6877067Srrh casepc(){ 6887067Srrh pagech = chget(IMP); 6897067Srrh } 6907067Srrh hseg(f,p) 6917067Srrh int (*f)(); 6927067Srrh filep p; 6937067Srrh { 6947067Srrh register acc, i; 6957067Srrh static filep q; 6967067Srrh 6977067Srrh acc = 0; 6987067Srrh if(p)q = p; 6997067Srrh while(1){ 7007067Srrh i = rbf0(q); 7017067Srrh q = incoff(q); 7027067Srrh if(!i || (i == IMP))return(acc); 7037067Srrh if((i & CMASK) == pagech){ 7047067Srrh nrbits = i & ~CMASK; 7057067Srrh nform = fmt[findr('%')]; 7067067Srrh acc += fnumb(v.pn,f); 7077067Srrh }else acc += (*f)(i); 7087067Srrh } 7097067Srrh } 7107067Srrh casepm(){ 7117067Srrh register i, k; 7127067Srrh register char *p; 7137067Srrh int xx, cnt, kk, tot; 7147067Srrh filep j; 7157067Srrh char *kvt(); 7167067Srrh char pmline[10]; 7177067Srrh 7187067Srrh kk = cnt = 0; 7197067Srrh tot = !skip(); 7207067Srrh for(i = 0; i<NM; i++){ 7217067Srrh if(!((xx = contab[i].rq) & MMASK))continue; 7227067Srrh p = pmline; 7237067Srrh j = (((filep)contab[i].x.mx)<<BLKBITS); 7247067Srrh k = 1; 7257067Srrh while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;} 7267067Srrh cnt++; 7277067Srrh kk += k; 7287067Srrh if(!tot){ 7297067Srrh *p++ = xx & 0177; 7307067Srrh if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' '; 7317067Srrh *p++ = ' '; 7327067Srrh kvt(k,p); 7337067Srrh prstr(pmline); 7347067Srrh } 7357067Srrh } 7367067Srrh if(tot || (cnt > 1)){ 7377067Srrh kvt(kk,pmline); 7387067Srrh prstr(pmline); 7397067Srrh } 7407067Srrh } 7417067Srrh char *kvt(k,p) 7427067Srrh int k; 7437067Srrh char *p; 7447067Srrh { 7457067Srrh if(k>=100)*p++ = k/100 + '0'; 7467067Srrh if(k>=10)*p++ = (k%100)/10 + '0'; 7477067Srrh *p++ = k%10 + '0'; 7487067Srrh *p++ = '\n'; 7497067Srrh *p = 0; 7507067Srrh return(p); 7517067Srrh } 7527067Srrh dummy(){} 753