xref: /csrg-svn/old/roff/common_source/n1.c (revision 7063)
1*7063Srrh #ifndef lint
2*7063Srrh static char sccsid[] = "@(#)n1.c	4.1 06/07/82";
3*7063Srrh #endif lint
4*7063Srrh 
5*7063Srrh #include <sys/types.h>
6*7063Srrh #include <sys/stat.h>
7*7063Srrh #include "tdef.h"
8*7063Srrh extern
9*7063Srrh #include "d.h"
10*7063Srrh extern
11*7063Srrh #include "v.h"
12*7063Srrh #ifdef NROFF
13*7063Srrh extern
14*7063Srrh #include "tw.h"
15*7063Srrh #endif
16*7063Srrh #include "sdef.h"
17*7063Srrh #include <setjmp.h>
18*7063Srrh jmp_buf sjbuf;
19*7063Srrh #include	<sgtty.h>
20*7063Srrh /*
21*7063Srrh troff1.c
22*7063Srrh 
23*7063Srrh consume options, initialization, main loop,
24*7063Srrh input routines, escape function calling
25*7063Srrh */
26*7063Srrh 
27*7063Srrh int	inchar[LNSIZE], *pinchar = inchar;	/* XXX */
28*7063Srrh extern struct s *frame, *stk, *nxf;
29*7063Srrh extern struct s *ejl, *litlev;
30*7063Srrh extern filep ip;
31*7063Srrh extern filep offset;
32*7063Srrh extern filep nextb;
33*7063Srrh 
34*7063Srrh 
35*7063Srrh extern int stdi;
36*7063Srrh extern int waitf;
37*7063Srrh extern int nofeed;
38*7063Srrh extern int quiet;
39*7063Srrh extern int ptid;
40*7063Srrh extern int ascii;
41*7063Srrh extern int npn;
42*7063Srrh extern int xflg;
43*7063Srrh extern int stop;
44*7063Srrh extern char ibuf[IBUFSZ];
45*7063Srrh extern char xbuf[IBUFSZ];
46*7063Srrh extern char *ibufp;
47*7063Srrh extern char *xbufp;
48*7063Srrh extern char *eibuf;
49*7063Srrh extern char *xeibuf;
50*7063Srrh extern int cbuf[NC];
51*7063Srrh extern int *cp;
52*7063Srrh extern int *vlist;
53*7063Srrh extern int nx;
54*7063Srrh extern int mflg;
55*7063Srrh extern int ch;
56*7063Srrh extern int pto;
57*7063Srrh extern int pfrom;
58*7063Srrh extern int cps;
59*7063Srrh extern int chbits;
60*7063Srrh extern int ibf;
61*7063Srrh extern int ttyod;
62*7063Srrh extern struct sgttyb ttys;
63*7063Srrh extern int iflg;
64*7063Srrh extern int init;
65*7063Srrh extern int rargc;
66*7063Srrh extern char **argp;
67*7063Srrh extern char trtab[256];
68*7063Srrh extern int lgf;
69*7063Srrh extern int copyf;
70*7063Srrh extern int eschar;
71*7063Srrh extern int ch0;
72*7063Srrh extern int cwidth;
73*7063Srrh extern int nlflg;
74*7063Srrh extern int *ap;
75*7063Srrh extern int donef;
76*7063Srrh extern int nflush;
77*7063Srrh extern int nchar;
78*7063Srrh extern int rchar;
79*7063Srrh extern int nfo;
80*7063Srrh extern int ifile;
81*7063Srrh extern int fc;
82*7063Srrh extern int padc;
83*7063Srrh extern int tabc;
84*7063Srrh extern int dotc;
85*7063Srrh extern int raw;
86*7063Srrh extern int tabtab[NTAB];
87*7063Srrh extern char nextf[];
88*7063Srrh extern int nfi;
89*7063Srrh #ifdef NROFF
90*7063Srrh extern char termtab[];
91*7063Srrh extern int tti;
92*7063Srrh #endif
93*7063Srrh extern int ifl[NSO];
94*7063Srrh extern int ifi;
95*7063Srrh extern int pendt;
96*7063Srrh extern int flss;
97*7063Srrh extern int fi;
98*7063Srrh extern int lg;
99*7063Srrh extern char ptname[];
100*7063Srrh extern int print;
101*7063Srrh extern int nonumb;
102*7063Srrh extern int pnlist[];
103*7063Srrh extern int *pnp;
104*7063Srrh extern int nb;
105*7063Srrh extern int trap;
106*7063Srrh extern int tflg;
107*7063Srrh extern int ejf;
108*7063Srrh extern int lit;
109*7063Srrh extern int cc;
110*7063Srrh extern int c2;
111*7063Srrh extern int spread;
112*7063Srrh extern int gflag;
113*7063Srrh extern int oline[];
114*7063Srrh extern int *olinep;
115*7063Srrh extern int dpn;
116*7063Srrh extern int noscale;
117*7063Srrh extern char *unlkp;
118*7063Srrh extern int pts;
119*7063Srrh extern int level;
120*7063Srrh extern int ttysave;
121*7063Srrh extern int tdelim;
122*7063Srrh extern int dotT;
123*7063Srrh extern int tabch, ldrch;
124*7063Srrh extern int eqflg;
125*7063Srrh extern no_out;
126*7063Srrh extern int hflg;
127*7063Srrh #ifndef NROFF
128*7063Srrh extern char codetab[];
129*7063Srrh extern int spbits;
130*7063Srrh #endif
131*7063Srrh extern int xxx;
132*7063Srrh int stopmesg;
133*7063Srrh filep ipl[NSO];
134*7063Srrh long offl[NSO];
135*7063Srrh long ioff;
136*7063Srrh char *ttyp;
137*7063Srrh extern struct contab {
138*7063Srrh 	int rq;
139*7063Srrh 	union {
140*7063Srrh 		int (*f)();
141*7063Srrh 		unsigned mx;
142*7063Srrh 	}x;
143*7063Srrh }contab[NM];
144*7063Srrh int ms[] = {31,28,31,30,31,30,31,31,30,31,30,31};
145*7063Srrh #ifndef NROFF
146*7063Srrh int acctf;
147*7063Srrh #endif
148*7063Srrh 
149*7063Srrh main(argc,argv)
150*7063Srrh int argc;
151*7063Srrh char **argv;
152*7063Srrh {
153*7063Srrh 	char *p, *q;
154*7063Srrh 	register i, j;
155*7063Srrh 	extern catch(), fpecatch(), kcatch();
156*7063Srrh 
157*7063Srrh 	signal(SIGHUP,catch);
158*7063Srrh 	if(signal(SIGINT,catch) == SIG_IGN){
159*7063Srrh 		signal(SIGHUP,SIG_IGN);
160*7063Srrh 		signal(SIGINT,SIG_IGN);
161*7063Srrh 		signal(SIGQUIT,SIG_IGN);
162*7063Srrh 	}
163*7063Srrh 	signal(SIGFPE,fpecatch);
164*7063Srrh 	signal(SIGPIPE,catch);
165*7063Srrh 	signal(SIGTERM,kcatch);
166*7063Srrh 	init1(argv[0][0]);
167*7063Srrh options:
168*7063Srrh 	while(--argc > 0 && (++argv)[0][0]=='-')
169*7063Srrh 		switch(argv[0][1]){
170*7063Srrh 
171*7063Srrh 		case 0:
172*7063Srrh 			goto start;
173*7063Srrh 		case 'i':
174*7063Srrh 			stdi++;
175*7063Srrh 			continue;
176*7063Srrh 		case 'q':
177*7063Srrh 			quiet++;
178*7063Srrh 			if(gtty(0, &ttys) >= 0)
179*7063Srrh 				ttysave = ttys.sg_flags;
180*7063Srrh 			continue;
181*7063Srrh 		case 'n':
182*7063Srrh 			npn = cnum(&argv[0][2]);
183*7063Srrh 			continue;
184*7063Srrh 		case 'p':
185*7063Srrh 			xflg = 0;
186*7063Srrh 			cps = cnum(&argv[0][2]);
187*7063Srrh 			continue;
188*7063Srrh 		case 'S':
189*7063Srrh 			stopmesg++;
190*7063Srrh 			continue;
191*7063Srrh 		case 's':
192*7063Srrh 			if(!(stop = cnum(&argv[0][2])))stop++;
193*7063Srrh 			continue;
194*7063Srrh 		case 'r':
195*7063Srrh 			vlist[findr(argv[0][2])] = cnum(&argv[0][3]);
196*7063Srrh 			continue;
197*7063Srrh 		case 'm':
198*7063Srrh 			p = &nextf[nfi];
199*7063Srrh 			q = &argv[0][2];
200*7063Srrh 			while((*p++ = *q++) != 0);
201*7063Srrh 			if (access(nextf, 4) < 0) {
202*7063Srrh char *local = "/usr/local/lib/tmac/tmac.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
203*7063Srrh 				strcat(local, &argv[0][2]);
204*7063Srrh 				if (access(local, 4) == 0)
205*7063Srrh 					strcpy(nextf, local);
206*7063Srrh 			}
207*7063Srrh 			mflg++;
208*7063Srrh 			continue;
209*7063Srrh 		case 'o':
210*7063Srrh 			getpn(&argv[0][2]);
211*7063Srrh 			continue;
212*7063Srrh #ifdef NROFF
213*7063Srrh 		case 'h':
214*7063Srrh 			hflg++;
215*7063Srrh 			continue;
216*7063Srrh 		case 'z':
217*7063Srrh 			no_out++;
218*7063Srrh 			continue;
219*7063Srrh 		case 'e':
220*7063Srrh 			eqflg++;
221*7063Srrh 			continue;
222*7063Srrh 		case 'T':
223*7063Srrh 			p = &termtab[tti];
224*7063Srrh 			q = &argv[0][2];
225*7063Srrh 			if(!((*q) & 0177))continue;
226*7063Srrh 			while((*p++ = *q++) != 0);
227*7063Srrh 			dotT++;
228*7063Srrh 			continue;
229*7063Srrh #endif
230*7063Srrh #ifndef NROFF
231*7063Srrh 		case 'z':
232*7063Srrh 			no_out++;
233*7063Srrh 		case 'a':
234*7063Srrh 			ascii = 1;
235*7063Srrh 			nofeed++;
236*7063Srrh 		case 't':
237*7063Srrh 			ptid = 1;
238*7063Srrh 			continue;
239*7063Srrh 		case 'w':
240*7063Srrh 			waitf = 1;
241*7063Srrh 			continue;
242*7063Srrh 		case 'f':
243*7063Srrh 			nofeed++;
244*7063Srrh 			continue;
245*7063Srrh 		case 'x':
246*7063Srrh 			xflg = 0;
247*7063Srrh 			continue;
248*7063Srrh 		case 'b':
249*7063Srrh 			if(open(ptname,1) < 0)prstr("Busy.\n");
250*7063Srrh 			else prstr("Available.\n");
251*7063Srrh 			done3(0);
252*7063Srrh 		case 'g':
253*7063Srrh 			stop = ptid = gflag = 1;
254*7063Srrh 			dpn = 0;
255*7063Srrh 			continue;
256*7063Srrh #endif
257*7063Srrh 		default:
258*7063Srrh 			pto = cnum(&argv[0][1]);
259*7063Srrh 			continue;
260*7063Srrh 		}
261*7063Srrh 
262*7063Srrh 	if(argv[0][0] == '+'){
263*7063Srrh 		pfrom = cnum(&argv[0][1]);
264*7063Srrh 		print = 0;
265*7063Srrh 		if(argc > 0)goto options;
266*7063Srrh 	}
267*7063Srrh 
268*7063Srrh start:
269*7063Srrh 	argp = argv;
270*7063Srrh 	rargc = argc;
271*7063Srrh 	init2();
272*7063Srrh 	setjmp(sjbuf);
273*7063Srrh loop:
274*7063Srrh 	copyf = lgf = nb = nflush = nlflg = 0;
275*7063Srrh 	if(ip && (rbf0(ip)==0) && ejf && (frame->pframe <= ejl)){
276*7063Srrh 		nflush++;
277*7063Srrh 		trap = 0;
278*7063Srrh 		eject((struct s *)0);
279*7063Srrh 		goto loop;
280*7063Srrh 	}
281*7063Srrh 	i = getch();
282*7063Srrh 	if(pendt)goto lt;
283*7063Srrh 	if(lit && (frame <= litlev)){
284*7063Srrh 		lit--;
285*7063Srrh 		goto lt;
286*7063Srrh 	}
287*7063Srrh 	if((j = (i & CMASK)) == XPAR){
288*7063Srrh 		copyf++;
289*7063Srrh 		tflg++;
290*7063Srrh 		for(;(i & CMASK) != '\n';)pchar(i = getch());
291*7063Srrh 		tflg = 0;
292*7063Srrh 		copyf--;
293*7063Srrh 		goto loop;
294*7063Srrh 	}
295*7063Srrh 	if((j == cc) || (j == c2)){
296*7063Srrh 		if(j == c2)nb++;
297*7063Srrh 		copyf++;
298*7063Srrh 		while(((j=((i=getch()) & CMASK)) == ' ') ||
299*7063Srrh 			(j == '\t'));
300*7063Srrh 		ch = i;
301*7063Srrh 		copyf--;
302*7063Srrh 		control(getrq(),1);
303*7063Srrh 		flushi();
304*7063Srrh 		goto loop;
305*7063Srrh 	}
306*7063Srrh lt:
307*7063Srrh 	ch = i;
308*7063Srrh 	text();
309*7063Srrh 	goto loop;
310*7063Srrh }
311*7063Srrh catch(){
312*7063Srrh /*
313*7063Srrh 	prstr("Interrupt\n");
314*7063Srrh */
315*7063Srrh 	done3(01);
316*7063Srrh }
317*7063Srrh fpecatch(){
318*7063Srrh 	prstrfl("Floating Exception.\n");
319*7063Srrh 	signal(SIGFPE,fpecatch);
320*7063Srrh }
321*7063Srrh kcatch(){
322*7063Srrh 	signal(SIGTERM,SIG_IGN);
323*7063Srrh 	done3(01);
324*7063Srrh }
325*7063Srrh #ifndef NROFF
326*7063Srrh acctg() {
327*7063Srrh 	static char *acct_file = "/usr/adm/tracct";
328*7063Srrh 	acctf = open(acct_file,1);
329*7063Srrh 	setuid(getuid());
330*7063Srrh }
331*7063Srrh #endif
332*7063Srrh init1(a)
333*7063Srrh char a;
334*7063Srrh {
335*7063Srrh 	register char *p;
336*7063Srrh 	char *mktemp();
337*7063Srrh 	register i;
338*7063Srrh 
339*7063Srrh #ifndef NROFF
340*7063Srrh 	acctg();/*open troff actg file while mode 4755*/
341*7063Srrh #endif
342*7063Srrh 	p = mktemp("/tmp/taXXXXX");
343*7063Srrh 	if(a == 'a')p = &p[5];
344*7063Srrh 	if((close(creat(p, 0600))) < 0){
345*7063Srrh 		prstr("Cannot create temp file.\n");
346*7063Srrh 		exit(-1);
347*7063Srrh 	}
348*7063Srrh 	ibf = open(p, 2);
349*7063Srrh 	for(i=256; --i;)trtab[i]=i;
350*7063Srrh 	trtab[UNPAD] = ' ';
351*7063Srrh 	mchbits();
352*7063Srrh 	if(a != 'a')unlkp = p;
353*7063Srrh }
354*7063Srrh init2()
355*7063Srrh {
356*7063Srrh 	register i,j;
357*7063Srrh 	extern int block;
358*7063Srrh 	extern char *setbrk();
359*7063Srrh 	extern char *ttyname();
360*7063Srrh 
361*7063Srrh 	ttyod = 2;
362*7063Srrh 	if(((ttyp=ttyname(j=0)) != (char *)0) ||
363*7063Srrh 	   ((ttyp=ttyname(j=1)) != (char *)0) ||
364*7063Srrh 	   ((ttyp=ttyname(j=2)) != (char *)0)
365*7063Srrh 	  );else ttyp = "notty";
366*7063Srrh 	iflg = j;
367*7063Srrh 	if(ascii)mesg(0);
368*7063Srrh 
369*7063Srrh 	if((!ptid) && (!waitf)){
370*7063Srrh 		if((ptid = open(ptname,1)) < 0){
371*7063Srrh 			prstr("Typesetter busy.\n");
372*7063Srrh 			done3(-2);
373*7063Srrh 		}
374*7063Srrh 	}
375*7063Srrh 	ptinit();
376*7063Srrh 	for(i=NEV; i--;)write(ibf, (char *)&block, EVS*sizeof(int));
377*7063Srrh 	olinep = oline;
378*7063Srrh 	ibufp = eibuf = ibuf;
379*7063Srrh 	v.hp = init = 0;
380*7063Srrh 	pinchar = inchar;	/* XXX */
381*7063Srrh 	ioff = 0;
382*7063Srrh 	v.nl = -1;
383*7063Srrh 	cvtime();
384*7063Srrh 	frame = stk = (struct s *)setbrk(DELTA);
385*7063Srrh 	dip = &d[0];
386*7063Srrh 	nxf = frame + 1;
387*7063Srrh 	nx = mflg;
388*7063Srrh }
389*7063Srrh cvtime(){
390*7063Srrh 
391*7063Srrh 	long tt;
392*7063Srrh 	register i;
393*7063Srrh 
394*7063Srrh 	time(&tt);
395*7063Srrh 	tt -= 3600*ZONE;	/*5hrs for EST*/
396*7063Srrh 	v.dy = (tt/86400L) + 1;
397*7063Srrh 	v.dw = (v.dy + 3)%7 + 1;
398*7063Srrh 	for(v.yr=70;; v.yr++){
399*7063Srrh 		if((v.yr)%4)ms[1]=28;else ms[1]=29;
400*7063Srrh 		for(i=0;i<12;){
401*7063Srrh 			if(v.dy<=ms[i]){
402*7063Srrh 				v.mo = i+1;
403*7063Srrh 				return;
404*7063Srrh 			}
405*7063Srrh 			v.dy -= ms[i++];
406*7063Srrh 		}
407*7063Srrh 	}
408*7063Srrh }
409*7063Srrh cnum(a)
410*7063Srrh char *a;
411*7063Srrh {
412*7063Srrh 	register i;
413*7063Srrh 
414*7063Srrh 	ibufp = a;
415*7063Srrh 	eibuf = MAXPTR;
416*7063Srrh 	i = atoi();
417*7063Srrh 	ch = 0;
418*7063Srrh 	return(i);
419*7063Srrh }
420*7063Srrh mesg(f)
421*7063Srrh int f;
422*7063Srrh {
423*7063Srrh 	static int mode;
424*7063Srrh 
425*7063Srrh 	if (ttyp==0)
426*7063Srrh 		return;
427*7063Srrh 	if(!f){
428*7063Srrh 		stat(ttyp,cbuf);
429*7063Srrh 		mode = ((struct stat *)(cbuf))->st_mode;
430*7063Srrh 		chmod(ttyp,mode & ~022);
431*7063Srrh 	}else{
432*7063Srrh 		chmod(ttyp,mode);
433*7063Srrh 	}
434*7063Srrh }
435*7063Srrh prstrfl(s)
436*7063Srrh char *s;
437*7063Srrh {
438*7063Srrh 	flusho();
439*7063Srrh 	prstr(s);
440*7063Srrh }
441*7063Srrh prstr(s)
442*7063Srrh char *s;
443*7063Srrh {
444*7063Srrh 	register i;
445*7063Srrh 	register char *j;
446*7063Srrh 
447*7063Srrh 	j = s;
448*7063Srrh 	for(i=0;*s;i++)s++;
449*7063Srrh 	write(ttyod,j,i);
450*7063Srrh }
451*7063Srrh control(a,b)
452*7063Srrh int a,b;
453*7063Srrh {
454*7063Srrh 	register i,j;
455*7063Srrh 	extern filep boff();
456*7063Srrh 
457*7063Srrh 	i = a;
458*7063Srrh 	if((i == 0) || ((j = findmn(i)) == -1))return(0);
459*7063Srrh 	if(contab[j].rq & MMASK){
460*7063Srrh 		nxf->nargs = 0;
461*7063Srrh 		if(b)collect();
462*7063Srrh 		flushi();
463*7063Srrh 		return(pushi(((filep)contab[j].x.mx)<<BLKBITS));
464*7063Srrh 	}else{
465*7063Srrh 		if(!b)return(0);
466*7063Srrh 		return((*contab[j].x.f)(0));
467*7063Srrh 	}
468*7063Srrh }
469*7063Srrh 
470*7063Srrh getrq(){
471*7063Srrh 	register i,j;
472*7063Srrh 
473*7063Srrh 	if(((i=getach()) == 0) ||
474*7063Srrh 	   ((j=getach()) == 0))goto rtn;
475*7063Srrh 	i = PAIR(i,j);
476*7063Srrh rtn:
477*7063Srrh 	return(i);
478*7063Srrh }
479*7063Srrh getch(){
480*7063Srrh 	register int i, j, k;
481*7063Srrh 
482*7063Srrh 	level++;
483*7063Srrh g0:
484*7063Srrh 	if(ch){
485*7063Srrh 		if(((i = ch) & CMASK) == '\n')nlflg++;
486*7063Srrh 		ch = 0;
487*7063Srrh 		level--;
488*7063Srrh 		return(i);
489*7063Srrh 	}
490*7063Srrh 
491*7063Srrh 	if(nlflg){
492*7063Srrh 		level--;
493*7063Srrh 		return('\n');
494*7063Srrh 	}
495*7063Srrh 
496*7063Srrh 	if((k = (i = getch0()) & CMASK) != ESC){
497*7063Srrh 		if(i & MOT)goto g2;
498*7063Srrh 		if(k == FLSS){
499*7063Srrh 			copyf++; raw++;
500*7063Srrh 			i = getch0();
501*7063Srrh 			if(!fi)flss = i;
502*7063Srrh 			copyf--; raw--;
503*7063Srrh 			goto g0;
504*7063Srrh 		}
505*7063Srrh 		if(k == RPT){
506*7063Srrh 			setrpt();
507*7063Srrh 			goto g0;
508*7063Srrh 		}
509*7063Srrh 		if(!copyf){
510*7063Srrh 			if((k == 'f') && lg && !lgf){
511*7063Srrh 				i = getlg(i);
512*7063Srrh 				goto g2;
513*7063Srrh 			}
514*7063Srrh 			if((k == fc) || (k == tabch) || (k == ldrch)){
515*7063Srrh 				if((i=setfield(k)) == 0)goto g0; else goto g2;
516*7063Srrh 			}
517*7063Srrh 			if(k == 010){
518*7063Srrh 				i = makem(-width(' ' | chbits));
519*7063Srrh 				goto g2;
520*7063Srrh 			}
521*7063Srrh 		}
522*7063Srrh 		goto g2;
523*7063Srrh 	}
524*7063Srrh 	k = (j = getch0()) & CMASK;
525*7063Srrh 	if(j & MOT){
526*7063Srrh 		i = j;
527*7063Srrh 		goto g2;
528*7063Srrh 	}
529*7063Srrh /*
530*7063Srrh 	if(k == tdelim){
531*7063Srrh 		i = TDELIM;
532*7063Srrh 		tdelim = IMP;
533*7063Srrh 		goto g2;
534*7063Srrh 	}
535*7063Srrh */
536*7063Srrh 	switch(k){
537*7063Srrh 
538*7063Srrh 		case '\n':	/*concealed newline*/
539*7063Srrh 			goto g0;
540*7063Srrh 		case 'n':	/*number register*/
541*7063Srrh 			setn();
542*7063Srrh 			goto g0;
543*7063Srrh 		case '*':	/*string indicator*/
544*7063Srrh 			setstr();
545*7063Srrh 			goto g0;
546*7063Srrh 		case '$':	/*argument indicator*/
547*7063Srrh 			seta();
548*7063Srrh 			goto g0;
549*7063Srrh 		case '{':	/*LEFT*/
550*7063Srrh 			i = LEFT;
551*7063Srrh 			goto gx;
552*7063Srrh 		case '}':	/*RIGHT*/
553*7063Srrh 			i = RIGHT;
554*7063Srrh 			goto gx;
555*7063Srrh 		case '"':	/*comment*/
556*7063Srrh 			while(((i=getch0()) & CMASK ) != '\n');
557*7063Srrh 			goto g2;
558*7063Srrh 		case ESC:	/*double backslash*/
559*7063Srrh 			i = eschar;
560*7063Srrh 			goto gx;
561*7063Srrh 		case 'e':	/*printable version of current eschar*/
562*7063Srrh 			i = PRESC;
563*7063Srrh 			goto gx;
564*7063Srrh 		case ' ':	/*unpaddable space*/
565*7063Srrh 			i = UNPAD;
566*7063Srrh 			goto gx;
567*7063Srrh 		case '|':	/*narrow space*/
568*7063Srrh 			i = NARSP;
569*7063Srrh 			goto gx;
570*7063Srrh 		case '^':	/*half of narrow space*/
571*7063Srrh 			i = HNSP;
572*7063Srrh 			goto gx;
573*7063Srrh 		case '\'':	/*\(aa*/
574*7063Srrh 			i = 0222;
575*7063Srrh 			goto gx;
576*7063Srrh 		case '`':	/*\(ga*/
577*7063Srrh 			i = 0223;
578*7063Srrh 			goto gx;
579*7063Srrh 		case '_':	/*\(ul*/
580*7063Srrh 			i = 0224;
581*7063Srrh 			goto gx;
582*7063Srrh 		case '-':	/*current font minus*/
583*7063Srrh 			i = 0210;
584*7063Srrh 			goto gx;
585*7063Srrh 		case '&':	/*filler*/
586*7063Srrh 			i = FILLER;
587*7063Srrh 			goto gx;
588*7063Srrh 		case 'c':	/*to be continued*/
589*7063Srrh 			i = CONT;
590*7063Srrh 			goto gx;
591*7063Srrh 		case ':':	/*lem's char*/
592*7063Srrh 			i = COLON;
593*7063Srrh 			goto gx;
594*7063Srrh 		case '!':	/*transparent indicator*/
595*7063Srrh 			i = XPAR;
596*7063Srrh 			goto gx;
597*7063Srrh 		case 't':	/*tab*/
598*7063Srrh 			i = '\t';
599*7063Srrh 			goto g2;
600*7063Srrh 		case 'a':	/*leader (SOH)*/
601*7063Srrh 			i = LEADER;
602*7063Srrh 			goto g2;
603*7063Srrh 		case '%':	/*ohc*/
604*7063Srrh 			i = OHC;
605*7063Srrh 			goto g2;
606*7063Srrh 		case '.':	/*.*/
607*7063Srrh 			i = '.';
608*7063Srrh 		gx:
609*7063Srrh 			i = (j & ~CMASK) | i;
610*7063Srrh 			goto g2;
611*7063Srrh 	}
612*7063Srrh 	if(!copyf)
613*7063Srrh 		switch(k){
614*7063Srrh 
615*7063Srrh 			case 'p':	/*spread*/
616*7063Srrh 				spread++;
617*7063Srrh 				goto g0;
618*7063Srrh 			case '(':	/*special char name*/
619*7063Srrh 				if((i=setch()) == 0)goto g0;
620*7063Srrh 				break;
621*7063Srrh 			case 's':	/*size indicator*/
622*7063Srrh 				setps();
623*7063Srrh 				goto g0;
624*7063Srrh 			case 'f':	/*font indicator*/
625*7063Srrh 				setfont(0);
626*7063Srrh 				goto g0;
627*7063Srrh 			case 'w':	/*width function*/
628*7063Srrh 				setwd();
629*7063Srrh 				goto g0;
630*7063Srrh 			case 'v':	/*vert mot*/
631*7063Srrh 				if(i = vmot())break;
632*7063Srrh 				goto g0;
633*7063Srrh 			case 'h': 	/*horiz mot*/
634*7063Srrh 				if(i = hmot())break;
635*7063Srrh 				goto g0;
636*7063Srrh 			case 'z':	/*zero with char*/
637*7063Srrh 				i = setz();
638*7063Srrh 				break;
639*7063Srrh 			case 'l':	/*hor line*/
640*7063Srrh 				setline();
641*7063Srrh 				goto g0;
642*7063Srrh 			case 'L':	/*vert line*/
643*7063Srrh 				setvline();
644*7063Srrh 				goto g0;
645*7063Srrh 			case 'b':	/*bracket*/
646*7063Srrh 				setbra();
647*7063Srrh 				goto g0;
648*7063Srrh 			case 'o':	/*overstrike*/
649*7063Srrh 				setov();
650*7063Srrh 				goto g0;
651*7063Srrh 			case 'k':	/*mark hor place*/
652*7063Srrh 				if((i=findr(getsn())) == -1)goto g0;
653*7063Srrh 				vlist[i] = v.hp = sumhp();	/* XXX */
654*7063Srrh 				goto g0;
655*7063Srrh 			case 'j':	/*mark output hor place*/
656*7063Srrh 				if(!(i=getach()))goto g0;
657*7063Srrh 				i = (i<<BYTE) | JREG;
658*7063Srrh 				break;
659*7063Srrh 			case '0':	/*number space*/
660*7063Srrh 				i = makem(width('0' | chbits));
661*7063Srrh 				break;
662*7063Srrh 			case 'x':	/*extra line space*/
663*7063Srrh 				if(i = xlss())break;
664*7063Srrh 				goto g0;
665*7063Srrh 			case 'u':	/*half em up*/
666*7063Srrh 			case 'r':	/*full em up*/
667*7063Srrh 			case 'd':	/*half em down*/
668*7063Srrh 				i = sethl(k);
669*7063Srrh 				break;
670*7063Srrh 			default:
671*7063Srrh 				i = j;
672*7063Srrh 		}
673*7063Srrh 	else{
674*7063Srrh 		ch0 = j;
675*7063Srrh 		i = eschar;
676*7063Srrh 	}
677*7063Srrh g2:
678*7063Srrh 	if((i & CMASK) == '\n'){
679*7063Srrh 		nlflg++;
680*7063Srrh 		v.hp = 0;
681*7063Srrh 		pinchar = inchar;	/* XXX */
682*7063Srrh 		if(ip == 0)v.cd++;
683*7063Srrh 	}
684*7063Srrh 	if(!--level){
685*7063Srrh 		/* j = width(i); */
686*7063Srrh 		/* v.hp += j; */
687*7063Srrh 		/* cwidth = j; */
688*7063Srrh 		if (pinchar >= inchar + LNSIZE) {	/* XXX */
689*7063Srrh 			inchar[0] = makem(sumhp());
690*7063Srrh 			pinchar = &inchar[1];
691*7063Srrh 		}
692*7063Srrh 		*pinchar++ = i;	/* XXX */
693*7063Srrh 	}
694*7063Srrh 	return(i);
695*7063Srrh }
696*7063Srrh 
697*7063Srrh sumhp()	/* XXX - add up widths in inchar array */
698*7063Srrh {
699*7063Srrh 	register int n;
700*7063Srrh 	register int *p;
701*7063Srrh 
702*7063Srrh 	n = 0;
703*7063Srrh 	for (p = inchar; p < pinchar; p++)
704*7063Srrh 		n += width(*p);
705*7063Srrh 	return(n);
706*7063Srrh }
707*7063Srrh char ifilt[32] = {0,001,002,003,0,005,006,007,010,011,012};
708*7063Srrh getch0(){
709*7063Srrh 	register int i, j;
710*7063Srrh 
711*7063Srrh 	if(ch0){i=ch0; ch0=0; return(i);}
712*7063Srrh 	if(nchar){nchar--; return(rchar);}
713*7063Srrh 
714*7063Srrh again:
715*7063Srrh 	if(cp){
716*7063Srrh 		if((i = *cp++) == 0){
717*7063Srrh 			cp = 0;
718*7063Srrh 			goto again;
719*7063Srrh 		}
720*7063Srrh 	}else if(ap){
721*7063Srrh 		if((i = *ap++) == 0){
722*7063Srrh 			ap = 0;
723*7063Srrh 			goto again;
724*7063Srrh 		}
725*7063Srrh 	}else if(ip){
726*7063Srrh 		if(ip == -1)i = rdtty();
727*7063Srrh 		else i = rbf();
728*7063Srrh 	}else{
729*7063Srrh 		if(donef)done(0);
730*7063Srrh 		if(nx || ((ibufp >= eibuf) && (ibufp != MAXPTR))){
731*7063Srrh 			if(nfo)goto g1;
732*7063Srrh 		g0:
733*7063Srrh 			if(nextfile()){
734*7063Srrh 				if(ip)goto again;
735*7063Srrh 				if(ibufp < eibuf)goto g2;
736*7063Srrh 			}
737*7063Srrh 		g1:
738*7063Srrh 			nx = 0;
739*7063Srrh 			if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0;
740*7063Srrh 			ibufp = ibuf;
741*7063Srrh 			eibuf = ibuf + j;
742*7063Srrh 			if(ip)goto again;
743*7063Srrh 		}
744*7063Srrh 	g2:
745*7063Srrh 		i = *ibufp++ & 0177;
746*7063Srrh 		ioff++;
747*7063Srrh 		if(i >= 040)goto g4; else i = ifilt[i];
748*7063Srrh 	}
749*7063Srrh 	if(raw)return(i);
750*7063Srrh 	if((j = i & CMASK) == IMP)goto again;
751*7063Srrh 	if((i == 0) && !init)goto again;
752*7063Srrh g4:
753*7063Srrh 	if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370))
754*7063Srrh #ifndef NROFF
755*7063Srrh 		if(spbits && (i>31) && ((codetab[i-32] & 0200))) i |= spbits;
756*7063Srrh 		else
757*7063Srrh #endif
758*7063Srrh 		i |= chbits;
759*7063Srrh 	if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC;
760*7063Srrh 	return(i);
761*7063Srrh }
762*7063Srrh nextfile(){
763*7063Srrh 	register char *p;
764*7063Srrh 
765*7063Srrh n0:
766*7063Srrh 	if(ifile)close(ifile);
767*7063Srrh 	if(nx){
768*7063Srrh 		p = nextf;
769*7063Srrh 		if(*p != 0)goto n1;
770*7063Srrh 	}
771*7063Srrh 	if(ifi > 0){
772*7063Srrh 		if(popf())goto n0; /*popf error*/
773*7063Srrh 		return(1); /*popf ok*/
774*7063Srrh 	}
775*7063Srrh 	if(rargc-- <= 0)goto n2;
776*7063Srrh 	p = (argp++)[0];
777*7063Srrh n1:
778*7063Srrh 	if((p[0] == '-') && (p[1] == 0)){
779*7063Srrh 		ifile = 0;
780*7063Srrh 	}else if((ifile=open(p,0)) < 0){
781*7063Srrh 		prstr("Cannot open ");
782*7063Srrh 		prstr(p);
783*7063Srrh 		prstr("\n");
784*7063Srrh 		nfo -= mflg;
785*7063Srrh 		done(02);
786*7063Srrh 	}
787*7063Srrh 	nfo++;
788*7063Srrh 	v.cd = 0;
789*7063Srrh 	ioff = 0;
790*7063Srrh 	return(0);
791*7063Srrh n2:
792*7063Srrh 	if((nfo -= mflg) && !stdi)done(0);
793*7063Srrh 	nfo++;
794*7063Srrh 	v.cd = ifile =  stdi = mflg = 0;
795*7063Srrh 	ioff = 0;
796*7063Srrh 	return(0);
797*7063Srrh }
798*7063Srrh popf(){
799*7063Srrh 	register i;
800*7063Srrh 	register char *p, *q;
801*7063Srrh 	extern char *ttyname();
802*7063Srrh 
803*7063Srrh 	ioff = offl[--ifi];
804*7063Srrh 	ip = ipl[ifi];
805*7063Srrh 	if((ifile = ifl[ifi]) == 0){
806*7063Srrh 		p = xbuf;
807*7063Srrh 		q = ibuf;
808*7063Srrh 		ibufp = xbufp;
809*7063Srrh 		eibuf = xeibuf;
810*7063Srrh 		while(q < eibuf)*q++ = *p++;
811*7063Srrh 		return(0);
812*7063Srrh 	}
813*7063Srrh 	if((lseek(ifile,(long)(ioff & ~(IBUFSZ-1)),0) < 0) ||
814*7063Srrh 	   ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1);
815*7063Srrh 	eibuf = ibuf + i;
816*7063Srrh 	ibufp = ibuf;
817*7063Srrh 	if(ttyname(ifile) == (char *)0)
818*7063Srrh 		if((ibufp = ibuf + (int)(ioff & (IBUFSZ-1)))  >= eibuf)return(1);
819*7063Srrh 	return(0);
820*7063Srrh }
821*7063Srrh flushi(){
822*7063Srrh 	if(nflush)return;
823*7063Srrh 	ch = 0;
824*7063Srrh 	if((ch0 & CMASK) == '\n')nlflg++;
825*7063Srrh 	ch0 = 0;
826*7063Srrh 	copyf++;
827*7063Srrh 	while(!nlflg){
828*7063Srrh 		if(donef && (frame == stk))break;
829*7063Srrh 		getch();
830*7063Srrh 	}
831*7063Srrh 	copyf--;
832*7063Srrh 	v.hp = 0;
833*7063Srrh 	pinchar = inchar;	/* XXX */
834*7063Srrh }
835*7063Srrh getach(){
836*7063Srrh 	register i;
837*7063Srrh 
838*7063Srrh 	lgf++;
839*7063Srrh 	if(((i = getch()) & MOT) ||
840*7063Srrh 	    ((i&CMASK) == ' ') ||
841*7063Srrh 	    ((i&CMASK) == '\n')||
842*7063Srrh 	    (i & 0200)){
843*7063Srrh 			ch = i;
844*7063Srrh 			i = 0;
845*7063Srrh 	}
846*7063Srrh 	lgf--;
847*7063Srrh 	return(i & 0177);
848*7063Srrh }
849*7063Srrh casenx(){
850*7063Srrh 	lgf++;
851*7063Srrh 	skip();
852*7063Srrh 	getname();
853*7063Srrh 	nx++;
854*7063Srrh 	nextfile();
855*7063Srrh 	nlflg++;
856*7063Srrh 	ip = 0;
857*7063Srrh 	ap = 0;
858*7063Srrh 	nchar = pendt = 0;
859*7063Srrh 	frame = stk;
860*7063Srrh 	nxf = frame + 1;
861*7063Srrh }
862*7063Srrh getname(){
863*7063Srrh 	register int i, j, k;
864*7063Srrh 
865*7063Srrh 	lgf++;
866*7063Srrh 	for(k=0; k < (NS-1); k++){
867*7063Srrh 		if(((j=(i=getch()) & CMASK) <= ' ') ||
868*7063Srrh 			(j > 0176))break;
869*7063Srrh 		nextf[k] = j;
870*7063Srrh 	}
871*7063Srrh 	nextf[k] = 0;
872*7063Srrh 	ch = i;
873*7063Srrh 	lgf--;
874*7063Srrh 	return(nextf[0]);
875*7063Srrh }
876*7063Srrh caseso(){
877*7063Srrh 	register i;
878*7063Srrh 	register char *p, *q;
879*7063Srrh 
880*7063Srrh 	lgf++;
881*7063Srrh 	nextf[0] = 0;
882*7063Srrh 	if(skip() || !getname() || ((i=open(nextf,0)) <0) || (ifi >= NSO)) {
883*7063Srrh 		prstr("can't open file ");
884*7063Srrh 		prstr(nextf);
885*7063Srrh 		prstr("\n");
886*7063Srrh 		done(02);
887*7063Srrh 	}
888*7063Srrh 	flushi();
889*7063Srrh 	ifl[ifi] = ifile;
890*7063Srrh 	ifile = i;
891*7063Srrh 	offl[ifi] = ioff;
892*7063Srrh 	ioff = 0;
893*7063Srrh 	ipl[ifi] = ip;
894*7063Srrh 	ip = 0;
895*7063Srrh 	nx++;
896*7063Srrh 	nflush++;
897*7063Srrh 	if(!ifl[ifi++]){
898*7063Srrh 		p = ibuf;
899*7063Srrh 		q = xbuf;
900*7063Srrh 		xbufp = ibufp;
901*7063Srrh 		xeibuf = eibuf;
902*7063Srrh 		while(p < eibuf)*q++ = *p++;
903*7063Srrh 	}
904*7063Srrh }
905*7063Srrh 
906*7063Srrh casecf(){	/* copy file without change */
907*7063Srrh 	int fd, i, n;
908*7063Srrh 	char buf[OBUFSZ];
909*7063Srrh 
910*7063Srrh 	flusho();
911*7063Srrh 	lgf++;
912*7063Srrh 	nextf[0] = 0;
913*7063Srrh 	if(skip() || !getname() || ((fd=open(nextf,0)) <0) || (ifi >= NSO)) {
914*7063Srrh 		prstr("can't open file ");
915*7063Srrh 		prstr(nextf);
916*7063Srrh 		prstr("\n");
917*7063Srrh 		done(02);
918*7063Srrh 	}
919*7063Srrh 	while ((n = read(fd, buf, OBUFSZ)) > 0)
920*7063Srrh 		for (i = 0; i < n; i++)
921*7063Srrh 			oput(buf[i]);
922*7063Srrh 	flusho();
923*7063Srrh 	close(fd);
924*7063Srrh }
925*7063Srrh getpn(a)
926*7063Srrh char *a;
927*7063Srrh {
928*7063Srrh 	register i, neg;
929*7063Srrh 	long atoi1();
930*7063Srrh 
931*7063Srrh 	if((*a & 0177) == 0)return;
932*7063Srrh 	neg = 0;
933*7063Srrh 	ibufp = a;
934*7063Srrh 	eibuf = MAXPTR;
935*7063Srrh 	noscale++;
936*7063Srrh 	while((i = getch() & CMASK) != 0)switch(i){
937*7063Srrh 		case '+':
938*7063Srrh 		case ',':
939*7063Srrh 			continue;
940*7063Srrh 		case '-':
941*7063Srrh 			neg = MOT;
942*7063Srrh 			goto d2;
943*7063Srrh 		default:
944*7063Srrh 			ch = i;
945*7063Srrh 		d2:
946*7063Srrh 			i = atoi1();
947*7063Srrh 			if(nonumb)goto fini;
948*7063Srrh 			else{
949*7063Srrh 				*pnp++ = i | neg;
950*7063Srrh 				neg = 0;
951*7063Srrh 				if(pnp >= &pnlist[NPN-2]){
952*7063Srrh 					prstr("Too many page numbers\n");
953*7063Srrh 					done3(-3);
954*7063Srrh 				}
955*7063Srrh 			}
956*7063Srrh 		}
957*7063Srrh fini:
958*7063Srrh 	if(neg)*pnp++ = -2;
959*7063Srrh 	*pnp = -1;
960*7063Srrh 	ch = noscale = print = 0;
961*7063Srrh 	pnp = pnlist;
962*7063Srrh 	if(*pnp != -1)chkpn();
963*7063Srrh }
964*7063Srrh setrpt(){
965*7063Srrh 	register i, j;
966*7063Srrh 
967*7063Srrh 	copyf++;raw++;
968*7063Srrh 	i = getch0();
969*7063Srrh 	copyf--;raw--;
970*7063Srrh 	if((i < 0) ||
971*7063Srrh 	   (((j = getch0()) & CMASK) == RPT))return;
972*7063Srrh 	rchar = j;
973*7063Srrh 	nchar = i & BMASK;
974*7063Srrh }
975