xref: /csrg-svn/old/roff/common_source/n1.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 
87063Srrh #ifndef lint
9*48302Sbostic char copyright[] =
10*48302Sbostic "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
11*48302Sbostic  All rights reserved.\n";
12*48302Sbostic #endif /* not lint */
137063Srrh 
14*48302Sbostic #ifndef lint
15*48302Sbostic static char sccsid[] = "@(#)n1.c	4.13 (Berkeley) 04/18/91";
16*48302Sbostic #endif /* not lint */
17*48302Sbostic 
187171Smckusick #include "tdef.h"
1942856Skarels #include "pathnames.h"
2013262Srrh #include <sys/types.h>
217063Srrh #include <sys/stat.h>
2230776Sbostic #include <time.h>
237063Srrh extern
247063Srrh #include "d.h"
257063Srrh extern
267063Srrh #include "v.h"
277063Srrh #ifdef NROFF
287063Srrh extern
297063Srrh #include "tw.h"
307063Srrh #endif
317063Srrh #include "sdef.h"
327063Srrh #include <setjmp.h>
337063Srrh jmp_buf sjbuf;
347063Srrh #include	<sgtty.h>
357063Srrh /*
367063Srrh troff1.c
377063Srrh 
387063Srrh consume options, initialization, main loop,
397063Srrh input routines, escape function calling
407063Srrh */
417063Srrh 
427063Srrh int	inchar[LNSIZE], *pinchar = inchar;	/* XXX */
437063Srrh extern struct s *frame, *stk, *nxf;
447063Srrh extern struct s *ejl, *litlev;
457063Srrh extern filep ip;
467063Srrh extern filep offset;
477063Srrh extern filep nextb;
487063Srrh 
497063Srrh 
507063Srrh extern int stdi;
517063Srrh extern int waitf;
527063Srrh extern int nofeed;
537063Srrh extern int quiet;
547063Srrh extern int ptid;
557063Srrh extern int ascii;
567063Srrh extern int npn;
577063Srrh extern int xflg;
587063Srrh extern int stop;
597063Srrh extern char ibuf[IBUFSZ];
607063Srrh extern char xbuf[IBUFSZ];
617063Srrh extern char *ibufp;
627063Srrh extern char *xbufp;
637063Srrh extern char *eibuf;
647063Srrh extern char *xeibuf;
657063Srrh extern int *cp;
667063Srrh extern int *vlist;
677063Srrh extern int nx;
687063Srrh extern int mflg;
697063Srrh extern int ch;
707063Srrh extern int pto;
717063Srrh extern int pfrom;
727063Srrh extern int cps;
737063Srrh extern int chbits;
747063Srrh extern int ibf;
757063Srrh extern int ttyod;
767063Srrh extern struct sgttyb ttys;
777063Srrh extern int iflg;
787063Srrh extern int init;
797063Srrh extern int rargc;
807063Srrh extern char **argp;
817063Srrh extern char trtab[256];
827063Srrh extern int lgf;
837063Srrh extern int copyf;
847063Srrh extern int eschar;
857063Srrh extern int ch0;
867063Srrh extern int cwidth;
877063Srrh extern int nlflg;
887063Srrh extern int *ap;
897063Srrh extern int donef;
907063Srrh extern int nflush;
917063Srrh extern int nchar;
927063Srrh extern int rchar;
937063Srrh extern int nfo;
947063Srrh extern int ifile;
957063Srrh extern int fc;
967063Srrh extern int padc;
977063Srrh extern int tabc;
987063Srrh extern int dotc;
997063Srrh extern int raw;
1007063Srrh extern int tabtab[NTAB];
1017063Srrh extern char nextf[];
1027063Srrh extern int nfi;
1037063Srrh #ifdef NROFF
1047063Srrh extern char termtab[];
1057063Srrh extern int tti;
1067063Srrh #endif
1077063Srrh extern int ifl[NSO];
1087063Srrh extern int ifi;
1097063Srrh extern int pendt;
1107063Srrh extern int flss;
1117063Srrh extern int fi;
1127063Srrh extern int lg;
1137063Srrh extern char ptname[];
1147063Srrh extern int print;
1157063Srrh extern int nonumb;
1167063Srrh extern int pnlist[];
1177063Srrh extern int *pnp;
1187063Srrh extern int nb;
1197063Srrh extern int trap;
1207063Srrh extern int tflg;
1217063Srrh extern int ejf;
1227063Srrh extern int lit;
1237063Srrh extern int cc;
1247063Srrh extern int c2;
1257063Srrh extern int spread;
1267063Srrh extern int gflag;
1277063Srrh extern int oline[];
1287063Srrh extern int *olinep;
1297063Srrh extern int dpn;
1307063Srrh extern int noscale;
1317063Srrh extern char *unlkp;
1327063Srrh extern int pts;
1337063Srrh extern int level;
1347063Srrh extern int ttysave;
1357063Srrh extern int tdelim;
1367063Srrh extern int dotT;
1377063Srrh extern int tabch, ldrch;
1387063Srrh extern int eqflg;
1397063Srrh extern no_out;
1407063Srrh extern int hflg;
1417063Srrh #ifndef NROFF
1427063Srrh extern char codetab[];
1437063Srrh extern int spbits;
1447063Srrh #endif
1457063Srrh extern int xxx;
1467063Srrh int stopmesg;
1477063Srrh filep ipl[NSO];
1487063Srrh long offl[NSO];
1497063Srrh long ioff;
1507063Srrh char *ttyp;
1517063Srrh extern struct contab {
1527063Srrh 	int rq;
1537063Srrh 	union {
1547063Srrh 		int (*f)();
1557063Srrh 		unsigned mx;
1567063Srrh 	}x;
1577063Srrh }contab[NM];
1587063Srrh int ms[] = {31,28,31,30,31,30,31,31,30,31,30,31};
1597063Srrh #ifndef NROFF
1607063Srrh int acctf;
1617063Srrh #endif
1627063Srrh 
main(argc,argv)1637063Srrh main(argc,argv)
1647063Srrh int argc;
1657063Srrh char **argv;
1667063Srrh {
1677063Srrh 	char *p, *q;
1687063Srrh 	register i, j;
16946852Sbostic 	extern void catch(), fpecatch(), kcatch();
1707063Srrh 
1717063Srrh 	signal(SIGHUP,catch);
1727063Srrh 	if(signal(SIGINT,catch) == SIG_IGN){
1737063Srrh 		signal(SIGHUP,SIG_IGN);
1747063Srrh 		signal(SIGINT,SIG_IGN);
1757063Srrh 		signal(SIGQUIT,SIG_IGN);
1767063Srrh 	}
1777063Srrh 	signal(SIGFPE,fpecatch);
1787063Srrh 	signal(SIGPIPE,catch);
1797063Srrh 	signal(SIGTERM,kcatch);
1807063Srrh 	init1(argv[0][0]);
1817063Srrh options:
1827063Srrh 	while(--argc > 0 && (++argv)[0][0]=='-')
1837063Srrh 		switch(argv[0][1]){
1847063Srrh 
1857063Srrh 		case 0:
1867063Srrh 			goto start;
1877063Srrh 		case 'i':
1887063Srrh 			stdi++;
1897063Srrh 			continue;
1907063Srrh 		case 'q':
1917063Srrh 			quiet++;
1927063Srrh 			if(gtty(0, &ttys) >= 0)
1937063Srrh 				ttysave = ttys.sg_flags;
1947063Srrh 			continue;
1957063Srrh 		case 'n':
1967063Srrh 			npn = cnum(&argv[0][2]);
1977063Srrh 			continue;
1987063Srrh 		case 'p':
1997063Srrh 			xflg = 0;
2007063Srrh 			cps = cnum(&argv[0][2]);
2017063Srrh 			continue;
2027063Srrh 		case 'S':
2037063Srrh 			stopmesg++;
2047063Srrh 			continue;
2057063Srrh 		case 's':
2067063Srrh 			if(!(stop = cnum(&argv[0][2])))stop++;
2077063Srrh 			continue;
2087063Srrh 		case 'r':
2097063Srrh 			vlist[findr(argv[0][2])] = cnum(&argv[0][3]);
2107063Srrh 			continue;
2117063Srrh 		case 'm':
2127063Srrh 			p = &nextf[nfi];
2137063Srrh 			q = &argv[0][2];
2147063Srrh 			while((*p++ = *q++) != 0);
2157063Srrh 			if (access(nextf, 4) < 0) {
21642856Skarels 				char local[NS];
21742856Skarels 
21842856Skarels 				strcpy(local, _PATH_LOCAL_TMAC);
2197063Srrh 				strcat(local, &argv[0][2]);
2207063Srrh 				if (access(local, 4) == 0)
2217063Srrh 					strcpy(nextf, local);
2227063Srrh 			}
2237063Srrh 			mflg++;
2247063Srrh 			continue;
2257063Srrh 		case 'o':
2267063Srrh 			getpn(&argv[0][2]);
2277063Srrh 			continue;
2287063Srrh #ifdef NROFF
2297063Srrh 		case 'h':
2307063Srrh 			hflg++;
2317063Srrh 			continue;
2327063Srrh 		case 'z':
2337063Srrh 			no_out++;
2347063Srrh 			continue;
2357063Srrh 		case 'e':
2367063Srrh 			eqflg++;
2377063Srrh 			continue;
2387063Srrh 		case 'T':
2397063Srrh 			p = &termtab[tti];
2407063Srrh 			q = &argv[0][2];
2417063Srrh 			if(!((*q) & 0177))continue;
2427063Srrh 			while((*p++ = *q++) != 0);
2437063Srrh 			dotT++;
2447063Srrh 			continue;
2457063Srrh #endif
2467063Srrh #ifndef NROFF
2477063Srrh 		case 'z':
2487063Srrh 			no_out++;
2497063Srrh 		case 'a':
2507063Srrh 			ascii = 1;
2517063Srrh 			nofeed++;
2527063Srrh 		case 't':
2537063Srrh 			ptid = 1;
2547063Srrh 			continue;
2557063Srrh 		case 'w':
2567063Srrh 			waitf = 1;
2577063Srrh 			continue;
2587063Srrh 		case 'f':
2597063Srrh 			nofeed++;
2607063Srrh 			continue;
2617063Srrh 		case 'x':
2627063Srrh 			xflg = 0;
2637063Srrh 			continue;
2647063Srrh 		case 'b':
2657063Srrh 			if(open(ptname,1) < 0)prstr("Busy.\n");
2667063Srrh 			else prstr("Available.\n");
2677063Srrh 			done3(0);
2687063Srrh 		case 'g':
2697063Srrh 			stop = ptid = gflag = 1;
2707063Srrh 			dpn = 0;
2717063Srrh 			continue;
27211247Sshannon 		case 'F':
27311247Sshannon 			{
27411247Sshannon 			  extern char *fontfile;
27511247Sshannon 			  fontfile = &argv[0][2];
27611247Sshannon 			}
27711247Sshannon 			continue;
2787063Srrh #endif
2797063Srrh 		default:
2807063Srrh 			pto = cnum(&argv[0][1]);
2817063Srrh 			continue;
2827063Srrh 		}
2837063Srrh 
2847063Srrh 	if(argv[0][0] == '+'){
2857063Srrh 		pfrom = cnum(&argv[0][1]);
2867063Srrh 		print = 0;
2877063Srrh 		if(argc > 0)goto options;
2887063Srrh 	}
2897063Srrh 
2907063Srrh start:
2917063Srrh 	argp = argv;
2927063Srrh 	rargc = argc;
2937063Srrh 	init2();
2947063Srrh 	setjmp(sjbuf);
2957063Srrh loop:
2967063Srrh 	copyf = lgf = nb = nflush = nlflg = 0;
2977063Srrh 	if(ip && (rbf0(ip)==0) && ejf && (frame->pframe <= ejl)){
2987063Srrh 		nflush++;
2997063Srrh 		trap = 0;
3007063Srrh 		eject((struct s *)0);
3017063Srrh 		goto loop;
3027063Srrh 	}
3037063Srrh 	i = getch();
3047063Srrh 	if(pendt)goto lt;
3057063Srrh 	if(lit && (frame <= litlev)){
3067063Srrh 		lit--;
3077063Srrh 		goto lt;
3087063Srrh 	}
3097063Srrh 	if((j = (i & CMASK)) == XPAR){
3107063Srrh 		copyf++;
3117063Srrh 		tflg++;
3127063Srrh 		for(;(i & CMASK) != '\n';)pchar(i = getch());
3137063Srrh 		tflg = 0;
3147063Srrh 		copyf--;
3157063Srrh 		goto loop;
3167063Srrh 	}
3177063Srrh 	if((j == cc) || (j == c2)){
3187063Srrh 		if(j == c2)nb++;
3197063Srrh 		copyf++;
3207063Srrh 		while(((j=((i=getch()) & CMASK)) == ' ') ||
3217063Srrh 			(j == '\t'));
3227063Srrh 		ch = i;
3237063Srrh 		copyf--;
3247063Srrh 		control(getrq(),1);
3257063Srrh 		flushi();
3267063Srrh 		goto loop;
3277063Srrh 	}
3287063Srrh lt:
3297063Srrh 	ch = i;
3307063Srrh 	text();
3317063Srrh 	goto loop;
3327063Srrh }
33346852Sbostic void
catch()3347063Srrh catch(){
3357063Srrh /*
3367063Srrh 	prstr("Interrupt\n");
3377063Srrh */
3387063Srrh 	done3(01);
3397063Srrh }
34046852Sbostic void
fpecatch()3417063Srrh fpecatch(){
3427063Srrh 	prstrfl("Floating Exception.\n");
3437063Srrh 	signal(SIGFPE,fpecatch);
3447063Srrh }
34546852Sbostic void
kcatch()3467063Srrh kcatch(){
3477063Srrh 	signal(SIGTERM,SIG_IGN);
3487063Srrh 	done3(01);
3497063Srrh }
3507063Srrh #ifndef NROFF
acctg()3517063Srrh acctg() {
35246851Scael 	static char *acct_file = _PATH_TRACCT;
3537063Srrh 	acctf = open(acct_file,1);
3547063Srrh 	setuid(getuid());
3557063Srrh }
3567063Srrh #endif
init1(a)3577063Srrh init1(a)
3587063Srrh char a;
3597063Srrh {
3607063Srrh 	register char *p;
3617063Srrh 	char *mktemp();
36235269Sbostic 	static char tempname[] = "/tmp/taXXXXX";
3637063Srrh 	register i;
3647063Srrh 
3657063Srrh #ifndef NROFF
3667063Srrh 	acctg();/*open troff actg file while mode 4755*/
3677063Srrh #endif
36835269Sbostic 	p = mktemp(tempname);
3697063Srrh 	if(a == 'a')p = &p[5];
3707063Srrh 	if((close(creat(p, 0600))) < 0){
3717063Srrh 		prstr("Cannot create temp file.\n");
3727063Srrh 		exit(-1);
3737063Srrh 	}
3747063Srrh 	ibf = open(p, 2);
3757063Srrh 	for(i=256; --i;)trtab[i]=i;
3767063Srrh 	trtab[UNPAD] = ' ';
3777063Srrh 	mchbits();
3787063Srrh 	if(a != 'a')unlkp = p;
3797063Srrh }
init2()3807063Srrh init2()
3817063Srrh {
3827063Srrh 	register i,j;
3837063Srrh 	extern int block;
3847063Srrh 	extern char *setbrk();
3857063Srrh 	extern char *ttyname();
3867063Srrh 
3877063Srrh 	ttyod = 2;
3887063Srrh 	if(((ttyp=ttyname(j=0)) != (char *)0) ||
3897063Srrh 	   ((ttyp=ttyname(j=1)) != (char *)0) ||
3907063Srrh 	   ((ttyp=ttyname(j=2)) != (char *)0)
3917063Srrh 	  );else ttyp = "notty";
3927063Srrh 	iflg = j;
3937063Srrh 	if(ascii)mesg(0);
3947063Srrh 
3957063Srrh 	if((!ptid) && (!waitf)){
3967063Srrh 		if((ptid = open(ptname,1)) < 0){
3977063Srrh 			prstr("Typesetter busy.\n");
3987063Srrh 			done3(-2);
3997063Srrh 		}
4007063Srrh 	}
4017063Srrh 	ptinit();
4027063Srrh 	for(i=NEV; i--;)write(ibf, (char *)&block, EVS*sizeof(int));
4037063Srrh 	olinep = oline;
4047063Srrh 	ibufp = eibuf = ibuf;
4057063Srrh 	v.hp = init = 0;
4067063Srrh 	pinchar = inchar;	/* XXX */
4077063Srrh 	ioff = 0;
4087063Srrh 	v.nl = -1;
4097063Srrh 	cvtime();
4107063Srrh 	frame = stk = (struct s *)setbrk(DELTA);
4117063Srrh 	dip = &d[0];
4127063Srrh 	nxf = frame + 1;
4137063Srrh 	nx = mflg;
4147063Srrh }
cvtime()41530776Sbostic cvtime()
41630776Sbostic {
41730776Sbostic 	extern time_t time();
41830776Sbostic 	time_t t;
41930776Sbostic 	register struct tm *tmp;
4207063Srrh 
42130776Sbostic 	t = time((time_t *)0);
42230776Sbostic 	tmp = localtime(&t);
42330776Sbostic 	v.dy = tmp->tm_mday;
42430776Sbostic 	v.dw = tmp->tm_wday + 1;
42530776Sbostic 	v.yr = tmp->tm_year;
42630776Sbostic 	v.mo = tmp->tm_mon + 1;
4277063Srrh }
cnum(a)4287063Srrh cnum(a)
4297063Srrh char *a;
4307063Srrh {
4317063Srrh 	register i;
4327063Srrh 
4337063Srrh 	ibufp = a;
43417673Sralph 	eibuf = (char *) MAXPTR;
4357063Srrh 	i = atoi();
4367063Srrh 	ch = 0;
4377063Srrh 	return(i);
4387063Srrh }
mesg(f)4397063Srrh mesg(f)
4407063Srrh int f;
4417063Srrh {
44246852Sbostic 	struct stat cb;
4437063Srrh 	static int mode;
4447063Srrh 
4457063Srrh 	if (ttyp==0)
4467063Srrh 		return;
4477063Srrh 	if(!f){
44846852Sbostic 		stat(ttyp,&cb);
44946852Sbostic 		mode = (cb.st_mode);
4507063Srrh 		chmod(ttyp,mode & ~022);
4517063Srrh 	}else{
4527063Srrh 		chmod(ttyp,mode);
4537063Srrh 	}
4547063Srrh }
prstrfl(s)4557063Srrh prstrfl(s)
4567063Srrh char *s;
4577063Srrh {
4587063Srrh 	flusho();
4597063Srrh 	prstr(s);
4607063Srrh }
prstr(s)4617063Srrh prstr(s)
4627063Srrh char *s;
4637063Srrh {
4647063Srrh 	register i;
4657063Srrh 	register char *j;
4667063Srrh 
4677063Srrh 	j = s;
4687063Srrh 	for(i=0;*s;i++)s++;
4697063Srrh 	write(ttyod,j,i);
4707063Srrh }
control(a,b)4717063Srrh control(a,b)
4727063Srrh int a,b;
4737063Srrh {
4747063Srrh 	register i,j;
4757063Srrh 	extern filep boff();
4767063Srrh 
4777063Srrh 	i = a;
4787063Srrh 	if((i == 0) || ((j = findmn(i)) == -1))return(0);
4797063Srrh 	if(contab[j].rq & MMASK){
4807063Srrh 		nxf->nargs = 0;
4817063Srrh 		if(b)collect();
4827063Srrh 		flushi();
4837063Srrh 		return(pushi(((filep)contab[j].x.mx)<<BLKBITS));
4847063Srrh 	}else{
4857063Srrh 		if(!b)return(0);
4867063Srrh 		return((*contab[j].x.f)(0));
4877063Srrh 	}
4887063Srrh }
4897063Srrh 
getrq()4907063Srrh getrq(){
4917063Srrh 	register i,j;
4927063Srrh 
4937063Srrh 	if(((i=getach()) == 0) ||
4947063Srrh 	   ((j=getach()) == 0))goto rtn;
4957063Srrh 	i = PAIR(i,j);
4967063Srrh rtn:
4977063Srrh 	return(i);
4987063Srrh }
getch()4997063Srrh getch(){
5007063Srrh 	register int i, j, k;
5017063Srrh 
5027063Srrh 	level++;
5037063Srrh g0:
5047063Srrh 	if(ch){
5057063Srrh 		if(((i = ch) & CMASK) == '\n')nlflg++;
5067063Srrh 		ch = 0;
5077063Srrh 		level--;
5087063Srrh 		return(i);
5097063Srrh 	}
5107063Srrh 
5117063Srrh 	if(nlflg){
5127063Srrh 		level--;
5137063Srrh 		return('\n');
5147063Srrh 	}
5157063Srrh 
5167063Srrh 	if((k = (i = getch0()) & CMASK) != ESC){
5177063Srrh 		if(i & MOT)goto g2;
5187063Srrh 		if(k == FLSS){
5197063Srrh 			copyf++; raw++;
5207063Srrh 			i = getch0();
5217063Srrh 			if(!fi)flss = i;
5227063Srrh 			copyf--; raw--;
5237063Srrh 			goto g0;
5247063Srrh 		}
5257063Srrh 		if(k == RPT){
5267063Srrh 			setrpt();
5277063Srrh 			goto g0;
5287063Srrh 		}
5297063Srrh 		if(!copyf){
5307063Srrh 			if((k == 'f') && lg && !lgf){
5317063Srrh 				i = getlg(i);
5327063Srrh 				goto g2;
5337063Srrh 			}
5347063Srrh 			if((k == fc) || (k == tabch) || (k == ldrch)){
5357063Srrh 				if((i=setfield(k)) == 0)goto g0; else goto g2;
5367063Srrh 			}
5377063Srrh 			if(k == 010){
5387063Srrh 				i = makem(-width(' ' | chbits));
5397063Srrh 				goto g2;
5407063Srrh 			}
5417063Srrh 		}
5427063Srrh 		goto g2;
5437063Srrh 	}
5447063Srrh 	k = (j = getch0()) & CMASK;
5457063Srrh 	if(j & MOT){
5467063Srrh 		i = j;
5477063Srrh 		goto g2;
5487063Srrh 	}
5497063Srrh /*
5507063Srrh 	if(k == tdelim){
5517063Srrh 		i = TDELIM;
5527063Srrh 		tdelim = IMP;
5537063Srrh 		goto g2;
5547063Srrh 	}
5557063Srrh */
5567063Srrh 	switch(k){
5577063Srrh 
5587063Srrh 		case '\n':	/*concealed newline*/
5597063Srrh 			goto g0;
5607063Srrh 		case 'n':	/*number register*/
5617063Srrh 			setn();
5627063Srrh 			goto g0;
5637063Srrh 		case '*':	/*string indicator*/
5647063Srrh 			setstr();
5657063Srrh 			goto g0;
5667063Srrh 		case '$':	/*argument indicator*/
5677063Srrh 			seta();
5687063Srrh 			goto g0;
5697063Srrh 		case '{':	/*LEFT*/
5707063Srrh 			i = LEFT;
5717063Srrh 			goto gx;
5727063Srrh 		case '}':	/*RIGHT*/
5737063Srrh 			i = RIGHT;
5747063Srrh 			goto gx;
5757063Srrh 		case '"':	/*comment*/
5767063Srrh 			while(((i=getch0()) & CMASK ) != '\n');
5777063Srrh 			goto g2;
5787063Srrh 		case ESC:	/*double backslash*/
5797063Srrh 			i = eschar;
5807063Srrh 			goto gx;
5817063Srrh 		case 'e':	/*printable version of current eschar*/
5827063Srrh 			i = PRESC;
5837063Srrh 			goto gx;
5847063Srrh 		case ' ':	/*unpaddable space*/
5857063Srrh 			i = UNPAD;
5867063Srrh 			goto gx;
5877063Srrh 		case '|':	/*narrow space*/
5887063Srrh 			i = NARSP;
5897063Srrh 			goto gx;
5907063Srrh 		case '^':	/*half of narrow space*/
5917063Srrh 			i = HNSP;
5927063Srrh 			goto gx;
5937063Srrh 		case '\'':	/*\(aa*/
5947063Srrh 			i = 0222;
5957063Srrh 			goto gx;
5967063Srrh 		case '`':	/*\(ga*/
5977063Srrh 			i = 0223;
5987063Srrh 			goto gx;
5997063Srrh 		case '_':	/*\(ul*/
6007063Srrh 			i = 0224;
6017063Srrh 			goto gx;
6027063Srrh 		case '-':	/*current font minus*/
6037063Srrh 			i = 0210;
6047063Srrh 			goto gx;
6057063Srrh 		case '&':	/*filler*/
6067063Srrh 			i = FILLER;
6077063Srrh 			goto gx;
6087063Srrh 		case 'c':	/*to be continued*/
6097063Srrh 			i = CONT;
6107063Srrh 			goto gx;
6117063Srrh 		case ':':	/*lem's char*/
6127063Srrh 			i = COLON;
6137063Srrh 			goto gx;
6147063Srrh 		case '!':	/*transparent indicator*/
6157063Srrh 			i = XPAR;
6167063Srrh 			goto gx;
6177063Srrh 		case 't':	/*tab*/
6187063Srrh 			i = '\t';
6197063Srrh 			goto g2;
6207063Srrh 		case 'a':	/*leader (SOH)*/
6217063Srrh 			i = LEADER;
6227063Srrh 			goto g2;
6237063Srrh 		case '%':	/*ohc*/
6247063Srrh 			i = OHC;
6257063Srrh 			goto g2;
6267063Srrh 		case '.':	/*.*/
6277063Srrh 			i = '.';
6287063Srrh 		gx:
6297063Srrh 			i = (j & ~CMASK) | i;
6307063Srrh 			goto g2;
6317063Srrh 	}
6327063Srrh 	if(!copyf)
6337063Srrh 		switch(k){
6347063Srrh 
6357063Srrh 			case 'p':	/*spread*/
6367063Srrh 				spread++;
6377063Srrh 				goto g0;
6387063Srrh 			case '(':	/*special char name*/
6397063Srrh 				if((i=setch()) == 0)goto g0;
6407063Srrh 				break;
6417063Srrh 			case 's':	/*size indicator*/
6427063Srrh 				setps();
6437063Srrh 				goto g0;
6447063Srrh 			case 'f':	/*font indicator*/
6457063Srrh 				setfont(0);
6467063Srrh 				goto g0;
6477063Srrh 			case 'w':	/*width function*/
6487063Srrh 				setwd();
6497063Srrh 				goto g0;
6507063Srrh 			case 'v':	/*vert mot*/
6517063Srrh 				if(i = vmot())break;
6527063Srrh 				goto g0;
6537063Srrh 			case 'h': 	/*horiz mot*/
6547063Srrh 				if(i = hmot())break;
6557063Srrh 				goto g0;
6567063Srrh 			case 'z':	/*zero with char*/
6577063Srrh 				i = setz();
6587063Srrh 				break;
6597063Srrh 			case 'l':	/*hor line*/
6607063Srrh 				setline();
6617063Srrh 				goto g0;
6627063Srrh 			case 'L':	/*vert line*/
6637063Srrh 				setvline();
6647063Srrh 				goto g0;
6657063Srrh 			case 'b':	/*bracket*/
6667063Srrh 				setbra();
6677063Srrh 				goto g0;
6687063Srrh 			case 'o':	/*overstrike*/
6697063Srrh 				setov();
6707063Srrh 				goto g0;
6717063Srrh 			case 'k':	/*mark hor place*/
6727063Srrh 				if((i=findr(getsn())) == -1)goto g0;
6737063Srrh 				vlist[i] = v.hp = sumhp();	/* XXX */
6747063Srrh 				goto g0;
6757063Srrh 			case 'j':	/*mark output hor place*/
6767063Srrh 				if(!(i=getach()))goto g0;
6777063Srrh 				i = (i<<BYTE) | JREG;
6787063Srrh 				break;
6797063Srrh 			case '0':	/*number space*/
6807063Srrh 				i = makem(width('0' | chbits));
6817063Srrh 				break;
6827063Srrh 			case 'x':	/*extra line space*/
6837063Srrh 				if(i = xlss())break;
6847063Srrh 				goto g0;
6857063Srrh 			case 'u':	/*half em up*/
6867063Srrh 			case 'r':	/*full em up*/
6877063Srrh 			case 'd':	/*half em down*/
6887063Srrh 				i = sethl(k);
6897063Srrh 				break;
6907063Srrh 			default:
6917063Srrh 				i = j;
6927063Srrh 		}
6937063Srrh 	else{
6947063Srrh 		ch0 = j;
6957063Srrh 		i = eschar;
6967063Srrh 	}
6977063Srrh g2:
6987063Srrh 	if((i & CMASK) == '\n'){
6997063Srrh 		nlflg++;
7007063Srrh 		v.hp = 0;
7017063Srrh 		pinchar = inchar;	/* XXX */
7027063Srrh 		if(ip == 0)v.cd++;
7037063Srrh 	}
7047063Srrh 	if(!--level){
7057063Srrh 		/* j = width(i); */
7067063Srrh 		/* v.hp += j; */
7077063Srrh 		/* cwidth = j; */
7087063Srrh 		if (pinchar >= inchar + LNSIZE) {	/* XXX */
7097063Srrh 			inchar[0] = makem(sumhp());
7107063Srrh 			pinchar = &inchar[1];
7117063Srrh 		}
7127063Srrh 		*pinchar++ = i;	/* XXX */
7137063Srrh 	}
7147063Srrh 	return(i);
7157063Srrh }
7167063Srrh 
sumhp()7177063Srrh sumhp()	/* XXX - add up widths in inchar array */
7187063Srrh {
7197063Srrh 	register int n;
7207063Srrh 	register int *p;
7217063Srrh 
7227063Srrh 	n = 0;
7237063Srrh 	for (p = inchar; p < pinchar; p++)
7247063Srrh 		n += width(*p);
7257063Srrh 	return(n);
7267063Srrh }
7277063Srrh char ifilt[32] = {0,001,002,003,0,005,006,007,010,011,012};
getch0()7287063Srrh getch0(){
7297063Srrh 	register int i, j;
7307063Srrh 
7317063Srrh 	if(ch0){i=ch0; ch0=0; return(i);}
7327063Srrh 	if(nchar){nchar--; return(rchar);}
7337063Srrh 
7347063Srrh again:
7357063Srrh 	if(cp){
7367063Srrh 		if((i = *cp++) == 0){
7377063Srrh 			cp = 0;
7387063Srrh 			goto again;
7397063Srrh 		}
7407063Srrh 	}else if(ap){
7417063Srrh 		if((i = *ap++) == 0){
7427063Srrh 			ap = 0;
7437063Srrh 			goto again;
7447063Srrh 		}
7457063Srrh 	}else if(ip){
7467063Srrh 		if(ip == -1)i = rdtty();
7477063Srrh 		else i = rbf();
7487063Srrh 	}else{
7497063Srrh 		if(donef)done(0);
75031915Sbostic 		if(nx || ((ibufp >= eibuf) && (eibuf != (char *) MAXPTR))){
7517063Srrh 			if(nfo)goto g1;
7527063Srrh 		g0:
7537063Srrh 			if(nextfile()){
7547063Srrh 				if(ip)goto again;
7557063Srrh 				if(ibufp < eibuf)goto g2;
7567063Srrh 			}
7577063Srrh 		g1:
7587063Srrh 			nx = 0;
7597063Srrh 			if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0;
7607063Srrh 			ibufp = ibuf;
7617063Srrh 			eibuf = ibuf + j;
7627063Srrh 			if(ip)goto again;
7637063Srrh 		}
7647063Srrh 	g2:
7657063Srrh 		i = *ibufp++ & 0177;
7667063Srrh 		ioff++;
7677063Srrh 		if(i >= 040)goto g4; else i = ifilt[i];
7687063Srrh 	}
7697063Srrh 	if(raw)return(i);
7707063Srrh 	if((j = i & CMASK) == IMP)goto again;
7717063Srrh 	if((i == 0) && !init)goto again;
7727063Srrh g4:
7737063Srrh 	if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370))
7747063Srrh #ifndef NROFF
7757063Srrh 		if(spbits && (i>31) && ((codetab[i-32] & 0200))) i |= spbits;
7767063Srrh 		else
7777063Srrh #endif
7787063Srrh 		i |= chbits;
7797063Srrh 	if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC;
7807063Srrh 	return(i);
7817063Srrh }
nextfile()7827063Srrh nextfile(){
7837063Srrh 	register char *p;
7847063Srrh 
7857063Srrh n0:
7867063Srrh 	if(ifile)close(ifile);
7877063Srrh 	if(nx){
7887063Srrh 		p = nextf;
7897063Srrh 		if(*p != 0)goto n1;
7907063Srrh 	}
7917063Srrh 	if(ifi > 0){
7927063Srrh 		if(popf())goto n0; /*popf error*/
7937063Srrh 		return(1); /*popf ok*/
7947063Srrh 	}
7957063Srrh 	if(rargc-- <= 0)goto n2;
7967063Srrh 	p = (argp++)[0];
7977063Srrh n1:
7987063Srrh 	if((p[0] == '-') && (p[1] == 0)){
7997063Srrh 		ifile = 0;
8007063Srrh 	}else if((ifile=open(p,0)) < 0){
8017063Srrh 		prstr("Cannot open ");
8027063Srrh 		prstr(p);
8037063Srrh 		prstr("\n");
8047063Srrh 		nfo -= mflg;
8057063Srrh 		done(02);
8067063Srrh 	}
8077063Srrh 	nfo++;
8087063Srrh 	v.cd = 0;
8097063Srrh 	ioff = 0;
8107063Srrh 	return(0);
8117063Srrh n2:
8127063Srrh 	if((nfo -= mflg) && !stdi)done(0);
8137063Srrh 	nfo++;
8147063Srrh 	v.cd = ifile =  stdi = mflg = 0;
8157063Srrh 	ioff = 0;
8167063Srrh 	return(0);
8177063Srrh }
popf()8187063Srrh popf(){
8197063Srrh 	register i;
8207063Srrh 	register char *p, *q;
8217063Srrh 	extern char *ttyname();
8227063Srrh 
8237063Srrh 	ioff = offl[--ifi];
8247063Srrh 	ip = ipl[ifi];
8257063Srrh 	if((ifile = ifl[ifi]) == 0){
8267063Srrh 		p = xbuf;
8277063Srrh 		q = ibuf;
8287063Srrh 		ibufp = xbufp;
8297063Srrh 		eibuf = xeibuf;
8307063Srrh 		while(q < eibuf)*q++ = *p++;
8317063Srrh 		return(0);
8327063Srrh 	}
8337063Srrh 	if((lseek(ifile,(long)(ioff & ~(IBUFSZ-1)),0) < 0) ||
8347063Srrh 	   ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1);
8357063Srrh 	eibuf = ibuf + i;
8367063Srrh 	ibufp = ibuf;
8377063Srrh 	if(ttyname(ifile) == (char *)0)
8387063Srrh 		if((ibufp = ibuf + (int)(ioff & (IBUFSZ-1)))  >= eibuf)return(1);
8397063Srrh 	return(0);
8407063Srrh }
flushi()8417063Srrh flushi(){
8427063Srrh 	if(nflush)return;
8437063Srrh 	ch = 0;
8447063Srrh 	if((ch0 & CMASK) == '\n')nlflg++;
8457063Srrh 	ch0 = 0;
8467063Srrh 	copyf++;
8477063Srrh 	while(!nlflg){
8487063Srrh 		if(donef && (frame == stk))break;
8497063Srrh 		getch();
8507063Srrh 	}
8517063Srrh 	copyf--;
8527063Srrh 	v.hp = 0;
8537063Srrh 	pinchar = inchar;	/* XXX */
8547063Srrh }
getach()8557063Srrh getach(){
8567063Srrh 	register i;
8577063Srrh 
8587063Srrh 	lgf++;
8597063Srrh 	if(((i = getch()) & MOT) ||
8607063Srrh 	    ((i&CMASK) == ' ') ||
8617063Srrh 	    ((i&CMASK) == '\n')||
8627063Srrh 	    (i & 0200)){
8637063Srrh 			ch = i;
8647063Srrh 			i = 0;
8657063Srrh 	}
8667063Srrh 	lgf--;
8677063Srrh 	return(i & 0177);
8687063Srrh }
casenx()8697063Srrh casenx(){
8707063Srrh 	lgf++;
8717063Srrh 	skip();
8727063Srrh 	getname();
8737063Srrh 	nx++;
8747063Srrh 	nextfile();
8757063Srrh 	nlflg++;
8767063Srrh 	ip = 0;
8777063Srrh 	ap = 0;
8787063Srrh 	nchar = pendt = 0;
8797063Srrh 	frame = stk;
8807063Srrh 	nxf = frame + 1;
8817063Srrh }
getname()8827063Srrh getname(){
8837063Srrh 	register int i, j, k;
8847063Srrh 
8857063Srrh 	lgf++;
8867063Srrh 	for(k=0; k < (NS-1); k++){
8877063Srrh 		if(((j=(i=getch()) & CMASK) <= ' ') ||
8887063Srrh 			(j > 0176))break;
8897063Srrh 		nextf[k] = j;
8907063Srrh 	}
8917063Srrh 	nextf[k] = 0;
8927063Srrh 	ch = i;
8937063Srrh 	lgf--;
8947063Srrh 	return(nextf[0]);
8957063Srrh }
caseso()8967063Srrh caseso(){
8977063Srrh 	register i;
8987063Srrh 	register char *p, *q;
8997063Srrh 
9007063Srrh 	lgf++;
9017063Srrh 	nextf[0] = 0;
9027063Srrh 	if(skip() || !getname() || ((i=open(nextf,0)) <0) || (ifi >= NSO)) {
9037063Srrh 		prstr("can't open file ");
9047063Srrh 		prstr(nextf);
9057063Srrh 		prstr("\n");
9067063Srrh 		done(02);
9077063Srrh 	}
9087063Srrh 	flushi();
9097063Srrh 	ifl[ifi] = ifile;
9107063Srrh 	ifile = i;
9117063Srrh 	offl[ifi] = ioff;
9127063Srrh 	ioff = 0;
9137063Srrh 	ipl[ifi] = ip;
9147063Srrh 	ip = 0;
9157063Srrh 	nx++;
9167063Srrh 	nflush++;
9177063Srrh 	if(!ifl[ifi++]){
9187063Srrh 		p = ibuf;
9197063Srrh 		q = xbuf;
9207063Srrh 		xbufp = ibufp;
9217063Srrh 		xeibuf = eibuf;
9227063Srrh 		while(p < eibuf)*q++ = *p++;
9237063Srrh 	}
9247063Srrh }
9257063Srrh 
casecf()9267063Srrh casecf(){	/* copy file without change */
9277063Srrh 	int fd, i, n;
9287063Srrh 	char buf[OBUFSZ];
9297063Srrh 
9307063Srrh 	flusho();
9317063Srrh 	lgf++;
9327063Srrh 	nextf[0] = 0;
9337063Srrh 	if(skip() || !getname() || ((fd=open(nextf,0)) <0) || (ifi >= NSO)) {
9347063Srrh 		prstr("can't open file ");
9357063Srrh 		prstr(nextf);
9367063Srrh 		prstr("\n");
9377063Srrh 		done(02);
9387063Srrh 	}
9397063Srrh 	while ((n = read(fd, buf, OBUFSZ)) > 0)
9407063Srrh 		for (i = 0; i < n; i++)
9417063Srrh 			oput(buf[i]);
9427063Srrh 	flusho();
9437063Srrh 	close(fd);
9447063Srrh }
getpn(a)9457063Srrh getpn(a)
9467063Srrh char *a;
9477063Srrh {
9487063Srrh 	register i, neg;
9497063Srrh 	long atoi1();
9507063Srrh 
9517063Srrh 	if((*a & 0177) == 0)return;
9527063Srrh 	neg = 0;
9537063Srrh 	ibufp = a;
95417673Sralph 	eibuf = (char *) MAXPTR;
9557063Srrh 	noscale++;
9567063Srrh 	while((i = getch() & CMASK) != 0)switch(i){
9577063Srrh 		case '+':
9587063Srrh 		case ',':
9597063Srrh 			continue;
9607063Srrh 		case '-':
9617063Srrh 			neg = MOT;
9627063Srrh 			goto d2;
9637063Srrh 		default:
9647063Srrh 			ch = i;
9657063Srrh 		d2:
9667063Srrh 			i = atoi1();
9677063Srrh 			if(nonumb)goto fini;
9687063Srrh 			else{
9697063Srrh 				*pnp++ = i | neg;
9707063Srrh 				neg = 0;
9717063Srrh 				if(pnp >= &pnlist[NPN-2]){
9727063Srrh 					prstr("Too many page numbers\n");
9737063Srrh 					done3(-3);
9747063Srrh 				}
9757063Srrh 			}
9767063Srrh 		}
9777063Srrh fini:
9787063Srrh 	if(neg)*pnp++ = -2;
9797063Srrh 	*pnp = -1;
9807063Srrh 	ch = noscale = print = 0;
9817063Srrh 	pnp = pnlist;
9827063Srrh 	if(*pnp != -1)chkpn();
9837063Srrh }
setrpt()9847063Srrh setrpt(){
9857063Srrh 	register i, j;
9867063Srrh 
9877063Srrh 	copyf++;raw++;
9887063Srrh 	i = getch0();
9897063Srrh 	copyf--;raw--;
9907063Srrh 	if((i < 0) ||
9917063Srrh 	   (((j = getch0()) & CMASK) == RPT))return;
9927063Srrh 	rchar = j;
9937063Srrh 	nchar = i & BMASK;
9947063Srrh }
995