123879Sjaap #ifndef lint
2*64044Sbostic /*
333922Sjaap static char sccsid[] = "@(#)n1.c	2.2 (CWI) 88/03/31";
4*64044Sbostic */
5*64044Sbostic static char sccsid[] = "@(#)n1.c	2.3 (Berkeley) 07/27/93";
623879Sjaap #endif lint
723901Sjaap /*
823901Sjaap  * n1.c
923901Sjaap  *
1023901Sjaap  *	consume options, initialization, main loop,
1123901Sjaap  *	input routines, escape function calling
1223901Sjaap  */
1323901Sjaap 
1423879Sjaap #include <ctype.h>
1523901Sjaap #include <signal.h>
1623879Sjaap #include <sys/types.h>
1723879Sjaap #include <sys/stat.h>
1823901Sjaap #include <setjmp.h>
1923901Sjaap #include <sgtty.h>
2023901Sjaap 
2123879Sjaap #include "tdef.h"
22*64044Sbostic #include "pathnames.h"
2323901Sjaap #include "ext.h"
2423901Sjaap 
2523901Sjaap #include	<time.h>	/* See cvtime() (jaap) */
2623901Sjaap 
2723879Sjaap #ifdef NROFF
2823879Sjaap #include "tw.h"
2923879Sjaap #endif
3023901Sjaap 
3123879Sjaap jmp_buf sjbuf;
3223901Sjaap filep	ipl[NSO];
3323879Sjaap long	offl[NSO];
3423879Sjaap long	ioff;
3523879Sjaap char	*ttyp;
3623901Sjaap char	cfname[NSO][NS] = "<standard input>";	/*file name stack*/
3723901Sjaap int	cfline[NSO];		/*input line count stack*/
3823901Sjaap char	*progname;	/* program name (troff) */
3923879Sjaap 
main(argc,argv)4023879Sjaap main(argc, argv)
4123879Sjaap int	argc;
4223879Sjaap char	**argv;
4323879Sjaap {
4423879Sjaap 	register char	*p, *q;
4523879Sjaap 	register j;
4623901Sjaap 	register tchar i;
4723879Sjaap 	extern catch(), kcatch();
4823901Sjaap 	char	**oargv, *getenv();
4923879Sjaap 
5023901Sjaap 	progname = argv[0];
5123879Sjaap 	signal(SIGHUP, catch);
5223879Sjaap 	if (signal(SIGINT, catch) == SIG_IGN) {
5323879Sjaap 		signal(SIGHUP, SIG_IGN);
5423879Sjaap 		signal(SIGINT, SIG_IGN);
5523879Sjaap 		signal(SIGQUIT, SIG_IGN);
5623879Sjaap 	}
5723879Sjaap 	signal(SIGPIPE, catch);
5823879Sjaap 	signal(SIGTERM, kcatch);
5923879Sjaap 	oargv = argv;
6023901Sjaap 	mrehash();
6123901Sjaap 	nrehash();
6223879Sjaap 	init0();
6323901Sjaap 	if ((p = getenv("TYPESETTER")) != 0)
6423901Sjaap 		strcpy(devname, p);
6523879Sjaap 	while (--argc > 0 && (++argv)[0][0] == '-')
6623879Sjaap 		switch (argv[0][1]) {
6723879Sjaap 
6823879Sjaap 		case 'F':	/* switch font tables from default */
6923879Sjaap 			if (argv[0][2] != '\0') {
7023879Sjaap 				strcpy(termtab, &argv[0][2]);
7123879Sjaap 				strcpy(fontfile, &argv[0][2]);
7223879Sjaap 			} else {
7323879Sjaap 				argv++; argc--;
7423879Sjaap 				strcpy(termtab, argv[0]);
7523879Sjaap 				strcpy(fontfile, argv[0]);
7623879Sjaap 			}
7723879Sjaap 			continue;
7823879Sjaap 		case 0:
7923879Sjaap 			goto start;
8023879Sjaap 		case 'i':
8123879Sjaap 			stdi++;
8223879Sjaap 			continue;
8323879Sjaap 		case 'q':
8423879Sjaap 			quiet++;
8523879Sjaap 			if (gtty(0, &ttys) >= 0)
8623879Sjaap 				ttysave = ttys.sg_flags;
8723879Sjaap 			continue;
8823879Sjaap 		case 'n':
8923879Sjaap 			npn = ctoi(&argv[0][2]);
9023879Sjaap 			continue;
9123879Sjaap 		case 'u':	/* set emboldening amount */
9223879Sjaap 			bdtab[3] = ctoi(&argv[0][2]);
9323879Sjaap 			if (bdtab[3] < 0 || bdtab[3] > 50)
9423879Sjaap 				bdtab[3] = 0;
9523879Sjaap 			continue;
9623879Sjaap 		case 's':
9723879Sjaap 			if (!(stop = ctoi(&argv[0][2])))
9823879Sjaap 				stop++;
9923879Sjaap 			continue;
10023879Sjaap 		case 'r':
101*64044Sbostic 			eibuf = ibuf+strlen(ibuf);
102*64044Sbostic 			(void) sprintf(eibuf, ".nr %c %s\n",
10323879Sjaap 				argv[0][2], &argv[0][3]);
10423879Sjaap 			continue;
10523901Sjaap 		case 'c':
10623879Sjaap 		case 'm':
10723901Sjaap 			strcat(nextf, &argv[0][2]);
108*64044Sbostic 			if (access(nextf, 4) < 0) {
109*64044Sbostic 				char local[NS];
110*64044Sbostic 
111*64044Sbostic 				strcpy(local, _PATH_LOCAL_TMAC);
112*64044Sbostic 				strcat(local, &argv[0][2]);
113*64044Sbostic 				if (access(local, 4) == 0)
114*64044Sbostic 					strcpy(nextf, local);
115*64044Sbostic 			}
11623879Sjaap 			mflg++;
11723879Sjaap 			continue;
11823879Sjaap 		case 'o':
11923879Sjaap 			getpn(&argv[0][2]);
12023879Sjaap 			continue;
12123901Sjaap 		case 'T':
12223901Sjaap 			strcpy(devname, &argv[0][2]);
12323901Sjaap 			dotT++;
12423901Sjaap 			continue;
12523901Sjaap 		case 'D':	/* select DUTCH as hyphenation style (jaap) */
12623879Sjaap 			hyalg1 = hyalg = DUTCH;
12723879Sjaap 			thresh = DUTCH_THRESH;
12823879Sjaap 			continue;
12923879Sjaap #ifdef NROFF
13023879Sjaap 		case 'h':
13123879Sjaap 			hflg++;
13223879Sjaap 			continue;
13323879Sjaap 		case 'z':
13423879Sjaap 			no_out++;
13523879Sjaap 			continue;
13623879Sjaap 		case 'e':
13723879Sjaap 			eqflg++;
13823879Sjaap 			continue;
13923879Sjaap #endif
14023879Sjaap #ifndef NROFF
14123879Sjaap 		case 'z':
14223879Sjaap 			no_out++;
14323879Sjaap 		case 'a':
14423879Sjaap 			ascii = 1;
14523879Sjaap 			nofeed++;
14623879Sjaap 			continue;
14723879Sjaap 		case 'f':
14823879Sjaap 			nofeed++;
14923879Sjaap 			continue;
15023901Sjaap 		case 't':		/* for backward compatability */
15123901Sjaap 			continue;
15223879Sjaap #endif
15323879Sjaap 		default:
15423901Sjaap 			errprint("unknown option %s", argv[0]);
15523879Sjaap 			done(02);
15623879Sjaap 		}
15723879Sjaap 
15823879Sjaap start:
15923879Sjaap 	init1(oargv[0][0]);
16023879Sjaap 	argp = argv;
16123879Sjaap 	rargc = argc;
16223879Sjaap 	init2();
16323879Sjaap 	setjmp(sjbuf);
16423879Sjaap loop:
16523879Sjaap 	copyf = lgf = nb = nflush = nlflg = 0;
16623879Sjaap 	if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl) {
16723879Sjaap 		nflush++;
16823879Sjaap 		trap = 0;
16923879Sjaap 		eject((struct s *)0);
17023879Sjaap 		goto loop;
17123879Sjaap 	}
17223879Sjaap 	i = getch();
17323879Sjaap 	if (pendt)
17423901Sjaap 		goto Lt;
17523879Sjaap 	if ((j = cbits(i)) == XPAR) {
17623879Sjaap 		copyf++;
17723879Sjaap 		tflg++;
17823879Sjaap 		while (cbits(i) != '\n')
17923879Sjaap 			pchar(i = getch());
18023879Sjaap 		tflg = 0;
18123879Sjaap 		copyf--;
18223879Sjaap 		goto loop;
18323879Sjaap 	}
18423879Sjaap 	if (j == cc || j == c2) {
18523879Sjaap 		if (j == c2)
18623879Sjaap 			nb++;
18723879Sjaap 		copyf++;
18823879Sjaap 		while ((j = cbits(i = getch())) == ' ' || j == '\t')
18923879Sjaap 			;
19023879Sjaap 		ch = i;
19123879Sjaap 		copyf--;
19223879Sjaap 		control(getrq(), 1);
19323879Sjaap 		flushi();
19423879Sjaap 		goto loop;
19523879Sjaap 	}
19623901Sjaap Lt:
19723879Sjaap 	ch = i;
19823879Sjaap 	text();
19923901Sjaap 	if (nlflg)
20023901Sjaap 		numtab[HP].val = 0;
20123879Sjaap 	goto loop;
20223879Sjaap }
20323879Sjaap 
20423879Sjaap 
catch()20523879Sjaap catch()
20623879Sjaap {
20723879Sjaap 	done3(01);
20823879Sjaap }
20923879Sjaap 
21023879Sjaap 
kcatch()21123879Sjaap kcatch()
21223879Sjaap {
21323879Sjaap 	signal(SIGTERM, SIG_IGN);
21423879Sjaap 	done3(01);
21523879Sjaap }
21623879Sjaap 
21723879Sjaap 
init0()21823879Sjaap init0()
21923879Sjaap {
22023879Sjaap 	eibuf = ibufp = ibuf;
22123879Sjaap 	ibuf[0] = 0;
22223901Sjaap 	numtab[NL].val = -1;
22323879Sjaap }
22423879Sjaap 
22523879Sjaap 
init1(a)22623879Sjaap init1(a)
22723879Sjaap char	a;
22823879Sjaap {
22923879Sjaap 	register i;
23023879Sjaap 
23123879Sjaap 	for (i = NTRTAB; --i; )
23223879Sjaap 		trtab[i] = i;
23323879Sjaap 	trtab[UNPAD] = ' ';
23423879Sjaap }
23523879Sjaap 
23623879Sjaap 
init2()23723879Sjaap init2()
23823879Sjaap {
23923879Sjaap 	register i, j;
24023879Sjaap 	extern char	*ttyname();
241*64044Sbostic 	char *cp;
24223879Sjaap 
24323879Sjaap 	ttyod = 2;
24423879Sjaap 	if ((ttyp=ttyname(j=0)) != 0 || (ttyp=ttyname(j=1)) != 0 || (ttyp=ttyname(j=2)) != 0)
24523879Sjaap 		;
24623879Sjaap 	else
24723879Sjaap 		ttyp = "notty";
24823879Sjaap 	iflg = j;
24923879Sjaap 	if (ascii)
25023879Sjaap 		mesg(0);
25123879Sjaap 	ptinit();
25223879Sjaap 	mchbits();
25323879Sjaap 	cvtime();
25423901Sjaap 	numtab[PID].val = getpid();
25523879Sjaap 	olinep = oline;
25623879Sjaap 	ioff = 0;
25723901Sjaap 	numtab[HP].val = init = 0;
25823901Sjaap 	numtab[NL].val = -1;
25923879Sjaap 	nfo = 0;
26023879Sjaap 	ifile = 0;
26123879Sjaap 	copyf = raw = 0;
262*64044Sbostic 	cp = ibuf + strlen(ibuf);
263*64044Sbostic 	sprintf(cp, ".ds .T %s\n", devname);
264*64044Sbostic 	eibuf = cp + strlen(cp);
26523901Sjaap 	numtab[CD].val = -1;	/* compensation */
26623901Sjaap 	cpushback(ibuf);
26723879Sjaap 	ibufp = ibuf;
26823879Sjaap 	nx = mflg;
269*64044Sbostic 	frame = stk = (struct s *)malloc(DELTA * sizeof(struct s));
27023879Sjaap 	dip = &d[0];
27123879Sjaap 	nxf = frame + 1;
272*64044Sbostic 	for (i = 1; i < NEV; ++i)
273*64044Sbostic 		env_array[i] = *env;
27423879Sjaap }
27523879Sjaap 
27623901Sjaap /*
27723901Sjaap  * (jaap)
27823901Sjaap  * This replaces the old cvtime, so on well maintained systems, you don't
27923901Sjaap  * need to change the (quite unknown) ZONE constant in tdef.h
28023901Sjaap  */
28123901Sjaap 
cvtime()28223879Sjaap cvtime() {
28323879Sjaap 	long	tt;
28423879Sjaap 	register struct tm	*tym;
28523879Sjaap 	extern struct tm	*localtime();
28623879Sjaap 
28723879Sjaap 	time(&tt);
28823879Sjaap 	tym = localtime(&tt);
28923901Sjaap 	numtab[DY].val = tym->tm_mday;		/* Current day of the month */
29023901Sjaap 	numtab[DW].val = tym->tm_wday + 1;	/* Current day of the week */
29123901Sjaap 	numtab[YR].val = tym->tm_year;		/* Current year */
29223901Sjaap 	numtab[MO].val = tym->tm_mon + 1;	/* Current month of year */
29323879Sjaap }
29423879Sjaap 
29523901Sjaap 
ctoi(s)29623879Sjaap ctoi(s)
29723879Sjaap 	register char *s;
29823879Sjaap {
29923879Sjaap 	register n;
30023879Sjaap 
30123879Sjaap 	while (*s == ' ')
30223879Sjaap 		s++;
30323879Sjaap 	n = 0;
30423879Sjaap 	while (isdigit(*s))
30523879Sjaap 		n = 10 * n + *s++ - '0';
30623879Sjaap 	return n;
30723879Sjaap }
30823879Sjaap 
30923879Sjaap 
mesg(f)31023879Sjaap mesg(f)
31123879Sjaap int	f;
31223879Sjaap {
31323879Sjaap 	static int	mode;
31423901Sjaap 	struct stat stbuf;
31523879Sjaap 
31623879Sjaap 	if (!f) {
31723901Sjaap 		stat(ttyp, &stbuf);
31823901Sjaap 		mode = stbuf.st_mode;
31923879Sjaap 		chmod(ttyp, mode & ~0122);	/* turn off writing for others */
32023879Sjaap 	} else {
32123901Sjaap 		if (ttyp && *ttyp && mode)
32223879Sjaap 			chmod(ttyp, mode);
32323879Sjaap 	}
32423879Sjaap }
32523879Sjaap 
errprint(s,s1,s2,s3,s4,s5)32623901Sjaap errprint(s, s1, s2, s3, s4, s5)	/* error message printer */
32723901Sjaap 	char *s, *s1, *s2, *s3, *s4, *s5;
32823901Sjaap {
32923901Sjaap 	fdprintf(stderr, "%s: ", progname);
33023901Sjaap 	fdprintf(stderr, s, s1, s2, s3, s4, s5);
33123901Sjaap 	if (numtab[CD].val > 0)
33223901Sjaap 		fdprintf(stderr, "; line %d, file %s", numtab[CD].val, cfname[ifi]);
33323901Sjaap 	fdprintf(stderr, "\n");
33423901Sjaap 	stackdump();
33523901Sjaap }
33623879Sjaap 
control(a,b)33723879Sjaap control(a, b)
33823879Sjaap register int	a, b;
33923879Sjaap {
34023879Sjaap 	register int	j;
34123879Sjaap 
34223879Sjaap 	if (a == 0 || (j = findmn(a)) == -1)
34323879Sjaap 		return(0);
34423901Sjaap 	if (contab[j].f == 0) {
34523879Sjaap 		nxf->nargs = 0;
34623879Sjaap 		if (b)
34723879Sjaap 			collect();
34823879Sjaap 		flushi();
34923901Sjaap 		return pushi((filep)contab[j].mx, a);
35023879Sjaap 	} else if (b)
35123901Sjaap 		return((*contab[j].f)(0));
35223879Sjaap 	else
35323879Sjaap 		return(0);
35423879Sjaap }
35523879Sjaap 
35623879Sjaap 
getrq()35723879Sjaap getrq()
35823879Sjaap {
35923879Sjaap 	register i, j;
36023879Sjaap 
36123879Sjaap 	if (((i = getach()) == 0) || ((j = getach()) == 0))
36223879Sjaap 		goto rtn;
36323879Sjaap 	i = PAIR(i, j);
36423879Sjaap rtn:
36523879Sjaap 	return(i);
36623879Sjaap }
36723879Sjaap 
36823901Sjaap /*
36923901Sjaap  * table encodes some special characters, to speed up tests
37023901Sjaap  * in getchar, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
37123901Sjaap  */
37223879Sjaap 
37323901Sjaap char
37423901Sjaap gchtab[] = {
37523901Sjaap 	000,004,000,000,010,000,000,000, /* fc, ldr */
37623901Sjaap 	001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
37723901Sjaap 	000,000,000,000,000,000,000,000,
37823901Sjaap 	000,001,000,000,000,000,000,000, /* FLSS */
37923901Sjaap 	000,000,000,000,000,000,000,000,
38023901Sjaap 	000,000,000,000,000,000,000,000,
38123901Sjaap 	000,000,000,000,000,000,000,000,
38223901Sjaap 	000,000,000,000,000,000,000,000,
38323901Sjaap 	000,000,000,000,000,000,000,000,
38423901Sjaap 	000,000,000,000,000,000,000,000,
38523901Sjaap 	000,000,000,000,000,000,000,000,
38623901Sjaap 	000,000,000,000,000,000,000,000,
38723901Sjaap 	000,000,000,000,000,000,001,000, /* f */
38823901Sjaap 	000,000,000,000,000,000,000,000,
38923901Sjaap 	000,000,000,000,000,000,000,000,
39023901Sjaap 	000,000,000,000,000,000,000,000,
39123901Sjaap };
39223901Sjaap 
39323901Sjaap tchar
getch()39423901Sjaap getch()
39523879Sjaap {
39623879Sjaap 	register int	k;
39723901Sjaap 	register tchar i, j;
39823879Sjaap 	tchar setht(), setslant();
39923879Sjaap 
40023879Sjaap g0:
40123901Sjaap 	if (i = ch) {
40223901Sjaap 		if (cbits(i) == '\n')
40323879Sjaap 			nlflg++;
40423879Sjaap 		ch = 0;
40523879Sjaap 		return(i);
40623879Sjaap 	}
40723879Sjaap 
40823901Sjaap 	if (nlflg)
40923879Sjaap 		return('\n');
41023901Sjaap 	i = getch0();
41123901Sjaap 	if (ismot(i))
41223901Sjaap 		return(i);
41323901Sjaap 	k = cbits(i);
41423901Sjaap 	if (k != ESC) {
41523901Sjaap 		if (gchtab[k]==0)
41623901Sjaap 			return(i);
41723901Sjaap 		if (k == '\n') {
41823901Sjaap 			if (cbits(i) == '\n') {
41923901Sjaap 				nlflg++;
42023901Sjaap 				if (ip == 0)
42123901Sjaap 					numtab[CD].val++; /* line number */
42223901Sjaap 			}
42323901Sjaap 			return(k);
42423901Sjaap 		}
42523879Sjaap 		if (k == FLSS) {
42623879Sjaap 			copyf++;
42723879Sjaap 			raw++;
42823879Sjaap 			i = getch0();
42923879Sjaap 			if (!fi)
43023879Sjaap 				flss = i;
43123879Sjaap 			copyf--;
43223879Sjaap 			raw--;
43323879Sjaap 			goto g0;
43423879Sjaap 		}
43523879Sjaap 		if (k == RPT) {
43623879Sjaap 			setrpt();
43723879Sjaap 			goto g0;
43823879Sjaap 		}
43923879Sjaap 		if (!copyf) {
44023879Sjaap 			if (k == 'f' && lg && !lgf) {
44123879Sjaap 				i = getlg(i);
44223901Sjaap 				return(i);
44323879Sjaap 			}
44423879Sjaap 			if (k == fc || k == tabch || k == ldrch) {
44523879Sjaap 				if ((i = setfield(k)) == 0)
44623879Sjaap 					goto g0;
44723879Sjaap 				else
44823901Sjaap 					return(i);
44923879Sjaap 			}
45023879Sjaap 			if (k == '\b') {
45123879Sjaap 				i = makem(-width(' ' | chbits));
45223901Sjaap 				return(i);
45323879Sjaap 			}
45423879Sjaap 		}
45523901Sjaap 		return(i);
45623879Sjaap 	}
45723879Sjaap 	k = cbits(j = getch0());
45823901Sjaap 	if (ismot(j))
45923901Sjaap 		return(j);
46023879Sjaap 	switch (k) {
46123879Sjaap 
46223879Sjaap 	case '\n':	/* concealed newline */
46323879Sjaap 		goto g0;
46423879Sjaap 	case 'n':	/* number register */
46523879Sjaap 		setn();
46623879Sjaap 		goto g0;
46723879Sjaap 	case '*':	/* string indicator */
46823879Sjaap 		setstr();
46923879Sjaap 		goto g0;
47023879Sjaap 	case '$':	/* argument indicator */
47123879Sjaap 		seta();
47223879Sjaap 		goto g0;
47323879Sjaap 	case '{':	/* LEFT */
47423879Sjaap 		i = LEFT;
47523879Sjaap 		goto gx;
47623879Sjaap 	case '}':	/* RIGHT */
47723879Sjaap 		i = RIGHT;
47823879Sjaap 		goto gx;
47923879Sjaap 	case '"':	/* comment */
48023879Sjaap 		while (cbits(i = getch0()) != '\n')
48123879Sjaap 			;
48223901Sjaap 		nlflg++;
48323901Sjaap 		if (ip == 0)
48423901Sjaap 			numtab[CD].val++;
48523901Sjaap 		return(i);
48623879Sjaap 	case ESC:	/* double backslash */
48723879Sjaap 		i = eschar;
48823879Sjaap 		goto gx;
48923879Sjaap 	case 'e':	/* printable version of current eschar */
49023879Sjaap 		i = PRESC;
49123879Sjaap 		goto gx;
49223879Sjaap 	case ' ':	/* unpaddable space */
49323879Sjaap 		i = UNPAD;
49423879Sjaap 		goto gx;
49523879Sjaap 	case '\'':	/* \(aa */
49623879Sjaap 		i = ACUTE;
49723879Sjaap 		goto gx;
49823879Sjaap 	case '`':	/* \(ga */
49923879Sjaap 		i = GRAVE;
50023879Sjaap 		goto gx;
50123879Sjaap 	case '_':	/* \(ul */
50223879Sjaap 		i = UNDERLINE;
50323879Sjaap 		goto gx;
50423879Sjaap 	case '-':	/* current font minus */
50523879Sjaap 		i = MINUS;
50623879Sjaap 		goto gx;
50723879Sjaap 	case '&':	/* filler */
50823879Sjaap 		i = FILLER;
50923879Sjaap 		goto gx;
51023879Sjaap 	case 'c':	/* to be continued */
51123879Sjaap 		i = CONT;
51223879Sjaap 		goto gx;
51323879Sjaap 	case '!':	/* transparent indicator */
51423879Sjaap 		i = XPAR;
51523879Sjaap 		goto gx;
51623879Sjaap 	case 't':	/* tab */
51723879Sjaap 		i = '\t';
51823901Sjaap 		return(i);
51923879Sjaap 	case 'a':	/* leader (SOH) */
52023879Sjaap 		i = LEADER;
52123901Sjaap 		return(i);
52223879Sjaap 	case '%':	/* ohc */
52323879Sjaap 		i = OHC;
52423901Sjaap 		return(i);
52523879Sjaap 	case 'g':	/* return format of a number register */
52623879Sjaap 		setaf();
52723879Sjaap 		goto g0;
52823901Sjaap 	case 'N':	/* absolute character number */
52923901Sjaap 		i = setabs();
53023901Sjaap 		goto gx;
53123879Sjaap 	case '.':	/* . */
53223879Sjaap 		i = '.';
53323879Sjaap gx:
53423879Sjaap 		setsfbits(i, sfbits(j));
53523901Sjaap 		return(i);
53623879Sjaap 	}
53723901Sjaap 	if (copyf) {
53823901Sjaap 		*pbp++ = j;
53923901Sjaap 		return(eschar);
54023901Sjaap 	}
54123901Sjaap 	switch (k) {
54223879Sjaap 
54333922Sjaap 	case 'X':	/* \X'...' for copy through */
54433922Sjaap 		setxon();
54533922Sjaap 		goto g0;
54623901Sjaap 	case 'p':	/* spread */
54723901Sjaap 		spread++;
54823901Sjaap 		goto g0;
54923901Sjaap 	case '(':	/* special char name */
55023901Sjaap 		if ((i = setch()) == 0)
55123879Sjaap 			goto g0;
55223901Sjaap 		return(i);
55323901Sjaap 	case 's':	/* size indicator */
55423901Sjaap 		setps();
55523901Sjaap 		goto g0;
55623901Sjaap 	case 'H':	/* character height */
55723901Sjaap 		return(setht());
55823901Sjaap 	case 'S':	/* slant */
55923901Sjaap 		return(setslant());
56023901Sjaap 	case 'f':	/* font indicator */
56123901Sjaap 		setfont(0);
56223901Sjaap 		goto g0;
56323901Sjaap 	case 'w':	/* width function */
56423901Sjaap 		setwd();
56523901Sjaap 		goto g0;
56623901Sjaap 	case 'v':	/* vert mot */
56723901Sjaap 		if (i = vmot())
56823901Sjaap 			return(i);
56923901Sjaap 		goto g0;
57023901Sjaap 	case 'h': 	/* horiz mot */
57123901Sjaap 		if (i = hmot())
57223901Sjaap 			return(i);
57323901Sjaap 		goto g0;
57423901Sjaap 	case 'z':	/* zero with char */
57523901Sjaap 		return(setz());
57623901Sjaap 	case 'l':	/* hor line */
57723901Sjaap 		setline();
57823901Sjaap 		goto g0;
57923901Sjaap 	case 'L':	/* vert line */
58023901Sjaap 		setvline();
58123901Sjaap 		goto g0;
58223901Sjaap 	case 'D':	/* drawing function */
58323901Sjaap 		setdraw();
58423901Sjaap 		goto g0;
58523901Sjaap 	case 'b':	/* bracket */
58623901Sjaap 		setbra();
58723901Sjaap 		goto g0;
58823901Sjaap 	case 'o':	/* overstrike */
58923901Sjaap 		setov();
59023901Sjaap 		goto g0;
59123901Sjaap 	case 'k':	/* mark hor place */
59223901Sjaap 		if ((k = findr(getsn())) != -1) {
59323901Sjaap 			numtab[k].val = numtab[HP].val;
59423879Sjaap 		}
59523901Sjaap 		goto g0;
59623901Sjaap 	case '0':	/* number space */
59723901Sjaap 		return(makem(width('0' | chbits)));
59823901Sjaap #ifdef NROFF
59923901Sjaap 	case '|':
60023901Sjaap 	case '^':
60123901Sjaap 		goto g0;
60223901Sjaap #else
60323901Sjaap 	case '|':	/* narrow space */
60423901Sjaap 		return(makem((int)(EM)/6));
60523901Sjaap 	case '^':	/* half narrow space */
60623901Sjaap 		return(makem((int)(EM)/12));
60723901Sjaap #endif
60823901Sjaap 	case 'x':	/* extra line space */
60923901Sjaap 		if (i = xlss())
61023901Sjaap 			return(i);
61123901Sjaap 		goto g0;
61223901Sjaap 	case 'u':	/* half em up */
61323901Sjaap 	case 'r':	/* full em up */
61423901Sjaap 	case 'd':	/* half em down */
61523901Sjaap 		return(sethl(k));
61623901Sjaap 	default:
61723901Sjaap 		return(j);
61823879Sjaap 	}
61923901Sjaap 	/* NOTREACHED */
62023901Sjaap }
62123901Sjaap 
setxon()62223901Sjaap setxon()	/* \X'...' for copy through */
62323901Sjaap {
62423901Sjaap 	tchar xbuf[NC];
62523901Sjaap 	register tchar *i;
62623901Sjaap 	tchar c;
62723901Sjaap 	int delim, k;
62823901Sjaap 
62923901Sjaap 	if (ismot(c = getch()))
63023901Sjaap 		return;
63123901Sjaap 	delim = cbits(c);
63223901Sjaap 	i = xbuf;
63323901Sjaap 	*i++ = XON;
63423901Sjaap 	while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
63523901Sjaap 		if (k == ' ')
63623901Sjaap 			setcbits(c, UNPAD);
63723901Sjaap 		*i++ = c | ZBIT;
63823879Sjaap 	}
63923901Sjaap 	*i++ = XOFF;
64023901Sjaap 	*i = 0;
64123901Sjaap 	pushback(xbuf);
64223879Sjaap }
64323879Sjaap 
64423879Sjaap 
645*64044Sbostic #ifdef notdef
64623879Sjaap char	ifilt[32] = {
64723879Sjaap 	0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012};
648*64044Sbostic #endif
64923879Sjaap 
getch0()65023879Sjaap tchar getch0()
65123879Sjaap {
65223879Sjaap 	register int	j;
65323901Sjaap 	register tchar i;
65423879Sjaap 
65523879Sjaap again:
65623901Sjaap 	if (pbp > lastpbp)
65723901Sjaap 		i = *--pbp;
65823901Sjaap 	else if (ip) {
65923901Sjaap #ifdef INCORE
66023901Sjaap 		extern tchar corebuf[];
66123901Sjaap 		i = corebuf[ip];
66223901Sjaap 		if (i == 0)
66323901Sjaap 			i = rbf();
66423901Sjaap 		else {
66523901Sjaap 			if ((++ip & (BLK - 1)) == 0) {
66623901Sjaap 				--ip;
66723901Sjaap 				(void)rbf();
66823901Sjaap 			}
66923879Sjaap 		}
67023901Sjaap #else
67123901Sjaap 		i = rbf();
67223901Sjaap #endif
67323879Sjaap 	} else {
67423879Sjaap 		if (donef)
67523879Sjaap 			done(0);
67623879Sjaap 		if (nx || ibufp >= eibuf) {
67723901Sjaap 			if (nfo==0) {
67823879Sjaap g0:
67923901Sjaap 				if (nextfile()) {
68023901Sjaap 					if (ip)
68123901Sjaap 						goto again;
68223901Sjaap 					if (ibufp < eibuf)
68323901Sjaap 						goto g2;
68423901Sjaap 				}
68523879Sjaap 			}
68623879Sjaap 			nx = 0;
68723879Sjaap 			if ((j = read(ifile, ibuf, IBUFSZ)) <= 0)
68823879Sjaap 				goto g0;
68923879Sjaap 			ibufp = ibuf;
69023879Sjaap 			eibuf = ibuf + j;
69123879Sjaap 			if (ip)
69223879Sjaap 				goto again;
69323879Sjaap 		}
69423879Sjaap g2:
69523879Sjaap 		i = *ibufp++ & 0177;
69623879Sjaap 		ioff++;
69723901Sjaap 		if (i >= 040 && i < 0177)
69823901Sjaap 			goto g4;
699*64044Sbostic #ifdef notdef
70023901Sjaap 		if (i != 0177)
70123879Sjaap 			i = ifilt[i];
702*64044Sbostic #endif
70323879Sjaap 	}
70423901Sjaap 	if (cbits(i) == IMP && !raw)
70523879Sjaap 		goto again;
70623901Sjaap 	if ((i == 0 || i == 0177) && !init && !raw) {
70723879Sjaap 		goto again;
70823901Sjaap 	}
70923879Sjaap g4:
71023901Sjaap 	if (copyf == 0 && (i & ~BYTEMASK) == 0)
71123879Sjaap 		i |= chbits;
71223901Sjaap 	if (cbits(i) == eschar && !raw)
71323879Sjaap 		setcbits(i, ESC);
71423879Sjaap 	return(i);
71523879Sjaap }
71623879Sjaap 
pushback(b)71723901Sjaap pushback(b)
71823901Sjaap register tchar *b;
71923901Sjaap {
72023901Sjaap 	register tchar *ob = b;
72123879Sjaap 
72223901Sjaap 	while (*b++)
72323901Sjaap 		;
72423901Sjaap 	b--;
72523901Sjaap 	while (b > ob && pbp < &pbbuf[NC-3])
72623901Sjaap 		*pbp++ = *--b;
72723901Sjaap 	if (pbp >= &pbbuf[NC-3]) {
72823901Sjaap 		errprint("pushback overflow");
72923901Sjaap 		done(2);
73023901Sjaap 	}
73123901Sjaap }
73223901Sjaap 
cpushback(b)73323901Sjaap cpushback(b)
73423901Sjaap register char *b;
73523901Sjaap {
73623901Sjaap 	register char *ob = b;
73723901Sjaap 
73823901Sjaap 	while (*b++)
73923901Sjaap 		;
74023901Sjaap 	b--;
74123901Sjaap 	while (b > ob && pbp < &pbbuf[NC-3])
74223901Sjaap 		*pbp++ = *--b;
74323901Sjaap 	if (pbp >= &pbbuf[NC-3]) {
74423901Sjaap 		errprint("cpushback overflow");
74523901Sjaap 		done(2);
74623901Sjaap 	}
74723901Sjaap }
74823901Sjaap 
nextfile()74923879Sjaap nextfile()
75023879Sjaap {
75123879Sjaap 	register char	*p;
75223879Sjaap 
75323879Sjaap n0:
75423879Sjaap 	if (ifile)
75523879Sjaap 		close(ifile);
75623879Sjaap 	if (nx) {
75723879Sjaap 		p = nextf;
75823879Sjaap 		if (*p != 0)
75923879Sjaap 			goto n1;
76023879Sjaap 	}
76123879Sjaap 	if (ifi > 0) {
76223879Sjaap 		if (popf())
76323879Sjaap 			goto n0; /* popf error */
76423879Sjaap 		return(1); /* popf ok */
76523879Sjaap 	}
76623879Sjaap 	if (rargc-- <= 0) {
76723901Sjaap 		if ((nfo -= mflg) && !stdi)
76823901Sjaap 			done(0);
76923901Sjaap 		nfo++;
77023901Sjaap 		numtab[CD].val = ifile = stdi = mflg = 0;
77123901Sjaap 		strcpy(cfname[ifi], "<standard input>");
77223901Sjaap 		ioff = 0;
77323901Sjaap 		return(0);
77423879Sjaap 	}
77523879Sjaap 	p = (argp++)[0];
77623879Sjaap n1:
77723901Sjaap 	numtab[CD].val = 0;
77823901Sjaap 	if (p[0] == '-' && p[1] == 0) {
77923879Sjaap 		ifile = 0;
78023901Sjaap 		strcpy(cfname[ifi], "<standard input>");
78123879Sjaap 	} else if ((ifile = open(p, 0)) < 0) {
78223901Sjaap 		errprint("cannot open file %s", p);
78323879Sjaap 		nfo -= mflg;
78423879Sjaap 		done(02);
78523901Sjaap 	} else
78623901Sjaap 		strcpy(cfname[ifi],p);
78723879Sjaap 	nfo++;
78823879Sjaap 	ioff = 0;
78923879Sjaap 	return(0);
79023879Sjaap }
79123879Sjaap 
79223879Sjaap 
popf()79323879Sjaap popf()
79423879Sjaap {
79523879Sjaap 	register i;
79623879Sjaap 	register char	*p, *q;
79723879Sjaap 	extern char	*ttyname();
79823879Sjaap 
79923879Sjaap 	ioff = offl[--ifi];
80023901Sjaap 	numtab[CD].val = cfline[ifi];		/*restore line counter*/
80123879Sjaap 	ip = ipl[ifi];
80223879Sjaap 	if ((ifile = ifl[ifi]) == 0) {
80323879Sjaap 		p = xbuf;
80423879Sjaap 		q = ibuf;
80523879Sjaap 		ibufp = xbufp;
80623879Sjaap 		eibuf = xeibuf;
80723879Sjaap 		while (q < eibuf)
80823879Sjaap 			*q++ = *p++;
80923879Sjaap 		return(0);
81023879Sjaap 	}
81123901Sjaap 	if (lseek(ifile, (long)(ioff & ~(IBUFSZ-1)), 0) == (long) -1
81223901Sjaap 	   || (i = read(ifile, ibuf, IBUFSZ)) < 0)
81323879Sjaap 		return(1);
81423879Sjaap 	eibuf = ibuf + i;
81523879Sjaap 	ibufp = ibuf;
81623879Sjaap 	if (ttyname(ifile) == 0)
81723901Sjaap 		/* was >= ... */
81823901Sjaap 		if ((ibufp = ibuf + (int)(ioff & (IBUFSZ - 1))) > eibuf)
81923879Sjaap 			return(1);
82023879Sjaap 	return(0);
82123879Sjaap }
82223879Sjaap 
82323879Sjaap 
flushi()82423879Sjaap flushi()
82523879Sjaap {
82623879Sjaap 	if (nflush)
82723879Sjaap 		return;
82823879Sjaap 	ch = 0;
82923879Sjaap 	copyf++;
83023879Sjaap 	while (!nlflg) {
83123879Sjaap 		if (donef && (frame == stk))
83223879Sjaap 			break;
83323879Sjaap 		getch();
83423879Sjaap 	}
83523879Sjaap 	copyf--;
83623879Sjaap }
83723879Sjaap 
83823879Sjaap 
getach()83923879Sjaap getach()
84023879Sjaap {
84123901Sjaap 	register tchar i;
84223879Sjaap 	register j;
84323879Sjaap 
84423879Sjaap 	lgf++;
84523879Sjaap 	j = cbits(i = getch());
84623879Sjaap 	if (ismot(i) || j == ' ' || j == '\n' || j & 0200) {
84723879Sjaap 		ch = i;
84823879Sjaap 		j = 0;
84923879Sjaap 	}
85023879Sjaap 	lgf--;
85123879Sjaap 	return(j & 0177);
85223879Sjaap }
85323879Sjaap 
85423879Sjaap 
casenx()85523879Sjaap casenx()
85623879Sjaap {
85723879Sjaap 	lgf++;
85823879Sjaap 	skip();
85923879Sjaap 	getname();
86023879Sjaap 	nx++;
86123879Sjaap 	nextfile();
86223879Sjaap 	nlflg++;
86323879Sjaap 	ip = 0;
86423901Sjaap 	pendt = 0;
86523879Sjaap 	frame = stk;
86623879Sjaap 	nxf = frame + 1;
86723879Sjaap }
86823879Sjaap 
86923879Sjaap 
getname()87023879Sjaap getname()
87123879Sjaap {
87223879Sjaap 	register int	j, k;
87323879Sjaap 	tchar i;
87423879Sjaap 
87523879Sjaap 	lgf++;
87623879Sjaap 	for (k = 0; k < (NS - 1); k++) {
87723879Sjaap 		if (((j = cbits(i = getch())) <= ' ') || (j > 0176))
87823879Sjaap 			break;
87923879Sjaap 		nextf[k] = j;
88023879Sjaap 	}
88123879Sjaap 	nextf[k] = 0;
88223879Sjaap 	ch = i;
88323879Sjaap 	lgf--;
88423879Sjaap 	return(nextf[0]);
88523879Sjaap }
88623879Sjaap 
88723879Sjaap 
caseso()88823879Sjaap caseso()
88923879Sjaap {
89023879Sjaap 	register i;
89123879Sjaap 	register char	*p, *q;
89223879Sjaap 
89323879Sjaap 	lgf++;
89423879Sjaap 	nextf[0] = 0;
89523879Sjaap 	if (skip() || !getname() || ((i = open(nextf, 0)) < 0) || (ifi >= NSO)) {
89623901Sjaap 		errprint("can't open file %s", nextf);
89723879Sjaap 		done(02);
89823879Sjaap 	}
89923901Sjaap 	strcpy(cfname[ifi+1], nextf);
90023901Sjaap 	cfline[ifi] = numtab[CD].val;		/*hold line counter*/
90123901Sjaap 	numtab[CD].val = 0;
90223879Sjaap 	flushi();
90323879Sjaap 	ifl[ifi] = ifile;
90423879Sjaap 	ifile = i;
90523879Sjaap 	offl[ifi] = ioff;
90623879Sjaap 	ioff = 0;
90723879Sjaap 	ipl[ifi] = ip;
90823879Sjaap 	ip = 0;
90923879Sjaap 	nx++;
91023879Sjaap 	nflush++;
91123879Sjaap 	if (!ifl[ifi++]) {
91223879Sjaap 		p = ibuf;
91323879Sjaap 		q = xbuf;
91423879Sjaap 		xbufp = ibufp;
91523879Sjaap 		xeibuf = eibuf;
91623879Sjaap 		while (p < eibuf)
91723879Sjaap 			*q++ = *p++;
91823879Sjaap 	}
91923879Sjaap }
92023879Sjaap 
caself()92123901Sjaap caself()	/* set line number and file */
92223901Sjaap {
92323901Sjaap 	int n;
92423879Sjaap 
92523901Sjaap 	if (skip())
92623901Sjaap 		return;
92723901Sjaap 	n = atoi();
92823901Sjaap 	cfline[ifi] = numtab[CD].val = n - 2;
92923901Sjaap 	if (skip())
93023901Sjaap 		return;
93123901Sjaap 	if (getname())
93223901Sjaap 		strcpy(cfname[ifi], nextf);
93323901Sjaap }
93423901Sjaap 
93523901Sjaap 
casecf()93623879Sjaap casecf()
93723879Sjaap {	/* copy file without change */
93823879Sjaap #ifndef NROFF
93923879Sjaap 	int	fd, n;
940*64044Sbostic 	char	buf[8192];
94123901Sjaap 	extern int hpos, esc, po;
94223879Sjaap 	nextf[0] = 0;
94323879Sjaap 	if (skip() || !getname() || (fd = open(nextf, 0)) < 0) {
94423901Sjaap 		errprint("can't open file %s", nextf);
94523879Sjaap 		done(02);
94623879Sjaap 	}
94723879Sjaap 	tbreak();
94823879Sjaap 	/* make it into a clean state, be sure that everything is out */
94923879Sjaap 	hpos = po;
95023879Sjaap 	esc = un;
95123879Sjaap 	ptesc();
95223879Sjaap 	ptlead();
95323879Sjaap 	ptps();
95423879Sjaap 	ptfont();
95523879Sjaap 	flusho();
95623901Sjaap 	while ((n = read(fd, buf, sizeof buf)) > 0)
957*64044Sbostic 		write(fileno(ptid), buf, n);
95823879Sjaap 	close(fd);
95923879Sjaap #endif
96023879Sjaap }
96123879Sjaap 
96223879Sjaap 
casesy()96323901Sjaap casesy()	/* call system */
96423901Sjaap {
96523879Sjaap 	char	sybuf[NTM];
96623879Sjaap 	int	i;
96723879Sjaap 
96823879Sjaap 	lgf++;
96923879Sjaap 	copyf++;
97023879Sjaap 	skip();
97123879Sjaap 	for (i = 0; i < NTM - 2; i++)
97223879Sjaap 		if ((sybuf[i] = getch()) == '\n')
97323879Sjaap 			break;
97423879Sjaap 	sybuf[i] = 0;
97523879Sjaap 	system(sybuf);
97623879Sjaap 	copyf--;
97723901Sjaap 	lgf--;
97823879Sjaap }
97923879Sjaap 
98023879Sjaap 
getpn(a)98123879Sjaap getpn(a)
98223879Sjaap 	register char *a;
98323879Sjaap {
98423879Sjaap 	register int n, neg;
98523879Sjaap 
98623879Sjaap 	if (*a == 0)
98723879Sjaap 		return;
98823879Sjaap 	neg = 0;
98923879Sjaap 	for ( ; *a; a++)
99023879Sjaap 		switch (*a) {
99123879Sjaap 		case '+':
99223879Sjaap 		case ',':
99323879Sjaap 			continue;
99423879Sjaap 		case '-':
99523879Sjaap 			neg = 1;
99623879Sjaap 			continue;
99723879Sjaap 		default:
99823879Sjaap 			n = 0;
99923879Sjaap 			if (isdigit(*a)) {
100023879Sjaap 				do
100123879Sjaap 					n = 10 * n + *a++ - '0';
100223879Sjaap 				while (isdigit(*a));
100323879Sjaap 				a--;
100423879Sjaap 			} else
100523879Sjaap 				n = 9999;
100623879Sjaap 			*pnp++ = neg ? -n : n;
100723879Sjaap 			neg = 0;
100823879Sjaap 			if (pnp >= &pnlist[NPN-2]) {
100923901Sjaap 				errprint("too many page numbers");
101023879Sjaap 				done3(-3);
101123879Sjaap 			}
101223879Sjaap 		}
101323879Sjaap 	if (neg)
101423879Sjaap 		*pnp++ = -9999;
101523879Sjaap 	*pnp = -32767;
101623879Sjaap 	print = 0;
101723879Sjaap 	pnp = pnlist;
101823879Sjaap 	if (*pnp != -32767)
101923879Sjaap 		chkpn();
102023879Sjaap }
102123879Sjaap 
102223879Sjaap 
setrpt()102323879Sjaap setrpt()
102423879Sjaap {
102523879Sjaap 	tchar i, j;
102623879Sjaap 
102723879Sjaap 	copyf++;
102823879Sjaap 	raw++;
102923879Sjaap 	i = getch0();
103023879Sjaap 	copyf--;
103123879Sjaap 	raw--;
103223879Sjaap 	if (i < 0 || cbits(j = getch0()) == RPT)
103323879Sjaap 		return;
103423901Sjaap 	i &= BYTEMASK;
103523901Sjaap 	while (i>0 && pbp < &pbbuf[NC-3]) {
103623901Sjaap 		i--;
103723901Sjaap 		*pbp++ = j;
103823901Sjaap 	}
103923879Sjaap }
1040