xref: /plan9/sys/src/cmd/troff/n1.c (revision 14f51593fd82e19ba95969a8c07ff71131015979)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * n1.c
33e12c5d1SDavid du Colombier  *
43e12c5d1SDavid du Colombier  *	consume options, initialization, main loop,
53e12c5d1SDavid du Colombier  *	input routines, escape function calling
63e12c5d1SDavid du Colombier  */
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier #include "tdef.h"
93e12c5d1SDavid du Colombier #include "fns.h"
103e12c5d1SDavid du Colombier #include "ext.h"
11219b2ee8SDavid du Colombier #include "dwbinit.h"
123e12c5d1SDavid du Colombier 
133e12c5d1SDavid du Colombier #include <setjmp.h>
143e12c5d1SDavid du Colombier #include <time.h>
153e12c5d1SDavid du Colombier 
16219b2ee8SDavid du Colombier char	*Version	= "March 11, 1994";
17219b2ee8SDavid du Colombier 
18219b2ee8SDavid du Colombier #ifndef DWBVERSION
19219b2ee8SDavid du Colombier #define DWBVERSION      "???"
20219b2ee8SDavid du Colombier #endif
21219b2ee8SDavid du Colombier 
22219b2ee8SDavid du Colombier char	*DWBfontdir = FONTDIR;
23219b2ee8SDavid du Colombier char	*DWBntermdir = NTERMDIR;
24219b2ee8SDavid du Colombier char	*DWBalthyphens = ALTHYPHENS;
25219b2ee8SDavid du Colombier char	*DWBhomedir = "";
26219b2ee8SDavid du Colombier 
27219b2ee8SDavid du Colombier dwbinit dwbpaths[] = {
28219b2ee8SDavid du Colombier 	&DWBfontdir, NULL, 0,
29219b2ee8SDavid du Colombier 	&DWBntermdir, NULL, 0,
30219b2ee8SDavid du Colombier 	&DWBalthyphens, NULL, 0,
31219b2ee8SDavid du Colombier 	&DWBhomedir, NULL, 0,
32219b2ee8SDavid du Colombier 	NULL, nextf, NS,
33219b2ee8SDavid du Colombier 	NULL, NULL, 0
34219b2ee8SDavid du Colombier };
35219b2ee8SDavid du Colombier 
363e12c5d1SDavid du Colombier int	TROFF	= 1;	/* assume we started in troff... */
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier jmp_buf sjbuf;
393e12c5d1SDavid du Colombier Offset	ipl[NSO];
403e12c5d1SDavid du Colombier 
413e12c5d1SDavid du Colombier static	FILE	*ifile	= stdin;
423e12c5d1SDavid du Colombier static	FILE	*ifl[NSO];	/* open input file pointers */
433e12c5d1SDavid du Colombier char	cfname[NSO+1][NS] = {  "stdin" };	/* file name stack */
443e12c5d1SDavid du Colombier int	cfline[NSO];		/* input line count stack */
453e12c5d1SDavid du Colombier char	*progname;		/* program name (troff or nroff) */
463e12c5d1SDavid du Colombier 
47219b2ee8SDavid du Colombier int	trace = 0;	/* tracing mode: default off */
48219b2ee8SDavid du Colombier int	trace1 = 0;
493e12c5d1SDavid du Colombier 
main(int argc,char * argv[])503e12c5d1SDavid du Colombier main(int argc, char *argv[])
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier 	char *p;
533e12c5d1SDavid du Colombier 	int j;
543e12c5d1SDavid du Colombier 	Tchar i;
553e12c5d1SDavid du Colombier 	char buf[100];
563e12c5d1SDavid du Colombier 
57219b2ee8SDavid du Colombier 	buf[0] = '\0';		/* make sure it's empty (silly 3b2) */
583e12c5d1SDavid du Colombier 	progname = argv[0];
59219b2ee8SDavid du Colombier 	if ((p = strrchr(progname, '/')) == NULL)
60219b2ee8SDavid du Colombier 		p = progname;
61219b2ee8SDavid du Colombier 	else
62219b2ee8SDavid du Colombier 		p++;
63219b2ee8SDavid du Colombier 	DWBinit(progname, dwbpaths);
64219b2ee8SDavid du Colombier 	if (strcmp(p, "nroff") == 0)
653e12c5d1SDavid du Colombier 		TROFF = 0;
66219b2ee8SDavid du Colombier #ifdef UNICODE
673e12c5d1SDavid du Colombier 	alphabet = 128;	/* unicode for plan 9 */
68219b2ee8SDavid du Colombier #endif	/*UNICODE*/
69219b2ee8SDavid du Colombier 	mnspace();
70219b2ee8SDavid du Colombier 	nnspace();
713e12c5d1SDavid du Colombier 	mrehash();
723e12c5d1SDavid du Colombier 	nrehash();
73219b2ee8SDavid du Colombier 	numtabp[NL].val = -1;
743e12c5d1SDavid du Colombier 
753e12c5d1SDavid du Colombier 	while (--argc > 0 && (++argv)[0][0] == '-')
763e12c5d1SDavid du Colombier 		switch (argv[0][1]) {
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier 		case 'N':	/* ought to be used first... */
793e12c5d1SDavid du Colombier 			TROFF = 0;
803e12c5d1SDavid du Colombier 			break;
813e12c5d1SDavid du Colombier 		case 'd':
823e12c5d1SDavid du Colombier 			fprintf(stderr, "troff/nroff version %s\n", Version);
833e12c5d1SDavid du Colombier 			break;
843e12c5d1SDavid du Colombier 		case 'F':	/* switch font tables from default */
853e12c5d1SDavid du Colombier 			if (argv[0][2] != '\0') {
863e12c5d1SDavid du Colombier 				strcpy(termtab, &argv[0][2]);
873e12c5d1SDavid du Colombier 				strcpy(fontdir, &argv[0][2]);
883e12c5d1SDavid du Colombier 			} else {
893e12c5d1SDavid du Colombier 				argv++; argc--;
903e12c5d1SDavid du Colombier 				strcpy(termtab, argv[0]);
913e12c5d1SDavid du Colombier 				strcpy(fontdir, argv[0]);
923e12c5d1SDavid du Colombier 			}
933e12c5d1SDavid du Colombier 			break;
943e12c5d1SDavid du Colombier 		case 0:
953e12c5d1SDavid du Colombier 			goto start;
963e12c5d1SDavid du Colombier 		case 'i':
973e12c5d1SDavid du Colombier 			stdi++;
983e12c5d1SDavid du Colombier 			break;
993e12c5d1SDavid du Colombier 		case 'n':
1003e12c5d1SDavid du Colombier 			npn = atoi(&argv[0][2]);
1013e12c5d1SDavid du Colombier 			break;
1023e12c5d1SDavid du Colombier 		case 'u':	/* set emboldening amount */
1033e12c5d1SDavid du Colombier 			bdtab[3] = atoi(&argv[0][2]);
1043e12c5d1SDavid du Colombier 			if (bdtab[3] < 0 || bdtab[3] > 50)
1053e12c5d1SDavid du Colombier 				bdtab[3] = 0;
1063e12c5d1SDavid du Colombier 			break;
1073e12c5d1SDavid du Colombier 		case 's':
1083e12c5d1SDavid du Colombier 			if (!(stop = atoi(&argv[0][2])))
1093e12c5d1SDavid du Colombier 				stop++;
1103e12c5d1SDavid du Colombier 			break;
1113e12c5d1SDavid du Colombier 		case 'r':
1123e12c5d1SDavid du Colombier 			sprintf(buf + strlen(buf), ".nr %c %s\n",
1133e12c5d1SDavid du Colombier 				argv[0][2], &argv[0][3]);
114219b2ee8SDavid du Colombier 			/* not yet cpushback(buf);*/
1153e12c5d1SDavid du Colombier 			/* dotnr(&argv[0][2], &argv[0][3]); */
1163e12c5d1SDavid du Colombier 			break;
1173e12c5d1SDavid du Colombier 		case 'm':
1183e12c5d1SDavid du Colombier 			if (mflg++ >= NMF) {
1193e12c5d1SDavid du Colombier 				ERROR "Too many macro packages: %s", argv[0] WARN;
1203e12c5d1SDavid du Colombier 				break;
1213e12c5d1SDavid du Colombier 			}
1223e12c5d1SDavid du Colombier 			strcpy(mfiles[nmfi], nextf);
1233e12c5d1SDavid du Colombier 			strcat(mfiles[nmfi++], &argv[0][2]);
1243e12c5d1SDavid du Colombier 			break;
1253e12c5d1SDavid du Colombier 		case 'o':
1263e12c5d1SDavid du Colombier 			getpn(&argv[0][2]);
1273e12c5d1SDavid du Colombier 			break;
1283e12c5d1SDavid du Colombier 		case 'T':
1293e12c5d1SDavid du Colombier 			strcpy(devname, &argv[0][2]);
1303e12c5d1SDavid du Colombier 			dotT++;
1313e12c5d1SDavid du Colombier 			break;
1323e12c5d1SDavid du Colombier 		case 'a':
1333e12c5d1SDavid du Colombier 			ascii = 1;
1343e12c5d1SDavid du Colombier 			break;
1353e12c5d1SDavid du Colombier 		case 'h':
1363e12c5d1SDavid du Colombier 			hflg++;
1373e12c5d1SDavid du Colombier 			break;
1383e12c5d1SDavid du Colombier 		case 'e':
1393e12c5d1SDavid du Colombier 			eqflg++;
1403e12c5d1SDavid du Colombier 			break;
1413e12c5d1SDavid du Colombier 		case 'q':
1423e12c5d1SDavid du Colombier 			quiet++;
1433e12c5d1SDavid du Colombier 			save_tty();
1443e12c5d1SDavid du Colombier 			break;
145219b2ee8SDavid du Colombier 		case 'V':
146219b2ee8SDavid du Colombier 			fprintf(stdout, "%croff: DWB %s\n",
147219b2ee8SDavid du Colombier 					TROFF ? 't' : 'n', DWBVERSION);
148219b2ee8SDavid du Colombier 			exit(0);
149219b2ee8SDavid du Colombier 		case 't':
150219b2ee8SDavid du Colombier 			if (argv[0][2] != '\0')
151219b2ee8SDavid du Colombier 				trace = trace1 = argv[0][2];
152219b2ee8SDavid du Colombier 			break;		/* for the sake of compatibility */
1533e12c5d1SDavid du Colombier 		default:
1543e12c5d1SDavid du Colombier 			ERROR "unknown option %s", argv[0] WARN;
1553e12c5d1SDavid du Colombier 			done(02);
1563e12c5d1SDavid du Colombier 		}
1573e12c5d1SDavid du Colombier 
1583e12c5d1SDavid du Colombier start:
159219b2ee8SDavid du Colombier 	/*
160219b2ee8SDavid du Colombier 	 * cpushback maintains a LIFO, so push pack the -r arguments
161219b2ee8SDavid du Colombier 	 * in reverse order to maintain a FIFO in case someone did -rC1 -rC3
162219b2ee8SDavid du Colombier 	 */
163219b2ee8SDavid du Colombier 	if (buf[0]) {
164219b2ee8SDavid du Colombier 		char *p = buf;
165219b2ee8SDavid du Colombier 		while(*p++)
166219b2ee8SDavid du Colombier 			;
167219b2ee8SDavid du Colombier 		while(p > buf) {
168219b2ee8SDavid du Colombier 			while(strncmp(p, ".nr", 3) != 0)
169219b2ee8SDavid du Colombier 				p--;
170219b2ee8SDavid du Colombier 			cpushback(p);
171219b2ee8SDavid du Colombier 			*p-- = '\0';
172219b2ee8SDavid du Colombier 		}
173219b2ee8SDavid du Colombier 	}
1743e12c5d1SDavid du Colombier 	argp = argv;
1753e12c5d1SDavid du Colombier 	rargc = argc;
1763e12c5d1SDavid du Colombier 	nmfi = 0;
1773e12c5d1SDavid du Colombier 	init2();
1783e12c5d1SDavid du Colombier 	setjmp(sjbuf);
1793e12c5d1SDavid du Colombier loop:
1803e12c5d1SDavid du Colombier 	copyf = lgf = nb = nflush = nlflg = 0;
181219b2ee8SDavid du Colombier 	if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl && dip == d) {
1823e12c5d1SDavid du Colombier 		nflush++;
1833e12c5d1SDavid du Colombier 		trap = 0;
1843e12c5d1SDavid du Colombier 		eject((Stack *)0);
1853e12c5d1SDavid du Colombier 		goto loop;
1863e12c5d1SDavid du Colombier 	}
1873e12c5d1SDavid du Colombier 	i = getch();
1883e12c5d1SDavid du Colombier 	if (pendt)
1893e12c5d1SDavid du Colombier 		goto Lt;
1903e12c5d1SDavid du Colombier 	if ((j = cbits(i)) == XPAR) {
1913e12c5d1SDavid du Colombier 		copyf++;
1923e12c5d1SDavid du Colombier 		tflg++;
1933e12c5d1SDavid du Colombier 		while (cbits(i) != '\n')
1943e12c5d1SDavid du Colombier 			pchar(i = getch());
1953e12c5d1SDavid du Colombier 		tflg = 0;
196*14f51593SDavid du Colombier 		copyf--;			/* pointless */
1973e12c5d1SDavid du Colombier 		goto loop;
1983e12c5d1SDavid du Colombier 	}
1993e12c5d1SDavid du Colombier 	if (j == cc || j == c2) {
2003e12c5d1SDavid du Colombier 		if (j == c2)
2013e12c5d1SDavid du Colombier 			nb++;
2023e12c5d1SDavid du Colombier 		copyf++;
2033e12c5d1SDavid du Colombier 		while ((j = cbits(i = getch())) == ' ' || j == '\t')
2043e12c5d1SDavid du Colombier 			;
2053e12c5d1SDavid du Colombier 		ch = i;
2063e12c5d1SDavid du Colombier 		copyf--;
2073e12c5d1SDavid du Colombier 		control(getrq(), 1);
2083e12c5d1SDavid du Colombier 		flushi();
2093e12c5d1SDavid du Colombier 		goto loop;
2103e12c5d1SDavid du Colombier 	}
2113e12c5d1SDavid du Colombier Lt:
2123e12c5d1SDavid du Colombier 	ch = i;
2133e12c5d1SDavid du Colombier 	text();
2143e12c5d1SDavid du Colombier 	if (nlflg)
215219b2ee8SDavid du Colombier 		numtabp[HP].val = 0;
2163e12c5d1SDavid du Colombier 	goto loop;
2173e12c5d1SDavid du Colombier }
2183e12c5d1SDavid du Colombier 
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier 
init2(void)2213e12c5d1SDavid du Colombier void init2(void)
2223e12c5d1SDavid du Colombier {
2233e12c5d1SDavid du Colombier 	int i;
2243e12c5d1SDavid du Colombier 	char buf[100];
2253e12c5d1SDavid du Colombier 
2263e12c5d1SDavid du Colombier 	for (i = NTRTAB; --i; )
2273e12c5d1SDavid du Colombier 		trtab[i] = i;
2283e12c5d1SDavid du Colombier 	trtab[UNPAD] = ' ';
2293e12c5d1SDavid du Colombier 	iflg = 0;
2303e12c5d1SDavid du Colombier 	obufp = obuf;
2313e12c5d1SDavid du Colombier 	if (TROFF)
2323e12c5d1SDavid du Colombier 		t_ptinit();
2333e12c5d1SDavid du Colombier 	else
2343e12c5d1SDavid du Colombier 		n_ptinit();
2353e12c5d1SDavid du Colombier 	mchbits();
2363e12c5d1SDavid du Colombier 	cvtime();
237219b2ee8SDavid du Colombier 	numtabp[PID].val = getpid();
238219b2ee8SDavid du Colombier 	numtabp[HP].val = init = 0;
239219b2ee8SDavid du Colombier 	numtabp[NL].val = -1;
2403e12c5d1SDavid du Colombier 	nfo = 0;
2413e12c5d1SDavid du Colombier 	copyf = raw = 0;
2423e12c5d1SDavid du Colombier 	sprintf(buf, ".ds .T %s\n", devname);
2433e12c5d1SDavid du Colombier 	cpushback(buf);
244219b2ee8SDavid du Colombier 	sprintf(buf, ".ds .P %s\n", DWBhomedir);
245219b2ee8SDavid du Colombier 	cpushback(buf);
246219b2ee8SDavid du Colombier 	numtabp[CD].val = -1;	/* compensation */
2473e12c5d1SDavid du Colombier 	nx = mflg;
2483e12c5d1SDavid du Colombier 	frame = stk = (Stack *)setbrk(STACKSIZE);
2493e12c5d1SDavid du Colombier 	dip = &d[0];
2503e12c5d1SDavid du Colombier 	nxf = frame + 1;
2513e12c5d1SDavid du Colombier 	for (i = 1; i < NEV; i++)	/* propagate the environment */
2523e12c5d1SDavid du Colombier 		envcopy(&env[i], &env[0]);
253219b2ee8SDavid du Colombier 	for (i = 0; i < NEV; i++) {
254219b2ee8SDavid du Colombier 		if ((env[i]._word._bufp = (Tchar *)calloc(WDSIZE, sizeof(Tchar))) == NULL) {
255219b2ee8SDavid du Colombier 			ERROR "not enough room for word buffers" WARN;
256219b2ee8SDavid du Colombier 			done2(1);
257219b2ee8SDavid du Colombier 		}
258219b2ee8SDavid du Colombier 		env[i]._word._size = WDSIZE;
259219b2ee8SDavid du Colombier 		if ((env[i]._line._bufp = (Tchar *)calloc(LNSIZE, sizeof(Tchar))) == NULL) {
260219b2ee8SDavid du Colombier 			ERROR "not enough room for line buffers" WARN;
261219b2ee8SDavid du Colombier 			done2(1);
262219b2ee8SDavid du Colombier 		}
263219b2ee8SDavid du Colombier 		env[i]._line._size = LNSIZE;
264219b2ee8SDavid du Colombier 	}
265219b2ee8SDavid du Colombier 	if ((oline = (Tchar *)calloc(OLNSIZE, sizeof(Tchar))) == NULL) {
266219b2ee8SDavid du Colombier 		ERROR "not enough room for line buffers" WARN;
267219b2ee8SDavid du Colombier 		done2(1);
268219b2ee8SDavid du Colombier 	}
269219b2ee8SDavid du Colombier 	olinep = oline;
270219b2ee8SDavid du Colombier 	olnsize = OLNSIZE;
2713e12c5d1SDavid du Colombier 	blockinit();
2723e12c5d1SDavid du Colombier }
2733e12c5d1SDavid du Colombier 
cvtime(void)2743e12c5d1SDavid du Colombier void cvtime(void)
2753e12c5d1SDavid du Colombier {
2763e12c5d1SDavid du Colombier 	long tt;
2773e12c5d1SDavid du Colombier 	struct tm *ltime;
2783e12c5d1SDavid du Colombier 
2793e12c5d1SDavid du Colombier 	time(&tt);
2803e12c5d1SDavid du Colombier 	ltime = localtime(&tt);
2817dd7cddfSDavid du Colombier 	numtabp[YR].val = ltime->tm_year % 100;
2827dd7cddfSDavid du Colombier 	numtabp[YR].fmt = 2;
283219b2ee8SDavid du Colombier 	numtabp[MO].val = ltime->tm_mon + 1;	/* troff uses 1..12 */
284219b2ee8SDavid du Colombier 	numtabp[DY].val = ltime->tm_mday;
285219b2ee8SDavid du Colombier 	numtabp[DW].val = ltime->tm_wday + 1;	/* troff uses 1..7 */
2863e12c5d1SDavid du Colombier }
2873e12c5d1SDavid du Colombier 
2883e12c5d1SDavid du Colombier 
2893e12c5d1SDavid du Colombier 
2903e12c5d1SDavid du Colombier char	errbuf[200];
2913e12c5d1SDavid du Colombier 
errprint(void)2923e12c5d1SDavid du Colombier void errprint(void)	/* error message printer */
2933e12c5d1SDavid du Colombier {
294219b2ee8SDavid du Colombier 	int savecd = numtabp[CD].val;
295219b2ee8SDavid du Colombier 
296219b2ee8SDavid du Colombier 	if (!nlflg)
297219b2ee8SDavid du Colombier 		numtabp[CD].val++;
298219b2ee8SDavid du Colombier 
2993e12c5d1SDavid du Colombier 	fprintf(stderr, "%s: ", progname);
3003e12c5d1SDavid du Colombier 	fputs(errbuf, stderr);
301219b2ee8SDavid du Colombier 	if (cfname[ifi][0])
3027dd7cddfSDavid du Colombier 		fprintf(stderr, "; %s:%d", cfname[ifi], numtabp[CD].val);
3033e12c5d1SDavid du Colombier 	fputs("\n", stderr);
304219b2ee8SDavid du Colombier 	if (cfname[ifi][0])
3053e12c5d1SDavid du Colombier 		stackdump();
306219b2ee8SDavid du Colombier 	numtabp[CD].val = savecd;
3073e12c5d1SDavid du Colombier }
3083e12c5d1SDavid du Colombier 
3093e12c5d1SDavid du Colombier 
control(int a,int b)3103e12c5d1SDavid du Colombier int control(int a, int b)
3113e12c5d1SDavid du Colombier {
312219b2ee8SDavid du Colombier 	int j, k;
313219b2ee8SDavid du Colombier 	extern Contab *contabp;
3143e12c5d1SDavid du Colombier 
315219b2ee8SDavid du Colombier 	numerr.type = RQERR;
316219b2ee8SDavid du Colombier 	numerr.req = a;
3173e12c5d1SDavid du Colombier 	if (a == 0 || (j = findmn(a)) == -1)
3183e12c5d1SDavid du Colombier 		return(0);
319219b2ee8SDavid du Colombier 	if (contabp[j].f == 0) {
320219b2ee8SDavid du Colombier 		if (trace & TRMAC)
321219b2ee8SDavid du Colombier 			fprintf(stderr, "invoke macro %s\n", unpair(a));
322219b2ee8SDavid du Colombier 		if (dip != d)
323219b2ee8SDavid du Colombier 			for (k = dilev; k; k--)
324219b2ee8SDavid du Colombier 				if (d[k].curd == a) {
325219b2ee8SDavid du Colombier 					ERROR "diversion %s invokes itself during diversion",
326219b2ee8SDavid du Colombier 								unpair(a) WARN;
327219b2ee8SDavid du Colombier 					edone(0100);
328219b2ee8SDavid du Colombier 				}
3293e12c5d1SDavid du Colombier 		nxf->nargs = 0;
3303e12c5d1SDavid du Colombier 		if (b)
3313e12c5d1SDavid du Colombier 			collect();
3323e12c5d1SDavid du Colombier 		flushi();
333219b2ee8SDavid du Colombier 		return pushi(contabp[j].mx, a);	/* BUG??? all that matters is 0/!0 */
3343e12c5d1SDavid du Colombier 	}
335219b2ee8SDavid du Colombier 	if (b) {
336219b2ee8SDavid du Colombier 		if (trace & TRREQ)
337219b2ee8SDavid du Colombier 			fprintf(stderr, "invoke request %s\n", unpair(a));
338219b2ee8SDavid du Colombier 		 (*contabp[j].f)();
339219b2ee8SDavid du Colombier 	}
3403e12c5d1SDavid du Colombier 	return(0);
3413e12c5d1SDavid du Colombier }
3423e12c5d1SDavid du Colombier 
casept(void)343219b2ee8SDavid du Colombier void casept(void)
344219b2ee8SDavid du Colombier {
345219b2ee8SDavid du Colombier 	int i;
346219b2ee8SDavid du Colombier 
347219b2ee8SDavid du Colombier 	noscale++;
348219b2ee8SDavid du Colombier 	if (skip())
349219b2ee8SDavid du Colombier 		i = trace1;
350219b2ee8SDavid du Colombier 	else {
351219b2ee8SDavid du Colombier 		i = max(inumb(&trace), 0);
352219b2ee8SDavid du Colombier 		if (nonumb)
353219b2ee8SDavid du Colombier 			i = trace1;
354219b2ee8SDavid du Colombier 	}
355219b2ee8SDavid du Colombier 	trace1 = trace;
356219b2ee8SDavid du Colombier 	trace = i;
357219b2ee8SDavid du Colombier 	noscale = 0;
358219b2ee8SDavid du Colombier }
359219b2ee8SDavid du Colombier 
3603e12c5d1SDavid du Colombier 
getrq(void)3613e12c5d1SDavid du Colombier int getrq(void)
3623e12c5d1SDavid du Colombier {
3633e12c5d1SDavid du Colombier 	int i, j;
3643e12c5d1SDavid du Colombier 
3653e12c5d1SDavid du Colombier 	if ((i = getach()) == 0 || (j = getach()) == 0)
3663e12c5d1SDavid du Colombier 		goto rtn;
3673e12c5d1SDavid du Colombier 	i = PAIR(i, j);
3683e12c5d1SDavid du Colombier rtn:
3693e12c5d1SDavid du Colombier 	return(i);
3703e12c5d1SDavid du Colombier }
3713e12c5d1SDavid du Colombier 
3723e12c5d1SDavid du Colombier /*
3733e12c5d1SDavid du Colombier  * table encodes some special characters, to speed up tests
3743e12c5d1SDavid du Colombier  * in getch, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
3753e12c5d1SDavid du Colombier  */
3763e12c5d1SDavid du Colombier 
3773e12c5d1SDavid du Colombier char gchtab[NCHARS] = {
3783e12c5d1SDavid du Colombier 	000,004,000,000,010,000,000,000, /* fc, ldr */
3793e12c5d1SDavid du Colombier 	001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
3803e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3813e12c5d1SDavid du Colombier 	000,001,000,001,000,000,000,000, /* FLSS, ESC */
3823e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3833e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3843e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3853e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3863e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3873e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3883e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3893e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3903e12c5d1SDavid du Colombier 	000,000,000,000,000,000,001,000, /* f */
3913e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3923e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3933e12c5d1SDavid du Colombier 	000,000,000,000,000,000,000,000,
3943e12c5d1SDavid du Colombier };
3953e12c5d1SDavid du Colombier 
realcbits(Tchar c)3963e12c5d1SDavid du Colombier int realcbits(Tchar c)	/* return character bits, or MOTCH if motion */
3973e12c5d1SDavid du Colombier {
3983e12c5d1SDavid du Colombier 	if (ismot(c))
3993e12c5d1SDavid du Colombier 		return MOTCH;
4003e12c5d1SDavid du Colombier 	else
4013e12c5d1SDavid du Colombier 		return c & 0xFFFF;
4023e12c5d1SDavid du Colombier }
4033e12c5d1SDavid du Colombier 
getch(void)4043e12c5d1SDavid du Colombier Tchar getch(void)
4053e12c5d1SDavid du Colombier {
4063e12c5d1SDavid du Colombier 	int k;
4073e12c5d1SDavid du Colombier 	Tchar i, j;
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier g0:
4103e12c5d1SDavid du Colombier 	if (ch) {
4113e12c5d1SDavid du Colombier 		i = ch;
4123e12c5d1SDavid du Colombier 		if (cbits(i) == '\n')
4133e12c5d1SDavid du Colombier 			nlflg++;
4143e12c5d1SDavid du Colombier 		ch = 0;
4153e12c5d1SDavid du Colombier 		return(i);
4163e12c5d1SDavid du Colombier 	}
4173e12c5d1SDavid du Colombier 
4183e12c5d1SDavid du Colombier 	if (nlflg)
4193e12c5d1SDavid du Colombier 		return('\n');
4203e12c5d1SDavid du Colombier 	i = getch0();
4213e12c5d1SDavid du Colombier 	if (ismot(i))
4223e12c5d1SDavid du Colombier 		return(i);
4233e12c5d1SDavid du Colombier 	k = cbits(i);
4243e12c5d1SDavid du Colombier 	if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0)	/* nothing special */
4253e12c5d1SDavid du Colombier 		return(i);
4263e12c5d1SDavid du Colombier 	if (k != ESC) {
4273e12c5d1SDavid du Colombier 		if (k == '\n') {
4283e12c5d1SDavid du Colombier 			nlflg++;
4293e12c5d1SDavid du Colombier 			if (ip == 0)
430219b2ee8SDavid du Colombier 				numtabp[CD].val++; /* line number */
4313e12c5d1SDavid du Colombier 			return(k);
4323e12c5d1SDavid du Colombier 		}
4333e12c5d1SDavid du Colombier 		if (k == FLSS) {
4343e12c5d1SDavid du Colombier 			copyf++;
4353e12c5d1SDavid du Colombier 			raw++;
4363e12c5d1SDavid du Colombier 			i = getch0();
4373e12c5d1SDavid du Colombier 			if (!fi)
4383e12c5d1SDavid du Colombier 				flss = i;
4393e12c5d1SDavid du Colombier 			copyf--;
4403e12c5d1SDavid du Colombier 			raw--;
4413e12c5d1SDavid du Colombier 			goto g0;
4423e12c5d1SDavid du Colombier 		}
4433e12c5d1SDavid du Colombier 		if (k == RPT) {
4443e12c5d1SDavid du Colombier 			setrpt();
4453e12c5d1SDavid du Colombier 			goto g0;
4463e12c5d1SDavid du Colombier 		}
4473e12c5d1SDavid du Colombier 		if (!copyf) {
4483e12c5d1SDavid du Colombier 			if (k == 'f' && lg && !lgf) {
4493e12c5d1SDavid du Colombier 				i = getlg(i);
4503e12c5d1SDavid du Colombier 				return(i);
4513e12c5d1SDavid du Colombier 			}
4523e12c5d1SDavid du Colombier 			if (k == fc || k == tabch || k == ldrch) {
4533e12c5d1SDavid du Colombier 				if ((i = setfield(k)) == 0)
4543e12c5d1SDavid du Colombier 					goto g0;
4553e12c5d1SDavid du Colombier 				else
4563e12c5d1SDavid du Colombier 					return(i);
4573e12c5d1SDavid du Colombier 			}
4583e12c5d1SDavid du Colombier 			if (k == '\b') {
4593e12c5d1SDavid du Colombier 				i = makem(-width(' ' | chbits));
4603e12c5d1SDavid du Colombier 				return(i);
4613e12c5d1SDavid du Colombier 			}
4623e12c5d1SDavid du Colombier 		}
4633e12c5d1SDavid du Colombier 		return(i);
4643e12c5d1SDavid du Colombier 	}
4653e12c5d1SDavid du Colombier 
4663e12c5d1SDavid du Colombier 	k = cbits(j = getch0());
4673e12c5d1SDavid du Colombier 	if (ismot(j))
4683e12c5d1SDavid du Colombier 		return(j);
4693e12c5d1SDavid du Colombier 
4703e12c5d1SDavid du Colombier 	switch (k) {
4713e12c5d1SDavid du Colombier 	case 'n':	/* number register */
4723e12c5d1SDavid du Colombier 		setn();
4733e12c5d1SDavid du Colombier 		goto g0;
4743e12c5d1SDavid du Colombier 	case '$':	/* argument indicator */
4753e12c5d1SDavid du Colombier 		seta();
4763e12c5d1SDavid du Colombier 		goto g0;
4773e12c5d1SDavid du Colombier 	case '*':	/* string indicator */
4783e12c5d1SDavid du Colombier 		setstr();
4793e12c5d1SDavid du Colombier 		goto g0;
4803e12c5d1SDavid du Colombier 	case '{':	/* LEFT */
4813e12c5d1SDavid du Colombier 		i = LEFT;
4823e12c5d1SDavid du Colombier 		goto gx;
4833e12c5d1SDavid du Colombier 	case '}':	/* RIGHT */
4843e12c5d1SDavid du Colombier 		i = RIGHT;
4853e12c5d1SDavid du Colombier 		goto gx;
4863e12c5d1SDavid du Colombier 	case '"':	/* comment */
4873e12c5d1SDavid du Colombier 		while (cbits(i = getch0()) != '\n')
4883e12c5d1SDavid du Colombier 			;
4893e12c5d1SDavid du Colombier 		if (ip == 0)
490219b2ee8SDavid du Colombier 			numtabp[CD].val++; /* line number */
491219b2ee8SDavid du Colombier 		nlflg++;
4923e12c5d1SDavid du Colombier 		return(i);
4933e12c5d1SDavid du Colombier 
4943e12c5d1SDavid du Colombier /* experiment: put it here instead of copy mode */
4953e12c5d1SDavid du Colombier 	case '(':	/* special char name \(xx */
4963e12c5d1SDavid du Colombier 	case 'C':	/* 		\C'...' */
4973e12c5d1SDavid du Colombier 		if ((i = setch(k)) == 0)
4983e12c5d1SDavid du Colombier 			goto g0;
4993e12c5d1SDavid du Colombier 		goto gx;
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier 	case ESC:	/* double backslash */
5023e12c5d1SDavid du Colombier 		i = eschar;
5033e12c5d1SDavid du Colombier 		goto gx;
5043e12c5d1SDavid du Colombier 	case 'e':	/* printable version of current eschar */
5053e12c5d1SDavid du Colombier 		i = PRESC;
5063e12c5d1SDavid du Colombier 		goto gx;
5073e12c5d1SDavid du Colombier 	case '\n':	/* concealed newline */
508219b2ee8SDavid du Colombier 		numtabp[CD].val++;
5093e12c5d1SDavid du Colombier 		goto g0;
5103e12c5d1SDavid du Colombier 	case ' ':	/* unpaddable space */
5113e12c5d1SDavid du Colombier 		i = UNPAD;
5123e12c5d1SDavid du Colombier 		goto gx;
5133e12c5d1SDavid du Colombier 	case '\'':	/* \(aa */
5143e12c5d1SDavid du Colombier 		i = ACUTE;
5153e12c5d1SDavid du Colombier 		goto gx;
5163e12c5d1SDavid du Colombier 	case '`':	/* \(ga */
5173e12c5d1SDavid du Colombier 		i = GRAVE;
5183e12c5d1SDavid du Colombier 		goto gx;
5193e12c5d1SDavid du Colombier 	case '_':	/* \(ul */
5203e12c5d1SDavid du Colombier 		i = UNDERLINE;
5213e12c5d1SDavid du Colombier 		goto gx;
5223e12c5d1SDavid du Colombier 	case '-':	/* current font minus */
5233e12c5d1SDavid du Colombier 		i = MINUS;
5243e12c5d1SDavid du Colombier 		goto gx;
5253e12c5d1SDavid du Colombier 	case '&':	/* filler */
5263e12c5d1SDavid du Colombier 		i = FILLER;
5273e12c5d1SDavid du Colombier 		goto gx;
5283e12c5d1SDavid du Colombier 	case 'c':	/* to be continued */
5293e12c5d1SDavid du Colombier 		i = CONT;
5303e12c5d1SDavid du Colombier 		goto gx;
5313e12c5d1SDavid du Colombier 	case '!':	/* transparent indicator */
5323e12c5d1SDavid du Colombier 		i = XPAR;
5333e12c5d1SDavid du Colombier 		goto gx;
5343e12c5d1SDavid du Colombier 	case 't':	/* tab */
5353e12c5d1SDavid du Colombier 		i = '\t';
5363e12c5d1SDavid du Colombier 		return(i);
5373e12c5d1SDavid du Colombier 	case 'a':	/* leader (SOH) */
5383e12c5d1SDavid du Colombier /* old:		*pbp++ = LEADER; goto g0; */
5393e12c5d1SDavid du Colombier 		i = LEADER;
5403e12c5d1SDavid du Colombier 		return i;
5413e12c5d1SDavid du Colombier 	case '%':	/* ohc */
5423e12c5d1SDavid du Colombier 		i = OHC;
5433e12c5d1SDavid du Colombier 		return(i);
5443e12c5d1SDavid du Colombier 	case 'g':	/* return format of a number register */
5453e12c5d1SDavid du Colombier 		setaf();	/* should this really be in copy mode??? */
5463e12c5d1SDavid du Colombier 		goto g0;
5473e12c5d1SDavid du Colombier 	case '.':	/* . */
5483e12c5d1SDavid du Colombier 		i = '.';
5493e12c5d1SDavid du Colombier gx:
5503e12c5d1SDavid du Colombier 		setsfbits(i, sfbits(j));
5513e12c5d1SDavid du Colombier 		return(i);
5523e12c5d1SDavid du Colombier 	}
5533e12c5d1SDavid du Colombier 	if (copyf) {
5543e12c5d1SDavid du Colombier 		*pbp++ = j;
5553e12c5d1SDavid du Colombier 		return(eschar);
5563e12c5d1SDavid du Colombier 	}
5573e12c5d1SDavid du Colombier 	switch (k) {
5583e12c5d1SDavid du Colombier 
5593e12c5d1SDavid du Colombier 	case 'f':	/* font indicator */
5603e12c5d1SDavid du Colombier 		setfont(0);
5613e12c5d1SDavid du Colombier 		goto g0;
5623e12c5d1SDavid du Colombier 	case 's':	/* size indicator */
5633e12c5d1SDavid du Colombier 		setps();
5643e12c5d1SDavid du Colombier 		goto g0;
5653e12c5d1SDavid du Colombier 	case 'v':	/* vert mot */
566219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
5673e12c5d1SDavid du Colombier 		if (i = vmot()) {
5683e12c5d1SDavid du Colombier 			return(i);
5693e12c5d1SDavid du Colombier 		}
5703e12c5d1SDavid du Colombier 		goto g0;
5713e12c5d1SDavid du Colombier 	case 'h': 	/* horiz mot */
572219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
5733e12c5d1SDavid du Colombier 		if (i = hmot())
5743e12c5d1SDavid du Colombier 			return(i);
5753e12c5d1SDavid du Colombier 		goto g0;
5763e12c5d1SDavid du Colombier 	case '|':	/* narrow space */
5773e12c5d1SDavid du Colombier 		if (NROFF)
5783e12c5d1SDavid du Colombier 			goto g0;
5793e12c5d1SDavid du Colombier 		return(makem((int)(EM)/6));
5803e12c5d1SDavid du Colombier 	case '^':	/* half narrow space */
5813e12c5d1SDavid du Colombier 		if (NROFF)
5823e12c5d1SDavid du Colombier 			goto g0;
5833e12c5d1SDavid du Colombier 		return(makem((int)(EM)/12));
5843e12c5d1SDavid du Colombier 	case 'w':	/* width function */
5853e12c5d1SDavid du Colombier 		setwd();
5863e12c5d1SDavid du Colombier 		goto g0;
5873e12c5d1SDavid du Colombier 	case 'p':	/* spread */
5883e12c5d1SDavid du Colombier 		spread++;
5893e12c5d1SDavid du Colombier 		goto g0;
5903e12c5d1SDavid du Colombier 	case 'N':	/* absolute character number */
591219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
5923e12c5d1SDavid du Colombier 		if ((i = setabs()) == 0)
5933e12c5d1SDavid du Colombier 			goto g0;
5943e12c5d1SDavid du Colombier 		return i;
5953e12c5d1SDavid du Colombier 	case 'H':	/* character height */
596219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
5973e12c5d1SDavid du Colombier 		return(setht());
5983e12c5d1SDavid du Colombier 	case 'S':	/* slant */
599219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
6003e12c5d1SDavid du Colombier 		return(setslant());
6013e12c5d1SDavid du Colombier 	case 'z':	/* zero with char */
6023e12c5d1SDavid du Colombier 		return(setz());
6033e12c5d1SDavid du Colombier 	case 'l':	/* hor line */
604219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
6053e12c5d1SDavid du Colombier 		setline();
6063e12c5d1SDavid du Colombier 		goto g0;
6073e12c5d1SDavid du Colombier 	case 'L':	/* vert line */
608219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
6093e12c5d1SDavid du Colombier 		setvline();
6103e12c5d1SDavid du Colombier 		goto g0;
6113e12c5d1SDavid du Colombier 	case 'D':	/* drawing function */
612219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
6133e12c5d1SDavid du Colombier 		setdraw();
6143e12c5d1SDavid du Colombier 		goto g0;
6153e12c5d1SDavid du Colombier 	case 'X':	/* \X'...' for copy through */
6163e12c5d1SDavid du Colombier 		setxon();
6173e12c5d1SDavid du Colombier 		goto g0;
6183e12c5d1SDavid du Colombier 	case 'b':	/* bracket */
6193e12c5d1SDavid du Colombier 		setbra();
6203e12c5d1SDavid du Colombier 		goto g0;
6213e12c5d1SDavid du Colombier 	case 'o':	/* overstrike */
6223e12c5d1SDavid du Colombier 		setov();
6233e12c5d1SDavid du Colombier 		goto g0;
6243e12c5d1SDavid du Colombier 	case 'k':	/* mark hor place */
6253e12c5d1SDavid du Colombier 		if ((k = findr(getsn())) != -1) {
626219b2ee8SDavid du Colombier 			numtabp[k].val = numtabp[HP].val;
6273e12c5d1SDavid du Colombier 		}
6283e12c5d1SDavid du Colombier 		goto g0;
6293e12c5d1SDavid du Colombier 	case '0':	/* number space */
6303e12c5d1SDavid du Colombier 		return(makem(width('0' | chbits)));
6313e12c5d1SDavid du Colombier 	case 'x':	/* extra line space */
632219b2ee8SDavid du Colombier 		numerr.type = numerr.escarg = 0; numerr.esc = k;
6333e12c5d1SDavid du Colombier 		if (i = xlss())
6343e12c5d1SDavid du Colombier 			return(i);
6353e12c5d1SDavid du Colombier 		goto g0;
6363e12c5d1SDavid du Colombier 	case 'u':	/* half em up */
6373e12c5d1SDavid du Colombier 	case 'r':	/* full em up */
6383e12c5d1SDavid du Colombier 	case 'd':	/* half em down */
6393e12c5d1SDavid du Colombier 		return(sethl(k));
6403e12c5d1SDavid du Colombier 	default:
6413e12c5d1SDavid du Colombier 		return(j);
6423e12c5d1SDavid du Colombier 	}
6433e12c5d1SDavid du Colombier 	/* NOTREACHED */
6443e12c5d1SDavid du Colombier }
6453e12c5d1SDavid du Colombier 
setxon(void)6463e12c5d1SDavid du Colombier void setxon(void)	/* \X'...' for copy through */
6473e12c5d1SDavid du Colombier {
6483e12c5d1SDavid du Colombier 	Tchar xbuf[NC];
6493e12c5d1SDavid du Colombier 	Tchar *i;
6503e12c5d1SDavid du Colombier 	Tchar c;
6513e12c5d1SDavid du Colombier 	int delim, k;
6523e12c5d1SDavid du Colombier 
6533e12c5d1SDavid du Colombier 	if (ismot(c = getch()))
6543e12c5d1SDavid du Colombier 		return;
6553e12c5d1SDavid du Colombier 	delim = cbits(c);
6563e12c5d1SDavid du Colombier 	i = xbuf;
6573e12c5d1SDavid du Colombier 	*i++ = XON | chbits;
6583e12c5d1SDavid du Colombier 	while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
6593e12c5d1SDavid du Colombier 		if (k == ' ')
6603e12c5d1SDavid du Colombier 			setcbits(c, WORDSP);
6613e12c5d1SDavid du Colombier 		*i++ = c | ZBIT;
6623e12c5d1SDavid du Colombier 	}
6633e12c5d1SDavid du Colombier 	*i++ = XOFF | chbits;
6643e12c5d1SDavid du Colombier 	*i = 0;
6653e12c5d1SDavid du Colombier 	pushback(xbuf);
6663e12c5d1SDavid du Colombier }
6673e12c5d1SDavid du Colombier 
6683e12c5d1SDavid du Colombier 
6693e12c5d1SDavid du Colombier char	ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012 };
6703e12c5d1SDavid du Colombier 
getch0(void)6713e12c5d1SDavid du Colombier Tchar getch0(void)
6723e12c5d1SDavid du Colombier {
6733e12c5d1SDavid du Colombier 	Tchar i;
6743e12c5d1SDavid du Colombier 
6753e12c5d1SDavid du Colombier again:
6763e12c5d1SDavid du Colombier 	if (pbp > lastpbp)
6773e12c5d1SDavid du Colombier 		i = *--pbp;
6783e12c5d1SDavid du Colombier 	else if (ip) {
6793e12c5d1SDavid du Colombier 		/* i = rbf(); */
6803e12c5d1SDavid du Colombier 		i = rbf0(ip);
6813e12c5d1SDavid du Colombier 		if (i == 0)
6823e12c5d1SDavid du Colombier 			i = rbf();
6833e12c5d1SDavid du Colombier 		else {
6843e12c5d1SDavid du Colombier 			++ip;
6853e12c5d1SDavid du Colombier 			if (pastend(ip)) {
6863e12c5d1SDavid du Colombier 				--ip;
6873e12c5d1SDavid du Colombier 				rbf();
6883e12c5d1SDavid du Colombier 			}
6893e12c5d1SDavid du Colombier 		}
6903e12c5d1SDavid du Colombier 	} else {
6913e12c5d1SDavid du Colombier 		if (donef || ndone)
6923e12c5d1SDavid du Colombier 			done(0);
6933e12c5d1SDavid du Colombier 		if (nx || 1) {	/* BUG: was ibufp >= eibuf, so EOF test is wrong */
694219b2ee8SDavid du Colombier 			if (nfo < 0)
695219b2ee8SDavid du Colombier 				ERROR "in getch0, nfo = %d", nfo WARN;
6963e12c5d1SDavid du Colombier 			if (nfo == 0) {
6973e12c5d1SDavid du Colombier g0:
6983e12c5d1SDavid du Colombier 				if (nextfile()) {
6993e12c5d1SDavid du Colombier 					if (ip)
7003e12c5d1SDavid du Colombier 						goto again;
7013e12c5d1SDavid du Colombier 				}
7023e12c5d1SDavid du Colombier 			}
7033e12c5d1SDavid du Colombier 			nx = 0;
704219b2ee8SDavid du Colombier #ifdef UNICODE
705219b2ee8SDavid du Colombier 			if (MB_CUR_MAX > 1)
706219b2ee8SDavid du Colombier 				i = get1ch(ifile);
707219b2ee8SDavid du Colombier 			else
708219b2ee8SDavid du Colombier #endif	/*UNICODE*/
709219b2ee8SDavid du Colombier 				i = getc(ifile);
710219b2ee8SDavid du Colombier 			if (i == EOF)
7113e12c5d1SDavid du Colombier 				goto g0;
7123e12c5d1SDavid du Colombier 			if (ip)
7133e12c5d1SDavid du Colombier 				goto again;
7143e12c5d1SDavid du Colombier 		}
715219b2ee8SDavid du Colombier 		if (i >= 040)			/* zapped: && i < 0177 */
7163e12c5d1SDavid du Colombier 			goto g4;
7173e12c5d1SDavid du Colombier 		i = ifilt[i];
7183e12c5d1SDavid du Colombier 	}
7193e12c5d1SDavid du Colombier 	if (cbits(i) == IMP && !raw)
7203e12c5d1SDavid du Colombier 		goto again;
721219b2ee8SDavid du Colombier 	if (i == 0 && !init && !raw) {		/* zapped:  || i == 0177 */
7223e12c5d1SDavid du Colombier 		goto again;
7233e12c5d1SDavid du Colombier 	}
7243e12c5d1SDavid du Colombier g4:
7253e12c5d1SDavid du Colombier 	if (ismot(i))
7263e12c5d1SDavid du Colombier 		return i;
7273e12c5d1SDavid du Colombier 	if (copyf == 0 && sfbits(i) == 0)
7283e12c5d1SDavid du Colombier 		i |= chbits;
7293e12c5d1SDavid du Colombier 	if (cbits(i) == eschar && !raw)
7303e12c5d1SDavid du Colombier 		setcbits(i, ESC);
7313e12c5d1SDavid du Colombier 	return(i);
7323e12c5d1SDavid du Colombier }
7333e12c5d1SDavid du Colombier 
734219b2ee8SDavid du Colombier 
735219b2ee8SDavid du Colombier #ifdef UNICODE
get1ch(FILE * fp)7363e12c5d1SDavid du Colombier Tchar get1ch(FILE *fp)	/* get one "character" from input, figure out what alphabet */
7373e12c5d1SDavid du Colombier {
7383e12c5d1SDavid du Colombier 	wchar_t wc;
7393e12c5d1SDavid du Colombier 	char buf[100], *p;
7403e12c5d1SDavid du Colombier 	int i, n, c;
7413e12c5d1SDavid du Colombier 
742*14f51593SDavid du Colombier 	n = c = 0;
7433e12c5d1SDavid du Colombier 	for (i = 0, p = buf; i < MB_CUR_MAX; i++) {
7443e12c5d1SDavid du Colombier 		if ((c = getc(fp)) == EOF)
7453e12c5d1SDavid du Colombier 			return c;
7463e12c5d1SDavid du Colombier 		*p++ = c;
7473e12c5d1SDavid du Colombier 		if ((n = mbtowc(&wc, buf, p-buf)) >= 0)
7483e12c5d1SDavid du Colombier 			break;
7493e12c5d1SDavid du Colombier 	}
7503e12c5d1SDavid du Colombier 	if (n == 1)	/* real ascii, presumably */
7513e12c5d1SDavid du Colombier 		return wc;
7523e12c5d1SDavid du Colombier 	if (n == 0)
7533e12c5d1SDavid du Colombier 		return p[-1];	/* illegal, but what else to do? */
7543e12c5d1SDavid du Colombier 	if (c == EOF)
7553e12c5d1SDavid du Colombier 		return EOF;
7563e12c5d1SDavid du Colombier 	*p = 0;
7573e12c5d1SDavid du Colombier 	return chadd(buf, MBchar, Install);	/* add name even if haven't seen it */
7583e12c5d1SDavid du Colombier }
759219b2ee8SDavid du Colombier #endif	/*UNICODE*/
7603e12c5d1SDavid du Colombier 
pushback(Tchar * b)7613e12c5d1SDavid du Colombier void pushback(Tchar *b)
7623e12c5d1SDavid du Colombier {
7633e12c5d1SDavid du Colombier 	Tchar *ob = b;
7643e12c5d1SDavid du Colombier 
7653e12c5d1SDavid du Colombier 	while (*b++)
7663e12c5d1SDavid du Colombier 		;
7673e12c5d1SDavid du Colombier 	b--;
7683e12c5d1SDavid du Colombier 	while (b > ob && pbp < &pbbuf[NC-3])
7693e12c5d1SDavid du Colombier 		*pbp++ = *--b;
7703e12c5d1SDavid du Colombier 	if (pbp >= &pbbuf[NC-3]) {
7713e12c5d1SDavid du Colombier 		ERROR "pushback overflow" WARN;
7723e12c5d1SDavid du Colombier 		done(2);
7733e12c5d1SDavid du Colombier 	}
7743e12c5d1SDavid du Colombier }
7753e12c5d1SDavid du Colombier 
cpushback(char * b)7763e12c5d1SDavid du Colombier void cpushback(char *b)
7773e12c5d1SDavid du Colombier {
7783e12c5d1SDavid du Colombier 	char *ob = b;
7793e12c5d1SDavid du Colombier 
7803e12c5d1SDavid du Colombier 	while (*b++)
7813e12c5d1SDavid du Colombier 		;
7823e12c5d1SDavid du Colombier 	b--;
7833e12c5d1SDavid du Colombier 	while (b > ob && pbp < &pbbuf[NC-3])
7843e12c5d1SDavid du Colombier 		*pbp++ = *--b;
7853e12c5d1SDavid du Colombier 	if (pbp >= &pbbuf[NC-3]) {
7863e12c5d1SDavid du Colombier 		ERROR "cpushback overflow" WARN;
7873e12c5d1SDavid du Colombier 		done(2);
7883e12c5d1SDavid du Colombier 	}
7893e12c5d1SDavid du Colombier }
7903e12c5d1SDavid du Colombier 
nextfile(void)7913e12c5d1SDavid du Colombier int nextfile(void)
7923e12c5d1SDavid du Colombier {
7933e12c5d1SDavid du Colombier 	char *p;
7943e12c5d1SDavid du Colombier 
7953e12c5d1SDavid du Colombier n0:
7963e12c5d1SDavid du Colombier 	if (ifile != stdin)
7973e12c5d1SDavid du Colombier 		fclose(ifile);
798219b2ee8SDavid du Colombier 	if (ifi > 0 && !nx) {
7993e12c5d1SDavid du Colombier 		if (popf())
8003e12c5d1SDavid du Colombier 			goto n0; /* popf error */
8013e12c5d1SDavid du Colombier 		return(1);	 /* popf ok */
8023e12c5d1SDavid du Colombier 	}
8033e12c5d1SDavid du Colombier 	if (nx || nmfi < mflg) {
8043e12c5d1SDavid du Colombier 		p = mfiles[nmfi++];
8053e12c5d1SDavid du Colombier 		if (*p != 0)
8063e12c5d1SDavid du Colombier 			goto n1;
8073e12c5d1SDavid du Colombier 	}
8083e12c5d1SDavid du Colombier 	if (rargc-- <= 0) {
809219b2ee8SDavid du Colombier 		if ((nfo -= mflg) && !stdi) {
8103e12c5d1SDavid du Colombier 			done(0);
811219b2ee8SDavid du Colombier }
8123e12c5d1SDavid du Colombier 		nfo++;
813219b2ee8SDavid du Colombier 		numtabp[CD].val = stdi = mflg = 0;
8143e12c5d1SDavid du Colombier 		ifile = stdin;
8153e12c5d1SDavid du Colombier 		strcpy(cfname[ifi], "stdin");
8163e12c5d1SDavid du Colombier 		return(0);
8173e12c5d1SDavid du Colombier 	}
8183e12c5d1SDavid du Colombier 	p = (argp++)[0];
819219b2ee8SDavid du Colombier 	if (rargc >= 0)
820219b2ee8SDavid du Colombier 		cfname[ifi][0] = 0;
8213e12c5d1SDavid du Colombier n1:
822219b2ee8SDavid du Colombier 	numtabp[CD].val = 0;
8233e12c5d1SDavid du Colombier 	if (p[0] == '-' && p[1] == 0) {
8243e12c5d1SDavid du Colombier 		ifile = stdin;
8253e12c5d1SDavid du Colombier 		strcpy(cfname[ifi], "stdin");
8263e12c5d1SDavid du Colombier 	} else if ((ifile = fopen(p, "r")) == NULL) {
8273e12c5d1SDavid du Colombier 		ERROR "cannot open file %s", p WARN;
8283e12c5d1SDavid du Colombier 		nfo -= mflg;
8293e12c5d1SDavid du Colombier 		done(02);
8303e12c5d1SDavid du Colombier 	} else
8313e12c5d1SDavid du Colombier 		strcpy(cfname[ifi],p);
8323e12c5d1SDavid du Colombier 	nfo++;
8333e12c5d1SDavid du Colombier 	return(0);
8343e12c5d1SDavid du Colombier }
8353e12c5d1SDavid du Colombier 
8363e12c5d1SDavid du Colombier 
popf(void)8373e12c5d1SDavid du Colombier popf(void)
8383e12c5d1SDavid du Colombier {
8393e12c5d1SDavid du Colombier 	--ifi;
8403e12c5d1SDavid du Colombier 	if (ifi < 0) {
8413e12c5d1SDavid du Colombier 		ERROR "popf went negative" WARN;
8423e12c5d1SDavid du Colombier 		return 1;
8433e12c5d1SDavid du Colombier 	}
844219b2ee8SDavid du Colombier 	numtabp[CD].val = cfline[ifi];	/* restore line counter */
8453e12c5d1SDavid du Colombier 	ip = ipl[ifi];			/* input pointer */
8463e12c5d1SDavid du Colombier 	ifile = ifl[ifi];		/* input FILE * */
8473e12c5d1SDavid du Colombier 	return(0);
8483e12c5d1SDavid du Colombier }
8493e12c5d1SDavid du Colombier 
8503e12c5d1SDavid du Colombier 
flushi(void)8513e12c5d1SDavid du Colombier void flushi(void)
8523e12c5d1SDavid du Colombier {
8533e12c5d1SDavid du Colombier 	if (nflush)
8543e12c5d1SDavid du Colombier 		return;
8553e12c5d1SDavid du Colombier 	ch = 0;
8563e12c5d1SDavid du Colombier 	copyf++;
8573e12c5d1SDavid du Colombier 	while (!nlflg) {
8583e12c5d1SDavid du Colombier 		if (donef && frame == stk)
8593e12c5d1SDavid du Colombier 			break;
8603e12c5d1SDavid du Colombier 		getch();
8613e12c5d1SDavid du Colombier 	}
8623e12c5d1SDavid du Colombier 	copyf--;
8633e12c5d1SDavid du Colombier }
8643e12c5d1SDavid du Colombier 
865219b2ee8SDavid du Colombier /*
866219b2ee8SDavid du Colombier  * return 16-bit, ascii/alphabetic character, ignore chars with more bits,
867219b2ee8SDavid du Colombier  * (internal names), spaces and special cookies (below 040).
868219b2ee8SDavid du Colombier  * Leave STX ETX ENQ ACK and BELL in to maintain compatibility with v7 troff.
869219b2ee8SDavid du Colombier  */
getach(void)870219b2ee8SDavid du Colombier getach(void)
8713e12c5d1SDavid du Colombier {
8723e12c5d1SDavid du Colombier 	Tchar i;
8733e12c5d1SDavid du Colombier 	int j;
8743e12c5d1SDavid du Colombier 
8753e12c5d1SDavid du Colombier 	lgf++;
8763e12c5d1SDavid du Colombier 	j = cbits(i = getch());
877219b2ee8SDavid du Colombier         if (ismot(i)
878219b2ee8SDavid du Colombier 	    || j > SHORTMASK
879219b2ee8SDavid du Colombier 	    || (j <= 040 && j != 002	/*STX*/
880219b2ee8SDavid du Colombier 			&& j != 003	/*ETX*/
881219b2ee8SDavid du Colombier 			&& j != 005	/*ENQ*/
882219b2ee8SDavid du Colombier 			&& j != 006	/*ACK*/
883219b2ee8SDavid du Colombier 			&& j != 007)) {	/*BELL*/
8843e12c5d1SDavid du Colombier 		ch = i;
8853e12c5d1SDavid du Colombier 		j = 0;
8863e12c5d1SDavid du Colombier 	}
8873e12c5d1SDavid du Colombier 	lgf--;
8883e12c5d1SDavid du Colombier 	return j;
8893e12c5d1SDavid du Colombier }
8903e12c5d1SDavid du Colombier 
8913e12c5d1SDavid du Colombier 
casenx(void)8923e12c5d1SDavid du Colombier void casenx(void)
8933e12c5d1SDavid du Colombier {
8943e12c5d1SDavid du Colombier 	lgf++;
8953e12c5d1SDavid du Colombier 	skip();
8963e12c5d1SDavid du Colombier 	getname();
8973e12c5d1SDavid du Colombier 	nx++;
8983e12c5d1SDavid du Colombier 	if (nmfi > 0)
8993e12c5d1SDavid du Colombier 		nmfi--;
9003e12c5d1SDavid du Colombier 	strcpy(mfiles[nmfi], nextf);
9013e12c5d1SDavid du Colombier 	nextfile();
9023e12c5d1SDavid du Colombier 	nlflg++;
9033e12c5d1SDavid du Colombier 	ip = 0;
9043e12c5d1SDavid du Colombier 	pendt = 0;
9053e12c5d1SDavid du Colombier 	frame = stk;
9063e12c5d1SDavid du Colombier 	nxf = frame + 1;
9073e12c5d1SDavid du Colombier }
9083e12c5d1SDavid du Colombier 
9093e12c5d1SDavid du Colombier 
getname(void)9103e12c5d1SDavid du Colombier getname(void)
9113e12c5d1SDavid du Colombier {
9123e12c5d1SDavid du Colombier 	int j, k;
9133e12c5d1SDavid du Colombier 
9143e12c5d1SDavid du Colombier 	lgf++;
9153e12c5d1SDavid du Colombier 	for (k = 0; k < NS - 1; k++) {
916219b2ee8SDavid du Colombier 		j = getach();
917219b2ee8SDavid du Colombier 		if (!j)
9183e12c5d1SDavid du Colombier 			break;
9193e12c5d1SDavid du Colombier 		nextf[k] = j;
9203e12c5d1SDavid du Colombier 	}
9213e12c5d1SDavid du Colombier 	nextf[k] = 0;
9223e12c5d1SDavid du Colombier 	lgf--;
9233e12c5d1SDavid du Colombier 	return(nextf[0]);
9243e12c5d1SDavid du Colombier }
9253e12c5d1SDavid du Colombier 
9263e12c5d1SDavid du Colombier 
caseso(void)9273e12c5d1SDavid du Colombier void caseso(void)
9283e12c5d1SDavid du Colombier {
9293e12c5d1SDavid du Colombier 	FILE *fp;
9303e12c5d1SDavid du Colombier 
9313e12c5d1SDavid du Colombier 	lgf++;
9323e12c5d1SDavid du Colombier 	nextf[0] = 0;
933*14f51593SDavid du Colombier 	fp = NULL;
9343e12c5d1SDavid du Colombier 	if (skip() || !getname() || (fp = fopen(nextf, "r")) == NULL || ifi >= NSO) {
9353e12c5d1SDavid du Colombier 		ERROR "can't open file %s", nextf WARN;
9363e12c5d1SDavid du Colombier 		done(02);
9373e12c5d1SDavid du Colombier 	}
9383e12c5d1SDavid du Colombier 	strcpy(cfname[ifi+1], nextf);
939219b2ee8SDavid du Colombier 	cfline[ifi] = numtabp[CD].val;		/*hold line counter*/
940219b2ee8SDavid du Colombier 	numtabp[CD].val = 0;
9413e12c5d1SDavid du Colombier 	flushi();
9423e12c5d1SDavid du Colombier 	ifl[ifi] = ifile;
9433e12c5d1SDavid du Colombier 	ifile = fp;
9443e12c5d1SDavid du Colombier 	ipl[ifi] = ip;
9453e12c5d1SDavid du Colombier 	ip = 0;
9463e12c5d1SDavid du Colombier 	nx++;
9473e12c5d1SDavid du Colombier 	nflush++;
9483e12c5d1SDavid du Colombier 	ifi++;
9493e12c5d1SDavid du Colombier }
9503e12c5d1SDavid du Colombier 
caself(void)9513e12c5d1SDavid du Colombier void caself(void)	/* set line number and file */
9523e12c5d1SDavid du Colombier {
9533e12c5d1SDavid du Colombier 	int n;
9543e12c5d1SDavid du Colombier 
9553e12c5d1SDavid du Colombier 	if (skip())
9563e12c5d1SDavid du Colombier 		return;
9573e12c5d1SDavid du Colombier 	n = atoi0();
958219b2ee8SDavid du Colombier 	if (!nonumb)
959219b2ee8SDavid du Colombier 		cfline[ifi] = numtabp[CD].val = n - 1;
960219b2ee8SDavid du Colombier 	if (!skip())
961219b2ee8SDavid du Colombier 		if (getname()) {	/* eats '\n' ? */
9623e12c5d1SDavid du Colombier 			strcpy(cfname[ifi], nextf);
963219b2ee8SDavid du Colombier 			if (!nonumb)
964219b2ee8SDavid du Colombier 				numtabp[CD].val--;
965219b2ee8SDavid du Colombier 		}
9663e12c5d1SDavid du Colombier }
9673e12c5d1SDavid du Colombier 
cpout(FILE * fin,char * token)968219b2ee8SDavid du Colombier void cpout(FILE *fin, char *token)
969219b2ee8SDavid du Colombier {
970219b2ee8SDavid du Colombier 	int n;
971219b2ee8SDavid du Colombier 	char buf[1024];
972219b2ee8SDavid du Colombier 
973219b2ee8SDavid du Colombier 	if (token) {	/* BUG: There should be no NULL bytes in input */
974219b2ee8SDavid du Colombier 		char *newl = buf;
975219b2ee8SDavid du Colombier 		while ((fgets(buf, sizeof buf, fin)) != NULL) {
976219b2ee8SDavid du Colombier 			if (newl) {
977219b2ee8SDavid du Colombier 				numtabp[CD].val++; /* line number */
978219b2ee8SDavid du Colombier 				if (strcmp(token, buf) == 0)
979219b2ee8SDavid du Colombier 					return;
980219b2ee8SDavid du Colombier 			}
981219b2ee8SDavid du Colombier 			newl = strchr(buf, '\n');
982219b2ee8SDavid du Colombier 			fputs(buf, ptid);
983219b2ee8SDavid du Colombier 		}
984219b2ee8SDavid du Colombier 	} else {
985219b2ee8SDavid du Colombier 		while ((n = fread(buf, sizeof *buf, sizeof buf, fin)) > 0)
986219b2ee8SDavid du Colombier 			fwrite(buf, n, 1, ptid);
987219b2ee8SDavid du Colombier 		fclose(fin);
988219b2ee8SDavid du Colombier 	}
989219b2ee8SDavid du Colombier }
9903e12c5d1SDavid du Colombier 
casecf(void)9913e12c5d1SDavid du Colombier void casecf(void)
9923e12c5d1SDavid du Colombier {	/* copy file without change */
993219b2ee8SDavid du Colombier 	FILE *fd;
994219b2ee8SDavid du Colombier 	char *eof, *p;
9953e12c5d1SDavid du Colombier 	extern int hpos, esc, po;
9963e12c5d1SDavid du Colombier 
9973e12c5d1SDavid du Colombier 	/* this may not make much sense in nroff... */
9983e12c5d1SDavid du Colombier 
9993e12c5d1SDavid du Colombier 	lgf++;
10003e12c5d1SDavid du Colombier 	nextf[0] = 0;
1001219b2ee8SDavid du Colombier 	if (!skip() && getname()) {
1002219b2ee8SDavid du Colombier 		if (strncmp("<<", nextf, 2) != 0) {
1003219b2ee8SDavid du Colombier 			if ((fd = fopen(nextf, "r")) == NULL) {
10043e12c5d1SDavid du Colombier 				ERROR "can't open file %s", nextf WARN;
10053e12c5d1SDavid du Colombier 				done(02);
10063e12c5d1SDavid du Colombier 			}
1007219b2ee8SDavid du Colombier 			eof = (char *) NULL;
1008219b2ee8SDavid du Colombier 		} else {	/* current file */
1009219b2ee8SDavid du Colombier 			if (pbp > lastpbp || ip) {
1010219b2ee8SDavid du Colombier 				ERROR "casecf: not reading from file" WARN;
1011219b2ee8SDavid du Colombier 				done(02);
1012219b2ee8SDavid du Colombier 			}
1013219b2ee8SDavid du Colombier 			eof = &nextf[2];
1014219b2ee8SDavid du Colombier 			if (!*eof)  {
1015219b2ee8SDavid du Colombier 				ERROR "casecf: missing end of input token" WARN;
1016219b2ee8SDavid du Colombier 				done(02);
1017219b2ee8SDavid du Colombier 			}
1018219b2ee8SDavid du Colombier 			p = eof;
1019219b2ee8SDavid du Colombier 			while(*++p)
1020219b2ee8SDavid du Colombier 				;
1021219b2ee8SDavid du Colombier 			*p++ = '\n';
1022219b2ee8SDavid du Colombier 			*p = 0;
1023219b2ee8SDavid du Colombier 			fd = ifile;
1024219b2ee8SDavid du Colombier 		}
1025219b2ee8SDavid du Colombier 	} else {
1026219b2ee8SDavid du Colombier 		ERROR "casecf: no argument" WARN;
1027219b2ee8SDavid du Colombier 		lgf--;
1028219b2ee8SDavid du Colombier 		return;
1029219b2ee8SDavid du Colombier 	}
10303e12c5d1SDavid du Colombier 	lgf--;
10313e12c5d1SDavid du Colombier 
10323e12c5d1SDavid du Colombier 	/* make it into a clean state, be sure that everything is out */
10333e12c5d1SDavid du Colombier 	tbreak();
10343e12c5d1SDavid du Colombier 	hpos = po;
10353e12c5d1SDavid du Colombier 	esc = 0;
10363e12c5d1SDavid du Colombier 	ptesc();	/* to left margin */
10373e12c5d1SDavid du Colombier 	esc = un;
10383e12c5d1SDavid du Colombier 	ptesc();
10393e12c5d1SDavid du Colombier 	ptlead();
10403e12c5d1SDavid du Colombier 	ptps();
10413e12c5d1SDavid du Colombier 	ptfont();
10423e12c5d1SDavid du Colombier 	flusho();
1043219b2ee8SDavid du Colombier 	cpout(fd, eof);
10443e12c5d1SDavid du Colombier 	ptps();
10453e12c5d1SDavid du Colombier 	ptfont();
10463e12c5d1SDavid du Colombier }
10473e12c5d1SDavid du Colombier 
getline(char * s,int n)10483e12c5d1SDavid du Colombier void getline(char *s, int n)	/* get rest of input line into s */
10493e12c5d1SDavid du Colombier {
10503e12c5d1SDavid du Colombier 	int i;
10513e12c5d1SDavid du Colombier 
10523e12c5d1SDavid du Colombier 	lgf++;
10533e12c5d1SDavid du Colombier 	copyf++;
10543e12c5d1SDavid du Colombier 	skip();
10553e12c5d1SDavid du Colombier 	for (i = 0; i < n-1; i++)
10563e12c5d1SDavid du Colombier 		if ((s[i] = cbits(getch())) == '\n' || s[i] == RIGHT)
10573e12c5d1SDavid du Colombier 			break;
10583e12c5d1SDavid du Colombier 	s[i] = 0;
10593e12c5d1SDavid du Colombier 	copyf--;
10603e12c5d1SDavid du Colombier 	lgf--;
10613e12c5d1SDavid du Colombier }
10623e12c5d1SDavid du Colombier 
casesy(void)10633e12c5d1SDavid du Colombier void casesy(void)	/* call system */
10643e12c5d1SDavid du Colombier {
10653e12c5d1SDavid du Colombier 	char sybuf[NTM];
10663e12c5d1SDavid du Colombier 
10673e12c5d1SDavid du Colombier 	getline(sybuf, NTM);
10683e12c5d1SDavid du Colombier 	system(sybuf);
10693e12c5d1SDavid du Colombier }
10703e12c5d1SDavid du Colombier 
10713e12c5d1SDavid du Colombier 
getpn(char * a)10723e12c5d1SDavid du Colombier void getpn(char *a)
10733e12c5d1SDavid du Colombier {
10743e12c5d1SDavid du Colombier 	int n, neg;
10753e12c5d1SDavid du Colombier 
10763e12c5d1SDavid du Colombier 	if (*a == 0)
10773e12c5d1SDavid du Colombier 		return;
10783e12c5d1SDavid du Colombier 	neg = 0;
10793e12c5d1SDavid du Colombier 	for ( ; *a; a++)
10803e12c5d1SDavid du Colombier 		switch (*a) {
10813e12c5d1SDavid du Colombier 		case '+':
10823e12c5d1SDavid du Colombier 		case ',':
10833e12c5d1SDavid du Colombier 			continue;
10843e12c5d1SDavid du Colombier 		case '-':
10853e12c5d1SDavid du Colombier 			neg = 1;
10863e12c5d1SDavid du Colombier 			continue;
10873e12c5d1SDavid du Colombier 		default:
10883e12c5d1SDavid du Colombier 			n = 0;
10893e12c5d1SDavid du Colombier 			if (isdigit(*a)) {
10903e12c5d1SDavid du Colombier 				do
10913e12c5d1SDavid du Colombier 					n = 10 * n + *a++ - '0';
10923e12c5d1SDavid du Colombier 				while (isdigit(*a));
10933e12c5d1SDavid du Colombier 				a--;
10943e12c5d1SDavid du Colombier 			} else
10953e12c5d1SDavid du Colombier 				n = 9999;
10963e12c5d1SDavid du Colombier 			*pnp++ = neg ? -n : n;
10973e12c5d1SDavid du Colombier 			neg = 0;
10983e12c5d1SDavid du Colombier 			if (pnp >= &pnlist[NPN-2]) {
10993e12c5d1SDavid du Colombier 				ERROR "too many page numbers" WARN;
11003e12c5d1SDavid du Colombier 				done3(-3);
11013e12c5d1SDavid du Colombier 			}
11023e12c5d1SDavid du Colombier 		}
11033e12c5d1SDavid du Colombier 	if (neg)
11043e12c5d1SDavid du Colombier 		*pnp++ = -9999;
1105219b2ee8SDavid du Colombier 	*pnp = -INT_MAX;
11063e12c5d1SDavid du Colombier 	print = 0;
11073e12c5d1SDavid du Colombier 	pnp = pnlist;
1108219b2ee8SDavid du Colombier 	if (*pnp != -INT_MAX)
11093e12c5d1SDavid du Colombier 		chkpn();
11103e12c5d1SDavid du Colombier }
11113e12c5d1SDavid du Colombier 
11123e12c5d1SDavid du Colombier 
setrpt(void)11133e12c5d1SDavid du Colombier void setrpt(void)
11143e12c5d1SDavid du Colombier {
11153e12c5d1SDavid du Colombier 	Tchar i, j;
11163e12c5d1SDavid du Colombier 
11173e12c5d1SDavid du Colombier 	copyf++;
11183e12c5d1SDavid du Colombier 	raw++;
11193e12c5d1SDavid du Colombier 	i = getch0();
11203e12c5d1SDavid du Colombier 	copyf--;
11213e12c5d1SDavid du Colombier 	raw--;
11223e12c5d1SDavid du Colombier 	if ((long) i < 0 || cbits(j = getch0()) == RPT)
11233e12c5d1SDavid du Colombier 		return;
11243e12c5d1SDavid du Colombier 	while (i > 0 && pbp < &pbbuf[NC-3]) {
11253e12c5d1SDavid du Colombier 		i--;
11263e12c5d1SDavid du Colombier 		*pbp++ = j;
11273e12c5d1SDavid du Colombier 	}
11283e12c5d1SDavid du Colombier }
1129