xref: /csrg-svn/old/roff/common_source/n3.c (revision 48302)
1*48302Sbostic /*-
2*48302Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*48302Sbostic  * All rights reserved.
4*48302Sbostic  *
5*48302Sbostic  * %sccs.include.proprietary.c%
6*48302Sbostic  */
7*48302Sbostic 
87067Srrh #ifndef lint
9*48302Sbostic static char sccsid[] = "@(#)n3.c	4.5 (Berkeley) 04/18/91";
10*48302Sbostic #endif /* not lint */
117067Srrh 
127067Srrh #include "tdef.h"
137067Srrh extern
147067Srrh #include "d.h"
157067Srrh extern
167067Srrh #include "v.h"
177067Srrh #ifdef NROFF
187067Srrh extern
197067Srrh #include "tw.h"
207067Srrh #endif
217067Srrh #include "sdef.h"
227067Srrh 
237067Srrh /*
247067Srrh troff3.c
257067Srrh 
267067Srrh macro and string routines, storage allocation
277067Srrh */
287067Srrh 
297067Srrh unsigned blist[NBLIST];
307067Srrh extern struct s *frame, *stk, *nxf;
317067Srrh extern filep ip;
327067Srrh extern filep offset;
337067Srrh extern filep nextb;
347067Srrh extern char *enda;
357067Srrh 
367067Srrh extern int ch;
377067Srrh extern int ibf;
387067Srrh extern int lgf;
397067Srrh extern int copyf;
407067Srrh extern int ch0;
417067Srrh extern int app;
427067Srrh extern int ds;
437067Srrh extern int nlflg;
447067Srrh extern int *argtop;
457067Srrh extern int *ap;
467067Srrh extern int nchar;
477067Srrh extern int pendt;
487067Srrh extern int rchar;
497067Srrh extern int dilev;
507067Srrh extern int nonumb;
517067Srrh extern int lt;
527067Srrh extern int nrbits;
537067Srrh extern int nform;
547067Srrh extern int fmt[];
557067Srrh extern int oldmn;
567067Srrh extern int newmn;
577067Srrh extern int macerr;
587067Srrh extern filep apptr;
597067Srrh extern int diflg;
607067Srrh extern filep woff;
617067Srrh extern filep roff;
627067Srrh extern int wbfi;
637067Srrh extern int po;
647067Srrh extern int *cp;
657067Srrh extern int xxx;
667067Srrh int pagech = '%';
677067Srrh int strflg;
687067Srrh extern struct contab {
697067Srrh 	int rq;
707067Srrh 	union {
717067Srrh 		int (*f)();
727067Srrh 		unsigned mx;
737067Srrh 	}x;
747067Srrh }contab[NM];
757067Srrh #ifndef VMUNIX
767067Srrh int wbuf[BLK];
777067Srrh int rbuf[BLK];
787067Srrh #else
797067Srrh int *wbuf;
807067Srrh int *rbuf;
817067Srrh int Buf[NBLIST*BLK + NEV*EVS];
827067Srrh #endif
837067Srrh 
caseig()847067Srrh caseig(){
857067Srrh 	register i;
867067Srrh 
877067Srrh 	offset = 0;
887067Srrh 	if((i = copyb()) != '.')control(i,1);
897067Srrh }
casern()907067Srrh casern(){
917067Srrh 	register i,j;
927067Srrh 
937067Srrh 	lgf++;
947067Srrh 	skip();
957067Srrh 	if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return;
967067Srrh 	skip();
977067Srrh 	clrmn(findmn(j=getrq()));
987067Srrh 	if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
997067Srrh }
caserm()1007067Srrh caserm(){
1017067Srrh 	lgf++;
1027067Srrh 	while(!skip()){
1037067Srrh 		clrmn(findmn(getrq()));
1047067Srrh 	}
1057067Srrh }
caseas()1067067Srrh caseas(){
1077067Srrh 	app++;
1087067Srrh 	caseds();
1097067Srrh }
caseds()1107067Srrh caseds(){
1117067Srrh 	ds++;
1127067Srrh 	casede();
1137067Srrh }
caseam()1147067Srrh caseam(){
1157067Srrh 	app++;
1167067Srrh 	casede();
1177067Srrh }
casede()1187067Srrh casede(){
1197067Srrh 	register i, req;
1207067Srrh 	register filep savoff;
1217067Srrh 	extern filep finds();
1227067Srrh 
1237067Srrh 	if(dip != d)wbfl();
1247067Srrh 	req = '.';
1257067Srrh 	lgf++;
1267067Srrh 	skip();
1277067Srrh 	if((i=getrq())==0)goto de1;
1287067Srrh 	if((offset=finds(i)) == 0)goto de1;
1297067Srrh 	if(ds)copys();
1307067Srrh 		else req = copyb();
1317067Srrh 	wbfl();
1327067Srrh 	clrmn(oldmn);
1337067Srrh 	if(newmn)contab[newmn].rq = i | MMASK;
1347067Srrh 	if(apptr){
1357067Srrh 		savoff = offset;
1367067Srrh 		offset = apptr;
1377067Srrh 		wbt(IMP);
1387067Srrh 		offset = savoff;
1397067Srrh 	}
1407067Srrh 	offset = dip->op;
1417067Srrh 	if(req != '.')control(req,1);
1427067Srrh de1:
1437067Srrh 	ds = app = 0;
1447067Srrh 	return;
1457067Srrh }
findmn(i)1467067Srrh findmn(i)
1477067Srrh int i;
1487067Srrh {
1497067Srrh 	register j;
1507067Srrh 
1517067Srrh 	for(j=0;j<NM;j++){
1527067Srrh 		if(i == (contab[j].rq & ~MMASK))break;
1537067Srrh 	}
1547067Srrh 	if(j==NM)j = -1;
1557067Srrh 	return(j);
1567067Srrh }
clrmn(i)1577067Srrh clrmn(i)
1587067Srrh int i;
1597067Srrh {
1607067Srrh 	extern filep boff();
1617067Srrh 	if(i >= 0){
1627067Srrh 		if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS);
1637067Srrh 		contab[i].rq = 0;
1647067Srrh 		contab[i].x.mx = 0;
1657067Srrh 	}
1667067Srrh }
finds(mn)1677067Srrh filep finds(mn)
1687067Srrh int mn;
1697067Srrh {
1707067Srrh 	register i;
1717067Srrh 	extern filep boff();
1727067Srrh 	register filep savip;
1737067Srrh 	extern filep alloc();
1747067Srrh 	extern filep incoff();
1757067Srrh 
1767067Srrh 	oldmn = findmn(mn);
1777067Srrh 	newmn = 0;
1787067Srrh 	apptr = (filep)0;
1797067Srrh 	if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){
1807067Srrh 			savip = ip;
1817067Srrh 			ip = (((filep)contab[oldmn].x.mx)<<BLKBITS);
1827067Srrh 			oldmn = -1;
1837067Srrh 			while((i=rbf()) != 0);
1847067Srrh 			apptr = ip;
1857067Srrh 			if(!diflg)ip = incoff(ip);
1867067Srrh 			nextb = ip;
1877067Srrh 			ip = savip;
1887067Srrh 	}else{
1897067Srrh 		for(i=0;i<NM;i++){
1907067Srrh 			if(contab[i].rq == 0)break;
1917067Srrh 		}
1927067Srrh 		if((i==NM) ||
1937067Srrh 		   (nextb = alloc()) == 0){
1947067Srrh 			app = 0;
1957067Srrh 			if(macerr++ > 1)done2(02);
1967067Srrh 			prstr("Too many string/macro names.\n");
1977067Srrh 			edone(04);
1987067Srrh 			return(offset = 0);
1997067Srrh 		}
2007067Srrh 			contab[i].x.mx = (unsigned)(nextb>>BLKBITS);
2017067Srrh 		if(!diflg){
2027067Srrh 			newmn = i;
2037067Srrh 			if(oldmn == -1)contab[i].rq = -1;
2047067Srrh 		}else{
2057067Srrh 			contab[i].rq = mn | MMASK;
2067067Srrh 		}
2077067Srrh 	}
2087067Srrh 
2097067Srrh 	app = 0;
2107067Srrh 	return(offset = nextb);
2117067Srrh }
skip()2127067Srrh skip(){
2137067Srrh 	register i;
2147067Srrh 
2157067Srrh 	while(((i=getch()) & CMASK) == ' ');
2167067Srrh 	ch=i;
2177067Srrh 	return(nlflg);
2187067Srrh }
copyb()2197067Srrh copyb()
2207067Srrh {
2217067Srrh 	register i, j, k;
2227067Srrh 	int ii, req, state;
2237067Srrh 	filep savoff;
2247067Srrh 
2257067Srrh 	if(skip() || !(j=getrq()))j = '.';
2267067Srrh 	req = j;
2277067Srrh 	k = j>>BYTE;
2287067Srrh 	j &= BMASK;
2297067Srrh 	copyf++;
2307067Srrh 	flushi();
2317067Srrh 	nlflg = 0;
2327067Srrh 	state = 1;
2337067Srrh 	while(1){
2347067Srrh 		i = (ii = getch()) & CMASK;
2357067Srrh 		if(state == 3){
2367067Srrh 			if(i == k)break;
2377067Srrh 			if(!k){
2387067Srrh 				ch = ii;
2397067Srrh 				i = getach();
2407067Srrh 				ch = ii;
2417067Srrh 				if(!i)break;
2427067Srrh 			}
2437067Srrh 			state = 0;
2447067Srrh 			goto c0;
2457067Srrh 		}
2467067Srrh 		if(i == '\n'){
2477067Srrh 			state = 1;
2487067Srrh 			nlflg = 0;
2497067Srrh 			goto c0;
2507067Srrh 		}
2517067Srrh 		if((state == 1) && (i == '.')){
2527067Srrh 			state++;
2537067Srrh 			savoff = offset;
2547067Srrh 			goto c0;
2557067Srrh 		}
2567067Srrh 		if((state == 2) && (i == j)){
2577067Srrh 			state++;
2587067Srrh 			goto c0;
2597067Srrh 		}
2607067Srrh 		state = 0;
2617067Srrh c0:
2627067Srrh 		if(offset)wbf(ii);
2637067Srrh 	}
2647067Srrh 	if(offset){
2657067Srrh 		wbfl();
2667067Srrh 		offset = savoff;
2677067Srrh 		wbt(0);
2687067Srrh 	}
2697067Srrh 	copyf--;
2707067Srrh 	return(req);
2717067Srrh }
copys()2727067Srrh copys()
2737067Srrh {
2747067Srrh 	register i;
2757067Srrh 
2767067Srrh 	copyf++;
2777067Srrh 	if(skip())goto c0;
2787067Srrh 	if(((i=getch()) & CMASK) != '"')wbf(i);
2797067Srrh 	while(((i=getch()) & CMASK) != '\n')wbf(i);
2807067Srrh c0:
2817067Srrh 	wbt(0);
2827067Srrh 	copyf--;
2837067Srrh }
alloc()2847067Srrh filep alloc()
2857067Srrh {
2867067Srrh 	register i;
2877067Srrh 	extern filep boff();
2887067Srrh 	filep j;
2897067Srrh 
2907067Srrh 	for(i=0;i<NBLIST;i++){
2917067Srrh 		if(blist[i] == 0)break;
2927067Srrh 	}
2937067Srrh 	if(i==NBLIST){
2947067Srrh 		j = 0;
2957067Srrh 	}else{
2967067Srrh 		blist[i] = -1;
2977067Srrh 		if((j = boff(i)) < NEV*EVS)j = 0;
2987067Srrh 	}
2997067Srrh 	return(nextb = j);
3007067Srrh }
ffree(i)3017067Srrh ffree(i)
3027067Srrh filep i;
3037067Srrh {
3047067Srrh 	register j;
3057067Srrh 
3067067Srrh 	while((blist[j = blisti(i)]) != -1){
3077067Srrh 		i = ((filep)blist[j])<<BLKBITS;
3087067Srrh 		blist[j] = 0;
3097067Srrh 	}
3107067Srrh 	blist[j] = 0;
3117067Srrh }
boff(i)3127067Srrh filep boff(i)
3137067Srrh int i;
3147067Srrh {
3157067Srrh 	return(((filep)i)*BLK + NEV*EVS);
3167067Srrh }
wbt(i)3177067Srrh wbt(i)
3187067Srrh int i;
3197067Srrh {
3207067Srrh 	wbf(i);
3217067Srrh 	wbfl();
3227067Srrh }
wbf(i)3237067Srrh wbf(i)
3247067Srrh int i;
3257067Srrh {
3267067Srrh 	register j;
3277067Srrh 
3287067Srrh 	if(!offset)return;
3297067Srrh 	if(!woff){
3307067Srrh 		woff = offset;
3317067Srrh #ifdef VMUNIX
3327067Srrh 		wbuf = &Buf[woff];
3337067Srrh #endif
3347067Srrh 		wbfi = 0;
3357067Srrh 	}
3367067Srrh 	wbuf[wbfi++] = i;
3377067Srrh 	if(!((++offset) & (BLK-1))){
3387067Srrh 		wbfl();
3397067Srrh 		if(blist[j = blisti(--offset)] == -1){
3407067Srrh 			if(alloc() == 0){
3417067Srrh 				prstr("Out of temp file space.\n");
3427067Srrh 				done2(01);
3437067Srrh 			}
3447067Srrh 			blist[j] = (unsigned)(nextb>>BLKBITS);
3457067Srrh 		}
3467067Srrh 		offset = ((filep)blist[j])<<BLKBITS;
3477067Srrh 	}
3487067Srrh 	if(wbfi >= BLK)wbfl();
3497067Srrh }
wbfl()3507067Srrh wbfl(){
3517067Srrh 	if(woff == 0)return;
3527067Srrh #ifndef VMUNIX
3537067Srrh 	lseek(ibf, ((long)woff) * sizeof(int), 0);
3547067Srrh 	write(ibf, (char *)wbuf, wbfi * sizeof(int));
3557067Srrh #endif
3567067Srrh 	if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1;
3577067Srrh 	woff = 0;
3587067Srrh }
blisti(i)3597067Srrh blisti(i)
3607067Srrh filep i;
3617067Srrh {
3627067Srrh 	return((i-NEV*EVS)/(BLK));
3637067Srrh }
rbf()3647067Srrh rbf(){
3657067Srrh 	register i;
3667067Srrh 	extern filep incoff();
3677067Srrh 
3687067Srrh 	if((i=rbf0(ip)) == 0){
3697067Srrh 		if(!app)i = popi();
3707067Srrh 	}else{
3717067Srrh 		ip = incoff(ip);
3727067Srrh 	}
3737067Srrh 	return(i);
3747067Srrh }
rbf0(p)3757067Srrh rbf0(p)
3767067Srrh filep p;
3777067Srrh {
3787067Srrh 	register filep i;
3797067Srrh 
3807067Srrh 	if((i = (p & (~(BLK-1)))) != roff){
3817067Srrh 		roff = i;
3827067Srrh #ifndef VMUNIX
3837067Srrh 		lseek(ibf, ((long)roff) * sizeof(int), 0);
3847067Srrh 		if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0);
3857067Srrh #else
3867067Srrh 		rbuf = &Buf[roff];
3877067Srrh #endif
3887067Srrh 	}
3897067Srrh 	return(rbuf[p & (BLK-1)]);
3907067Srrh }
incoff(p)3917067Srrh filep incoff(p)
3927067Srrh filep p;
3937067Srrh {
3947067Srrh 	register i;
3957067Srrh 	register filep j;
3967067Srrh 	if(!((j = (++p)) & (BLK-1))){
3977067Srrh 		if((i = blist[blisti(--p)]) == -1){
3987067Srrh 			prstr("Bad storage allocation.\n");
3997067Srrh 			done2(-5);
4007067Srrh 		}
4017067Srrh 		j = ((filep)i)<<BLKBITS;
4027067Srrh 	}
4037067Srrh 	return(j);
4047067Srrh }
popi()4057067Srrh popi(){
4067067Srrh 	register struct s *p;
4077067Srrh 
4087067Srrh 	if(frame == stk)return(0);
4097067Srrh 	if(strflg)strflg--;
4107067Srrh 	p = nxf = frame;
4117067Srrh 	p->nargs = 0;
4127067Srrh 	frame = p->pframe;
4137067Srrh 	ip = p->pip;
4147067Srrh 	nchar = p->pnchar;
4157067Srrh 	rchar = p->prchar;
4167067Srrh 	pendt = p->ppendt;
4177067Srrh 	ap = p->pap;
4187067Srrh 	cp = p->pcp;
4197067Srrh 	ch0 = p->pch0;
4207067Srrh 	return(p->pch);
4217067Srrh }
4228921Srrh 
4238921Srrh /*
4248921Srrh  *	test that the end of the allocation is above a certain location
4258921Srrh  *	in memory
4268921Srrh  */
4278921Srrh #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);}
4288921Srrh 
pushi(newip)4297067Srrh pushi(newip)
4307067Srrh filep newip;
4317067Srrh {
4327067Srrh 	register struct s *p;
4338921Srrh 	extern char	*setbrk();
4347067Srrh 
4358921Srrh 	SPACETEST(nxf, sizeof(struct s));
4367067Srrh 	p = nxf;
4377067Srrh 	p->pframe = frame;
4387067Srrh 	p->pip = ip;
4397067Srrh 	p->pnchar = nchar;
4407067Srrh 	p->prchar = rchar;
4417067Srrh 	p->ppendt = pendt;
4427067Srrh 	p->pap = ap;
4437067Srrh 	p->pcp = cp;
4447067Srrh 	p->pch0 = ch0;
4457067Srrh 	p->pch = ch;
4467067Srrh 	cp = ap = 0;
4477067Srrh 	nchar = rchar = pendt = ch0 = ch = 0;
4487067Srrh 	frame = nxf;
4498921Srrh 	if (nxf->nargs == 0)
4508921Srrh 		nxf += 1;
4518921Srrh 	else
4528921Srrh 		nxf = (struct s *)argtop;
4537067Srrh 	return(ip = newip);
4547067Srrh }
4558921Srrh 
4568921Srrh 
setbrk(x)4578921Srrh char	*setbrk(x)
4588921Srrh int	x;
4597067Srrh {
4608921Srrh 	register char	*i;
4618921Srrh 	char	*sbrk();
4627067Srrh 
46331687Sbostic 	x += sizeof(int) - 1;
46431687Sbostic 	x &= ~(sizeof(int) - 1);
46531687Sbostic 	if ((u_int)(i = sbrk(x)) == -1) {
4667067Srrh 		prstrfl("Core limit reached.\n");
4677067Srrh 		edone(0100);
4688921Srrh 	} else {
4697067Srrh 		enda = i + x;
4707067Srrh 	}
4717067Srrh 	return(i);
4727067Srrh }
4738921Srrh 
4748921Srrh 
getsn()4758921Srrh getsn()
4768921Srrh {
4777067Srrh 	register i;
4787067Srrh 
4798921Srrh 	if ((i = getach()) == 0)
4808921Srrh 		return(0);
4818921Srrh 	if (i == '(')
4828921Srrh 		return(getrq());
4838921Srrh 	else
4848921Srrh 		return(i);
4857067Srrh }
4868921Srrh 
4878921Srrh 
setstr()4888921Srrh setstr()
4898921Srrh {
4907067Srrh 	register i;
4917067Srrh 
4927067Srrh 	lgf++;
4938921Srrh 	if (    ((i = getsn()) == 0)
4948921Srrh 	     || ((i = findmn(i)) == -1)
4958921Srrh 	     ||  !(contab[i].rq & MMASK)) {
4967067Srrh 		lgf--;
4977067Srrh 		return(0);
4988921Srrh 	} else {
4998921Srrh 		SPACETEST(nxf, sizeof(struct s));
5007067Srrh 		nxf->nargs = 0;
5017067Srrh 		strflg++;
5027067Srrh 		lgf--;
5037067Srrh 		return(pushi(((filep)contab[i].x.mx)<<BLKBITS));
5047067Srrh 	}
5057067Srrh }
5068921Srrh 
5078921Srrh typedef	int	tchar;
5088921Srrh #define	cbits(x)	((x) & CMASK)
5098921Srrh 
collect()5107067Srrh collect()
5117067Srrh {
5128921Srrh 	register j;
5138921Srrh 	tchar i;
5148921Srrh 	register tchar *strp;
5158921Srrh 	tchar * lim;
5168921Srrh 	tchar * *argpp, **argppend;
5178921Srrh 	int	quote;
5187067Srrh 	struct s *savnxf;
5197067Srrh 
5207067Srrh 	copyf++;
5217067Srrh 	nxf->nargs = 0;
5227067Srrh 	savnxf = nxf;
5238921Srrh 	if (skip())
5248921Srrh 		goto rtn;
5258921Srrh 
5268921Srrh 	{
5278921Srrh 		char *memp;
5288921Srrh 		memp = (char *)savnxf;
5298921Srrh 		/*
5308921Srrh 		 *	1 s structure for the macro descriptor
5318921Srrh 		 *	APERMAC tchar *'s for pointers into the strings
5328921Srrh 		 *	space for the tchar's themselves
5338921Srrh 		 */
5348921Srrh 		memp += sizeof(struct s);
5358921Srrh 		/*
5368921Srrh 		 *	CPERMAC (the total # of characters for ALL arguments)
5378921Srrh 		 *	to a macros, has been carefully chosen
5388921Srrh 		 *	so that the distance between stack frames is < DELTA
5398921Srrh 		 */
5408921Srrh #define	CPERMAC	200
5418921Srrh #define	APERMAC	9
5428921Srrh 		memp += APERMAC * sizeof(tchar *);
5438921Srrh 		memp += CPERMAC * sizeof(tchar);
5448921Srrh 		nxf = (struct s*)memp;
5458921Srrh 	}
5468921Srrh 	lim = (tchar *)nxf;
5478921Srrh 	argpp = (tchar **)(savnxf + 1);
5488921Srrh 	argppend = &argpp[APERMAC];
5498921Srrh 	SPACETEST(argppend, sizeof(tchar *));
5508921Srrh 	strp = (tchar *)argppend;
5518921Srrh 	/*
5528921Srrh 	 *	Zero out all the string pointers before filling them in.
5538921Srrh 	 */
5548921Srrh 	for (j = 0; j < APERMAC; j++){
5558921Srrh 		argpp[j] = (tchar *)0;
5568921Srrh 	}
5578921Srrh #if 0
5588921Srrh 	fprintf(stderr, "savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x\n",
5598921Srrh 		savnxf, nxf, argpp, strp, lim, enda);
5608921Srrh #endif 0
5617067Srrh 	strflg = 0;
5628921Srrh 	while ((argpp != argppend) && (!skip())) {
5637067Srrh 		*argpp++ = strp;
5647067Srrh 		quote = 0;
5658921Srrh 		if (cbits(i = getch()) == '"')
5668921Srrh 			quote++;
5678921Srrh 		else
5688921Srrh 			ch = i;
5698921Srrh 		while (1) {
5707067Srrh 			i = getch();
5718921Srrh 			if ( nlflg ||  (!quote && cbits(i) == ' '))
5728921Srrh 				break;
5738921Srrh 			if (   quote
5748921Srrh 			    && (cbits(i) == '"')
5758921Srrh 			    && (cbits(i = getch()) != '"')) {
5767067Srrh 				ch = i;
5777067Srrh 				break;
5787067Srrh 			}
5797067Srrh 			*strp++ = i;
5808921Srrh 			if (strflg && (strp >= lim)) {
5818921Srrh #if 0
5828921Srrh 				fprintf(stderr, "strp=0x%x, lim = 0x%x\n",
5838921Srrh 					strp, lim);
5848921Srrh #endif 0
5857067Srrh 				prstrfl("Macro argument too long.\n");
5867067Srrh 				copyf--;
5877067Srrh 				edone(004);
5887067Srrh 			}
5898921Srrh 			SPACETEST(strp, 3 * sizeof(tchar));
5907067Srrh 		}
5917067Srrh 		*strp++ = 0;
5927067Srrh 	}
5937067Srrh 	nxf = savnxf;
5948921Srrh 	nxf->nargs = argpp - (tchar **)(savnxf + 1);
5957067Srrh 	argtop = strp;
5967067Srrh rtn:
5977067Srrh 	copyf--;
5987067Srrh }
5998921Srrh 
6008921Srrh 
seta()6017067Srrh seta()
6027067Srrh {
6037067Srrh 	register i;
6047067Srrh 
6057067Srrh 	if(((i = (getch() & CMASK) - '0') > 0) &&
6068921Srrh 		(i <= APERMAC) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **)));
6077067Srrh }
caseda()6087067Srrh caseda(){
6097067Srrh 	app++;
6107067Srrh 	casedi();
6117067Srrh }
casedi()6127067Srrh casedi(){
6137067Srrh 	register i, j;
6147067Srrh 	register *k;
6157067Srrh 
6167067Srrh 	lgf++;
6177067Srrh 	if(skip() || ((i=getrq()) == 0)){
6187067Srrh 		if(dip != d)wbt(0);
6197067Srrh 		if(dilev > 0){
6207067Srrh 			v.dn = dip->dnl;
6217067Srrh 			v.dl = dip->maxl;
6227067Srrh 			dip = &d[--dilev];
6237067Srrh 			offset = dip->op;
6247067Srrh 		}
6257067Srrh 		goto rtn;
6267067Srrh 	}
6277067Srrh 	if(++dilev == NDI){
6287067Srrh 		--dilev;
6297067Srrh 		prstr("Cannot divert.\n");
6307067Srrh 		edone(02);
6317067Srrh 	}
6327067Srrh 	if(dip != d)wbt(0);
6337067Srrh 	diflg++;
6347067Srrh 	dip = &d[dilev];
6357067Srrh 	dip->op = finds(i);
6367067Srrh 	dip->curd = i;
6377067Srrh 	clrmn(oldmn);
6387067Srrh 	k = (int *)&dip->dnl;
6397067Srrh 	for(j=0; j<10; j++)k[j] = 0;	/*not op and curd*/
6407067Srrh rtn:
6417067Srrh 	app = 0;
6427067Srrh 	diflg = 0;
6437067Srrh }
casedt()6447067Srrh casedt(){
6457067Srrh 	lgf++;
6467067Srrh 	dip->dimac = dip->ditrap = dip->ditf = 0;
6477067Srrh 	skip();
6487067Srrh 	dip->ditrap = vnumb((int *)0);
6497067Srrh 	if(nonumb)return;
6507067Srrh 	skip();
6517067Srrh 	dip->dimac = getrq();
6527067Srrh }
casetl()6537067Srrh casetl(){
6547067Srrh 	register i, j;
6557067Srrh 	int w1, w2, w3, delim;
6567067Srrh 	filep begin;
6577067Srrh 	extern width(), pchar();
6587067Srrh 
6597067Srrh 	dip->nls = 0;
6607067Srrh 	skip();
6617067Srrh 	if(dip != d)wbfl();
6627067Srrh 	if((offset = begin = alloc()) == 0)return;
6637067Srrh 	if((delim = getch()) & MOT){
6647067Srrh 		ch = delim;
6657067Srrh 		delim = '\'';
6667067Srrh 	}else delim &= CMASK;
6677067Srrh 	if(!nlflg)
6687067Srrh 		while(((i = getch()) & CMASK) != '\n'){
6697067Srrh 			if((i & CMASK) == delim)i = IMP;
6707067Srrh 			wbf(i);
6717067Srrh 		}
6727067Srrh 	wbf(IMP);wbf(IMP);wbt(0);
6737067Srrh 
6747067Srrh 	w1 = hseg(width,begin);
6757067Srrh 	w2 = hseg(width,(filep)0);
6767067Srrh 	w3 = hseg(width,(filep)0);
6777067Srrh 	offset = dip->op;
6787067Srrh #ifdef NROFF
6797067Srrh 	if(!offset)horiz(po);
6807067Srrh #endif
6817067Srrh 	hseg(pchar,begin);
6827067Srrh 	if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR));
6837067Srrh 	hseg(pchar,(filep)0);
6847067Srrh 	if(w3){
6857067Srrh 		horiz(lt-w1-w2-w3-j);
6867067Srrh 		hseg(pchar,(filep)0);
6877067Srrh 	}
6887067Srrh 	newline(0);
6897067Srrh 	if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;}
6907067Srrh 	else{if(v.nl > dip->hnl)dip->hnl = v.nl;}
6917067Srrh 	ffree(begin);
6927067Srrh }
casepc()6937067Srrh casepc(){
6947067Srrh 	pagech = chget(IMP);
6957067Srrh }
6967067Srrh hseg(f,p)
6977067Srrh int (*f)();
6987067Srrh filep p;
6997067Srrh {
7007067Srrh 	register acc, i;
7017067Srrh 	static filep q;
7027067Srrh 
7037067Srrh 	acc = 0;
7047067Srrh 	if(p)q = p;
7057067Srrh 	while(1){
7067067Srrh 		i = rbf0(q);
7077067Srrh 		q = incoff(q);
7087067Srrh 		if(!i || (i == IMP))return(acc);
7097067Srrh 		if((i & CMASK) == pagech){
7107067Srrh 			nrbits = i & ~CMASK;
7117067Srrh 			nform = fmt[findr('%')];
7127067Srrh 			acc += fnumb(v.pn,f);
7137067Srrh 		}else acc += (*f)(i);
7147067Srrh 	}
7157067Srrh }
casepm()7167067Srrh casepm(){
7177067Srrh 	register i, k;
7187067Srrh 	register char *p;
7197067Srrh 	int xx, cnt, kk, tot;
7207067Srrh 	filep j;
7217067Srrh 	char *kvt();
7227067Srrh 	char pmline[10];
7237067Srrh 
7247067Srrh 	kk = cnt = 0;
7257067Srrh 	tot = !skip();
7267067Srrh 	for(i = 0; i<NM; i++){
7277067Srrh 		if(!((xx = contab[i].rq) & MMASK))continue;
7287067Srrh 		p = pmline;
7297067Srrh 		j = (((filep)contab[i].x.mx)<<BLKBITS);
7307067Srrh 		k = 1;
7317067Srrh 		while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;}
7327067Srrh 		cnt++;
7337067Srrh 		kk += k;
7347067Srrh 		if(!tot){
7357067Srrh 			*p++ = xx & 0177;
7367067Srrh 			if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' ';
7377067Srrh 			*p++ = ' ';
7387067Srrh 			kvt(k,p);
7397067Srrh 			prstr(pmline);
7407067Srrh 		}
7417067Srrh 	}
7427067Srrh 	if(tot || (cnt > 1)){
7437067Srrh 		kvt(kk,pmline);
7447067Srrh 		prstr(pmline);
7457067Srrh 	}
7467067Srrh }
kvt(k,p)7477067Srrh char *kvt(k,p)
7487067Srrh int k;
7497067Srrh char *p;
7507067Srrh {
7517067Srrh 	if(k>=100)*p++ = k/100 + '0';
7527067Srrh 	if(k>=10)*p++ = (k%100)/10 + '0';
7537067Srrh 	*p++ = k%10 + '0';
7547067Srrh 	*p++ = '\n';
7557067Srrh 	*p = 0;
7567067Srrh 	return(p);
7577067Srrh }
dummy()7587067Srrh dummy(){}
759