17067Srrh #ifndef lint 2*31687Sbostic static char sccsid[] = "@(#)n3.c 4.4 06/25/87"; 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 } 4158921Srrh 4168921Srrh /* 4178921Srrh * test that the end of the allocation is above a certain location 4188921Srrh * in memory 4198921Srrh */ 4208921Srrh #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);} 4218921Srrh 4227067Srrh pushi(newip) 4237067Srrh filep newip; 4247067Srrh { 4257067Srrh register struct s *p; 4268921Srrh extern char *setbrk(); 4277067Srrh 4288921Srrh 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; 4428921Srrh if (nxf->nargs == 0) 4438921Srrh nxf += 1; 4448921Srrh else 4458921Srrh nxf = (struct s *)argtop; 4467067Srrh return(ip = newip); 4477067Srrh } 4488921Srrh 4498921Srrh 4508921Srrh char *setbrk(x) 4518921Srrh int x; 4527067Srrh { 4538921Srrh register char *i; 4548921Srrh char *sbrk(); 4557067Srrh 456*31687Sbostic x += sizeof(int) - 1; 457*31687Sbostic x &= ~(sizeof(int) - 1); 458*31687Sbostic if ((u_int)(i = sbrk(x)) == -1) { 4597067Srrh prstrfl("Core limit reached.\n"); 4607067Srrh edone(0100); 4618921Srrh } else { 4627067Srrh enda = i + x; 4637067Srrh } 4647067Srrh return(i); 4657067Srrh } 4668921Srrh 4678921Srrh 4688921Srrh getsn() 4698921Srrh { 4707067Srrh register i; 4717067Srrh 4728921Srrh if ((i = getach()) == 0) 4738921Srrh return(0); 4748921Srrh if (i == '(') 4758921Srrh return(getrq()); 4768921Srrh else 4778921Srrh return(i); 4787067Srrh } 4798921Srrh 4808921Srrh 4818921Srrh setstr() 4828921Srrh { 4837067Srrh register i; 4847067Srrh 4857067Srrh lgf++; 4868921Srrh if ( ((i = getsn()) == 0) 4878921Srrh || ((i = findmn(i)) == -1) 4888921Srrh || !(contab[i].rq & MMASK)) { 4897067Srrh lgf--; 4907067Srrh return(0); 4918921Srrh } else { 4928921Srrh SPACETEST(nxf, sizeof(struct s)); 4937067Srrh nxf->nargs = 0; 4947067Srrh strflg++; 4957067Srrh lgf--; 4967067Srrh return(pushi(((filep)contab[i].x.mx)<<BLKBITS)); 4977067Srrh } 4987067Srrh } 4998921Srrh 5008921Srrh typedef int tchar; 5018921Srrh #define cbits(x) ((x) & CMASK) 5028921Srrh 5037067Srrh collect() 5047067Srrh { 5058921Srrh register j; 5068921Srrh tchar i; 5078921Srrh register tchar *strp; 5088921Srrh tchar * lim; 5098921Srrh tchar * *argpp, **argppend; 5108921Srrh int quote; 5117067Srrh struct s *savnxf; 5127067Srrh 5137067Srrh copyf++; 5147067Srrh nxf->nargs = 0; 5157067Srrh savnxf = nxf; 5168921Srrh if (skip()) 5178921Srrh goto rtn; 5188921Srrh 5198921Srrh { 5208921Srrh char *memp; 5218921Srrh memp = (char *)savnxf; 5228921Srrh /* 5238921Srrh * 1 s structure for the macro descriptor 5248921Srrh * APERMAC tchar *'s for pointers into the strings 5258921Srrh * space for the tchar's themselves 5268921Srrh */ 5278921Srrh memp += sizeof(struct s); 5288921Srrh /* 5298921Srrh * CPERMAC (the total # of characters for ALL arguments) 5308921Srrh * to a macros, has been carefully chosen 5318921Srrh * so that the distance between stack frames is < DELTA 5328921Srrh */ 5338921Srrh #define CPERMAC 200 5348921Srrh #define APERMAC 9 5358921Srrh memp += APERMAC * sizeof(tchar *); 5368921Srrh memp += CPERMAC * sizeof(tchar); 5378921Srrh nxf = (struct s*)memp; 5388921Srrh } 5398921Srrh lim = (tchar *)nxf; 5408921Srrh argpp = (tchar **)(savnxf + 1); 5418921Srrh argppend = &argpp[APERMAC]; 5428921Srrh SPACETEST(argppend, sizeof(tchar *)); 5438921Srrh strp = (tchar *)argppend; 5448921Srrh /* 5458921Srrh * Zero out all the string pointers before filling them in. 5468921Srrh */ 5478921Srrh for (j = 0; j < APERMAC; j++){ 5488921Srrh argpp[j] = (tchar *)0; 5498921Srrh } 5508921Srrh #if 0 5518921Srrh fprintf(stderr, "savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x\n", 5528921Srrh savnxf, nxf, argpp, strp, lim, enda); 5538921Srrh #endif 0 5547067Srrh strflg = 0; 5558921Srrh while ((argpp != argppend) && (!skip())) { 5567067Srrh *argpp++ = strp; 5577067Srrh quote = 0; 5588921Srrh if (cbits(i = getch()) == '"') 5598921Srrh quote++; 5608921Srrh else 5618921Srrh ch = i; 5628921Srrh while (1) { 5637067Srrh i = getch(); 5648921Srrh if ( nlflg || (!quote && cbits(i) == ' ')) 5658921Srrh break; 5668921Srrh if ( quote 5678921Srrh && (cbits(i) == '"') 5688921Srrh && (cbits(i = getch()) != '"')) { 5697067Srrh ch = i; 5707067Srrh break; 5717067Srrh } 5727067Srrh *strp++ = i; 5738921Srrh if (strflg && (strp >= lim)) { 5748921Srrh #if 0 5758921Srrh fprintf(stderr, "strp=0x%x, lim = 0x%x\n", 5768921Srrh strp, lim); 5778921Srrh #endif 0 5787067Srrh prstrfl("Macro argument too long.\n"); 5797067Srrh copyf--; 5807067Srrh edone(004); 5817067Srrh } 5828921Srrh SPACETEST(strp, 3 * sizeof(tchar)); 5837067Srrh } 5847067Srrh *strp++ = 0; 5857067Srrh } 5867067Srrh nxf = savnxf; 5878921Srrh nxf->nargs = argpp - (tchar **)(savnxf + 1); 5887067Srrh argtop = strp; 5897067Srrh rtn: 5907067Srrh copyf--; 5917067Srrh } 5928921Srrh 5938921Srrh 5947067Srrh seta() 5957067Srrh { 5967067Srrh register i; 5977067Srrh 5987067Srrh if(((i = (getch() & CMASK) - '0') > 0) && 5998921Srrh (i <= APERMAC) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **))); 6007067Srrh } 6017067Srrh caseda(){ 6027067Srrh app++; 6037067Srrh casedi(); 6047067Srrh } 6057067Srrh casedi(){ 6067067Srrh register i, j; 6077067Srrh register *k; 6087067Srrh 6097067Srrh lgf++; 6107067Srrh if(skip() || ((i=getrq()) == 0)){ 6117067Srrh if(dip != d)wbt(0); 6127067Srrh if(dilev > 0){ 6137067Srrh v.dn = dip->dnl; 6147067Srrh v.dl = dip->maxl; 6157067Srrh dip = &d[--dilev]; 6167067Srrh offset = dip->op; 6177067Srrh } 6187067Srrh goto rtn; 6197067Srrh } 6207067Srrh if(++dilev == NDI){ 6217067Srrh --dilev; 6227067Srrh prstr("Cannot divert.\n"); 6237067Srrh edone(02); 6247067Srrh } 6257067Srrh if(dip != d)wbt(0); 6267067Srrh diflg++; 6277067Srrh dip = &d[dilev]; 6287067Srrh dip->op = finds(i); 6297067Srrh dip->curd = i; 6307067Srrh clrmn(oldmn); 6317067Srrh k = (int *)&dip->dnl; 6327067Srrh for(j=0; j<10; j++)k[j] = 0; /*not op and curd*/ 6337067Srrh rtn: 6347067Srrh app = 0; 6357067Srrh diflg = 0; 6367067Srrh } 6377067Srrh casedt(){ 6387067Srrh lgf++; 6397067Srrh dip->dimac = dip->ditrap = dip->ditf = 0; 6407067Srrh skip(); 6417067Srrh dip->ditrap = vnumb((int *)0); 6427067Srrh if(nonumb)return; 6437067Srrh skip(); 6447067Srrh dip->dimac = getrq(); 6457067Srrh } 6467067Srrh casetl(){ 6477067Srrh register i, j; 6487067Srrh int w1, w2, w3, delim; 6497067Srrh filep begin; 6507067Srrh extern width(), pchar(); 6517067Srrh 6527067Srrh dip->nls = 0; 6537067Srrh skip(); 6547067Srrh if(dip != d)wbfl(); 6557067Srrh if((offset = begin = alloc()) == 0)return; 6567067Srrh if((delim = getch()) & MOT){ 6577067Srrh ch = delim; 6587067Srrh delim = '\''; 6597067Srrh }else delim &= CMASK; 6607067Srrh if(!nlflg) 6617067Srrh while(((i = getch()) & CMASK) != '\n'){ 6627067Srrh if((i & CMASK) == delim)i = IMP; 6637067Srrh wbf(i); 6647067Srrh } 6657067Srrh wbf(IMP);wbf(IMP);wbt(0); 6667067Srrh 6677067Srrh w1 = hseg(width,begin); 6687067Srrh w2 = hseg(width,(filep)0); 6697067Srrh w3 = hseg(width,(filep)0); 6707067Srrh offset = dip->op; 6717067Srrh #ifdef NROFF 6727067Srrh if(!offset)horiz(po); 6737067Srrh #endif 6747067Srrh hseg(pchar,begin); 6757067Srrh if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR)); 6767067Srrh hseg(pchar,(filep)0); 6777067Srrh if(w3){ 6787067Srrh horiz(lt-w1-w2-w3-j); 6797067Srrh hseg(pchar,(filep)0); 6807067Srrh } 6817067Srrh newline(0); 6827067Srrh if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} 6837067Srrh else{if(v.nl > dip->hnl)dip->hnl = v.nl;} 6847067Srrh ffree(begin); 6857067Srrh } 6867067Srrh casepc(){ 6877067Srrh pagech = chget(IMP); 6887067Srrh } 6897067Srrh hseg(f,p) 6907067Srrh int (*f)(); 6917067Srrh filep p; 6927067Srrh { 6937067Srrh register acc, i; 6947067Srrh static filep q; 6957067Srrh 6967067Srrh acc = 0; 6977067Srrh if(p)q = p; 6987067Srrh while(1){ 6997067Srrh i = rbf0(q); 7007067Srrh q = incoff(q); 7017067Srrh if(!i || (i == IMP))return(acc); 7027067Srrh if((i & CMASK) == pagech){ 7037067Srrh nrbits = i & ~CMASK; 7047067Srrh nform = fmt[findr('%')]; 7057067Srrh acc += fnumb(v.pn,f); 7067067Srrh }else acc += (*f)(i); 7077067Srrh } 7087067Srrh } 7097067Srrh casepm(){ 7107067Srrh register i, k; 7117067Srrh register char *p; 7127067Srrh int xx, cnt, kk, tot; 7137067Srrh filep j; 7147067Srrh char *kvt(); 7157067Srrh char pmline[10]; 7167067Srrh 7177067Srrh kk = cnt = 0; 7187067Srrh tot = !skip(); 7197067Srrh for(i = 0; i<NM; i++){ 7207067Srrh if(!((xx = contab[i].rq) & MMASK))continue; 7217067Srrh p = pmline; 7227067Srrh j = (((filep)contab[i].x.mx)<<BLKBITS); 7237067Srrh k = 1; 7247067Srrh while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;} 7257067Srrh cnt++; 7267067Srrh kk += k; 7277067Srrh if(!tot){ 7287067Srrh *p++ = xx & 0177; 7297067Srrh if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' '; 7307067Srrh *p++ = ' '; 7317067Srrh kvt(k,p); 7327067Srrh prstr(pmline); 7337067Srrh } 7347067Srrh } 7357067Srrh if(tot || (cnt > 1)){ 7367067Srrh kvt(kk,pmline); 7377067Srrh prstr(pmline); 7387067Srrh } 7397067Srrh } 7407067Srrh char *kvt(k,p) 7417067Srrh int k; 7427067Srrh char *p; 7437067Srrh { 7447067Srrh if(k>=100)*p++ = k/100 + '0'; 7457067Srrh if(k>=10)*p++ = (k%100)/10 + '0'; 7467067Srrh *p++ = k%10 + '0'; 7477067Srrh *p++ = '\n'; 7487067Srrh *p = 0; 7497067Srrh return(p); 7507067Srrh } 7517067Srrh dummy(){} 752