/*
 * n1.c
 *
 *	consume options, initialization, main loop,
 *	input routines, escape function calling
 */

#include <u.h>
#include "tdef.h"
#include "fns.h"
#include "ext.h"
#include "dwbinit.h"

#include <setjmp.h>
#include <time.h>

char	*Version	= "March 11, 1994";

#ifndef DWBVERSION
#define DWBVERSION      "???"
#endif

char	*DWBfontdir = FONTDIR;
char	*DWBntermdir = NTERMDIR;
char	*DWBalthyphens = ALTHYPHENS;
char	*DWBhomedir = "";

dwbinit dwbpaths[] = {
	&DWBfontdir, NULL, 0,
	&DWBntermdir, NULL, 0,
	&DWBalthyphens, NULL, 0,
	&DWBhomedir, NULL, 0,
	NULL, nextf, NS,
	NULL, NULL, 0
};

int	TROFF	= 1;	/* assume we started in troff... */

jmp_buf sjbuf;
Offset	ipl[NSO];

static	FILE	*ifile;
static	FILE	*ifl[NSO];	/* open input file pointers */
char	cfname[NSO+1][NS] = {  "stdin" };	/* file name stack */
int	cfline[NSO];		/* input line count stack */
char	*progname;		/* program name (troff or nroff) */

int	trace = 0;	/* tracing mode: default off */
int	trace1 = 0;

int
main(int argc, char *argv[])
{
	char *p;
	int j;
	Tchar i;
	char buf[100];

	ifile = stdin;		/* gcc */
	ptid = stdout;

	buf[0] = '\0';		/* make sure it's empty (silly 3b2) */
	progname = argv[0];
	if ((p = strrchr(progname, '/')) == NULL)
		p = progname;
	else
		p++;
	DWBinit(progname, dwbpaths);
	if (strcmp(p, "nroff") == 0)
		TROFF = 0;
#ifdef UNICODE
	alphabet = 128;	/* unicode for plan 9 */
#endif	/*UNICODE*/
	mnspace();
	nnspace();
	mrehash();
	nrehash();
	numtabp[NL].val = -1;

	while (--argc > 0 && (++argv)[0][0] == '-')
		switch (argv[0][1]) {

		case 'N':	/* ought to be used first... */
			TROFF = 0;
			break;
		case 'd':
			fprintf(stderr, "troff/nroff version %s\n", Version);
			break;
		case 'F':	/* switch font tables from default */
			if (argv[0][2] != '\0') {
				strcpy(termtab, &argv[0][2]);
				strcpy(fontdir, &argv[0][2]);
			} else {
				argv++; argc--;
				strcpy(termtab, argv[0]);
				strcpy(fontdir, argv[0]);
			}
			break;
		case 0:
			goto start;
		case 'i':
			stdi++;
			break;
		case 'n':
			npn = atoi(&argv[0][2]);
			break;
		case 'u':	/* set emboldening amount */
			bdtab[3] = atoi(&argv[0][2]);
			if (bdtab[3] < 0 || bdtab[3] > 50)
				bdtab[3] = 0;
			break;
		case 's':
			if (!(stop = atoi(&argv[0][2])))
				stop++;
			break;
		case 'r':
			sprintf(buf + strlen(buf), ".nr %c %s\n",
				argv[0][2], &argv[0][3]);
			/* not yet cpushback(buf);*/
			/* dotnr(&argv[0][2], &argv[0][3]); */
			break;
		case 'm':
			if (mflg++ >= NMF) {
				ERROR "Too many macro packages: %s", argv[0] WARN;
				break;
			}
			strcpy(mfiles[nmfi], nextf);
			strcat(mfiles[nmfi++], &argv[0][2]);
			break;
		case 'o':
			getpn(&argv[0][2]);
			break;
		case 'T':
			strcpy(devname, &argv[0][2]);
			dotT++;
			break;
		case 'a':
			ascii = 1;
			break;
		case 'h':
			hflg++;
			break;
		case 'e':
			eqflg++;
			break;
		case 'q':
			quiet++;
			save_tty();
			break;
		case 'V':
			fprintf(stdout, "%croff: DWB %s\n", 
					TROFF ? 't' : 'n', DWBVERSION);
			exit(0);
		case 't':
			if (argv[0][2] != '\0')
				trace = trace1 = argv[0][2];
			break;		/* for the sake of compatibility */
		default:
			ERROR "unknown option %s", argv[0] WARN;
			done(02);
		}

start:
	/*
	 * cpushback maintains a LIFO, so push pack the -r arguments
	 * in reverse order to maintain a FIFO in case someone did -rC1 -rC3
	 */
	if (buf[0]) {
		char *p = buf;
		while(*p++)
			;
		while(p > buf) {
			while(strncmp(p, ".nr", 3) != 0)
				p--;
			cpushback(p);
			*p-- = '\0';
		}
	}
	argp = argv;
	rargc = argc;
	nmfi = 0;
	init2();
	setjmp(sjbuf);
loop:
	copyf = lgf = nb = nflush = nlflg = 0;
	if (ip && rbf0(ip) == 0 && ejf && frame->pframe <= ejl && dip == d) {
		nflush++;
		trap = 0;
		eject((Stack *)0);
		goto loop;
	}
	i = getch();
	if (pendt)
		goto Lt;
	if ((j = cbits(i)) == XPAR) {
		copyf++;
		tflg++;
		while (cbits(i) != '\n')
			pchar(i = getch());
		tflg = 0;
		copyf--;
		goto loop;
	}
	if (j == cc || j == c2) {
		if (j == c2)
			nb++;
		copyf++;
		while ((j = cbits(i = getch())) == ' ' || j == '\t')
			;
		ch = i;
		copyf--;
		control(getrq(), 1);
		flushi();
		goto loop;
	}
Lt:
	ch = i;
	text();
	if (nlflg)
		numtabp[HP].val = 0;
	goto loop;
}



void init2(void)
{
	int i;
	char buf[100];

	for (i = NTRTAB; --i; )
		trtab[i] = i;
	trtab[UNPAD] = ' ';
	iflg = 0;
	obufp = obuf;
	if (TROFF)
		t_ptinit();
	else
		n_ptinit();
	mchbits();
	cvtime();
	numtabp[PID].val = getpid();
	numtabp[HP].val = init = 0;
	numtabp[NL].val = -1;
	nfo = 0;
	copyf = raw = 0;
	sprintf(buf, ".ds .T %s\n", devname);
	cpushback(buf);
	sprintf(buf, ".ds .P %s\n", DWBhomedir);
	cpushback(buf);
	numtabp[CD].val = -1;	/* compensation */
	nx = mflg;
	frame = stk = (Stack *)setbrk(STACKSIZE);
	dip = &d[0];
	nxf = frame + 1;
	for (i = 1; i < NEV; i++)	/* propagate the environment */
		envcopy(&env[i], &env[0]);
	for (i = 0; i < NEV; i++) {
		if ((env[i]._word._bufp = (Tchar *)calloc(WDSIZE, sizeof(Tchar))) == NULL) {
			ERROR "not enough room for word buffers" WARN;
			done2(1);
		}
		env[i]._word._size = WDSIZE;
		if ((env[i]._line._bufp = (Tchar *)calloc(LNSIZE, sizeof(Tchar))) == NULL) {
			ERROR "not enough room for line buffers" WARN;
			done2(1);
		}
		env[i]._line._size = LNSIZE;
	}
	if ((oline = (Tchar *)calloc(OLNSIZE, sizeof(Tchar))) == NULL) {
		ERROR "not enough room for line buffers" WARN;
		done2(1);
	}
	olinep = oline;
	olnsize = OLNSIZE;
	blockinit();
}

void cvtime(void)
{
	time_t tt;
	struct tm *ltime;

	time(&tt);
	ltime = localtime(&tt);
	numtabp[YR].val = ltime->tm_year % 100;
	numtabp[YR].fmt = 2;
	numtabp[MO].val = ltime->tm_mon + 1;	/* troff uses 1..12 */
	numtabp[DY].val = ltime->tm_mday;
	numtabp[DW].val = ltime->tm_wday + 1;	/* troff uses 1..7 */
}



char	errbuf[200];

void errprint(void)	/* error message printer */
{
	int savecd = numtabp[CD].val;

	if (!nlflg)
		numtabp[CD].val++;

	fprintf(stderr, "%s: ", progname);
	fputs(errbuf, stderr);
	if (cfname[ifi][0])
		fprintf(stderr, "; %s:%d", cfname[ifi], numtabp[CD].val);
	fputs("\n", stderr);
	if (cfname[ifi][0])
		stackdump();
	numtabp[CD].val = savecd;
}


int control(int a, int b)
{
	int j, k;
	extern Contab *contabp;

	numerr.type = RQERR;
	numerr.req = a;
	if (a == 0 || (j = findmn(a)) == -1)
		return(0);
	if (contabp[j].f == 0) {
		if (trace & TRMAC)
			fprintf(stderr, "invoke macro %s\n", unpair(a));
		if (dip != d)
			for (k = dilev; k; k--)
				if (d[k].curd == a) {
					ERROR "diversion %s invokes itself during diversion",
								unpair(a) WARN;
					edone(0100);
				}
		nxf->nargs = 0;
		if (b)
			collect();
		flushi();
		return pushi(contabp[j].mx, a);	/* BUG??? all that matters is 0/!0 */
	}
	if (b) {
		if (trace & TRREQ)
			fprintf(stderr, "invoke request %s\n", unpair(a));
		 (*contabp[j].f)();
	}
	return(0);
}

void casept(void)
{
	int i;

	noscale++;
	if (skip())
		i = trace1;
	else {
		i = max(inumb(&trace), 0);
		if (nonumb)
			i = trace1;
	}
	trace1 = trace;
	trace = i;
	noscale = 0;
}


int getrq(void)
{
	int i, j;

	if ((i = getach()) == 0 || (j = getach()) == 0)
		goto rtn;
	i = PAIR(i, j);
rtn:
	return(i);
}

/*
 * table encodes some special characters, to speed up tests
 * in getch, viz FLSS, RPT, f, \b, \n, fc, tabch, ldrch
 */

char gchtab[NCHARS] = {
	000,004,000,000,010,000,000,000, /* fc, ldr */
	001,002,001,000,001,000,000,000, /* \b, tab, nl, RPT */
	000,000,000,000,000,000,000,000,
	000,001,000,001,000,000,000,000, /* FLSS, ESC */
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,001,000, /* f */
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000,
	000,000,000,000,000,000,000,000
};

int realcbits(Tchar c)	/* return character bits, or MOTCH if motion */
{
	if (ismot(c))
		return MOTCH;
	else
		return c & 0xFFFF;
}

Tchar getch(void)
{
	int k;
	Tchar i, j;

g0:
	if (ch) {
		i = ch;
		if (cbits(i) == '\n')
			nlflg++;
		ch = 0;
		return(i);
	}

	if (nlflg)
		return('\n');
	i = getch0();
	if (ismot(i))
		return(i);
	k = cbits(i);
	if (k >= sizeof(gchtab)/sizeof(gchtab[0]) || gchtab[k] == 0)	/* nothing special */
		return(i);
	if (k != ESC) {
		if (k == '\n') {
			nlflg++;
			if (ip == 0)
				numtabp[CD].val++; /* line number */
			return(k);
		}
		if (k == FLSS) {
			copyf++; 
			raw++;
			i = getch0();
			if (!fi)
				flss = i;
			copyf--; 
			raw--;
			goto g0;
		}
		if (k == RPT) {
			setrpt();
			goto g0;
		}
		if (!copyf) {
			if (k == 'f' && lg && !lgf) {
				i = getlg(i);
				return(i);
			}
			if (k == fc || k == tabch || k == ldrch) {
				if ((i = setfield(k)) == 0)
					goto g0; 
				else 
					return(i);
			}
			if (k == '\b') {
				i = makem(-width(' ' | chbits));
				return(i);
			}
		}
		return(i);
	}

	k = cbits(j = getch0());
	if (ismot(j))
		return(j);

	switch (k) {
	case 'n':	/* number register */
		setn();
		goto g0;
	case '$':	/* argument indicator */
		seta();
		goto g0;
	case '*':	/* string indicator */
		setstr();
		goto g0;
	case '{':	/* LEFT */
		i = LEFT;
		goto gx;
	case '}':	/* RIGHT */
		i = RIGHT;
		goto gx;
	case '"':	/* comment */
		while (cbits(i = getch0()) != '\n')
			;
		if (ip == 0)
			numtabp[CD].val++; /* line number */
		nlflg++;
		return(i);

/* experiment: put it here instead of copy mode */
	case '(':	/* special char name \(xx */
	case 'C':	/* 		\C'...' */
		if ((i = setch(k)) == 0)
			goto g0;
		goto gx;

	case ESC:	/* double backslash */
		i = eschar;
		goto gx;
	case 'e':	/* printable version of current eschar */
		i = PRESC;
		goto gx;
	case '\n':	/* concealed newline */
		numtabp[CD].val++;
		goto g0;
	case ' ':	/* unpaddable space */
		i = UNPAD;
		goto gx;
	case '\'':	/* \(aa */
		i = ACUTE;
		goto gx;
	case '`':	/* \(ga */
		i = GRAVE;
		goto gx;
	case '_':	/* \(ul */
		i = UNDERLINE;
		goto gx;
	case '-':	/* current font minus */
		i = MINUS;
		goto gx;
	case '&':	/* filler */
		i = FILLER;
		goto gx;
	case 'c':	/* to be continued */
		i = CONT;
		goto gx;
	case '!':	/* transparent indicator */
		i = XPAR;
		goto gx;
	case 't':	/* tab */
		i = '\t';
		return(i);
	case 'a':	/* leader (SOH) */
/* old:		*pbp++ = LEADER; goto g0; */
		i = LEADER;
		return i;
	case '%':	/* ohc */
		i = OHC;
		return(i);
	case 'g':	/* return format of a number register */
		setaf();	/* should this really be in copy mode??? */
		goto g0;
	case '.':	/* . */
		i = '.';
gx:
		setsfbits(i, sfbits(j));
		return(i);
	}
	if (copyf) {
		*pbp++ = j;
		return(eschar);
	}
	switch (k) {

	case 'f':	/* font indicator */
		setfont(0);
		goto g0;
	case 's':	/* size indicator */
		setps();
		goto g0;
	case 'v':	/* vert mot */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		if (i = vmot()) {
			return(i);
		}
		goto g0;
	case 'h': 	/* horiz mot */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		if (i = hmot())
			return(i);
		goto g0;
	case '|':	/* narrow space */
		if (NROFF)
			goto g0;
		return(makem((int)(EM)/6));
	case '^':	/* half narrow space */
		if (NROFF)
			goto g0;
		return(makem((int)(EM)/12));
	case 'w':	/* width function */
		setwd();
		goto g0;
	case 'p':	/* spread */
		spread++;
		goto g0;
	case 'N':	/* absolute character number */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		if ((i = setabs()) == 0)
			goto g0;
		return i;
	case 'H':	/* character height */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		return(setht());
	case 'S':	/* slant */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		return(setslant());
	case 'z':	/* zero with char */
		return(setz());
	case 'l':	/* hor line */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		setline();
		goto g0;
	case 'L':	/* vert line */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		setvline();
		goto g0;
	case 'D':	/* drawing function */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		setdraw();
		goto g0;
	case 'X':	/* \X'...' for copy through */
		setxon();
		goto g0;
	case 'b':	/* bracket */
		setbra();
		goto g0;
	case 'o':	/* overstrike */
		setov();
		goto g0;
	case 'k':	/* mark hor place */
		if ((k = findr(getsn())) != -1) {
			numtabp[k].val = numtabp[HP].val;
		}
		goto g0;
	case '0':	/* number space */
		return(makem(width('0' | chbits)));
	case 'x':	/* extra line space */
		numerr.type = numerr.escarg = 0; numerr.esc = k;
		if (i = xlss())
			return(i);
		goto g0;
	case 'u':	/* half em up */
	case 'r':	/* full em up */
	case 'd':	/* half em down */
		return(sethl(k));
	default:
		return(j);
	}
	/* NOTREACHED */
}

void setxon(void)	/* \X'...' for copy through */
{
	Tchar xbuf[NC];
	Tchar *i;
	Tchar c;
	int delim, k;

	if (ismot(c = getch()))
		return;
	delim = cbits(c);
	i = xbuf;
	*i++ = XON | chbits;
	while ((k = cbits(c = getch())) != delim && k != '\n' && i < xbuf+NC-1) {
		if (k == ' ')
			setcbits(c, WORDSP);
		*i++ = c | ZBIT;
	}
	*i++ = XOFF | chbits;
	*i = 0;
	pushback(xbuf);
}


char	ifilt[32] = { 0, 001, 002, 003, 0, 005, 006, 007, 010, 011, 012 };

Tchar getch0(void)
{
	Tchar i;

again:
	if (pbp > lastpbp)
		i = *--pbp;
	else if (ip) {
		/* i = rbf(); */
		i = rbf0(ip);
		if (i == 0)
			i = rbf();
		else {
			++ip;
			if (pastend(ip)) {
				--ip;
				rbf();
			}
		}
	} else {
		if (donef || ndone)
			done(0);
		if (nx || 1) {	/* BUG: was ibufp >= eibuf, so EOF test is wrong */
			if (nfo < 0)
				ERROR "in getch0, nfo = %d", nfo WARN;
			if (nfo == 0) {
g0:
				if (nextfile()) {
					if (ip)
						goto again;
				}
			}
			nx = 0;
#ifdef UNICODE
			if (MB_CUR_MAX > 1)
				i = get1ch(ifile);
			else
#endif	/*UNICODE*/
				i = getc(ifile);
			if (i == EOF)
				goto g0;
			if (ip)
				goto again;
		}
/*g2: */
		if (i >= 040)			/* zapped: && i < 0177 */
			goto g4;
		i = ifilt[i];
	}
	if (cbits(i) == IMP && !raw)
		goto again;
	if (i == 0 && !init && !raw) {		/* zapped:  || i == 0177 */
		goto again;
	}
g4:
	if (ismot(i))
		return i;
	if (copyf == 0 && sfbits(i) == 0)
		i |= chbits;
	if (cbits(i) == eschar && !raw)
		setcbits(i, ESC);
	return(i);
}


#ifdef UNICODE
Tchar get1ch(FILE *fp)	/* get one "character" from input, figure out what alphabet */
{
	wchar_t wc;
	char buf[100], *p;
	int i, n, c;

	for (i = 0, p = buf; i < MB_CUR_MAX; i++) {
		if ((c = getc(fp)) == EOF)
			return c;
		*p++ = c;
		if ((n = mbtowc(&wc, buf, p-buf)) >= 0)
			break;
	}

	if (n == 1)	/* real ascii, presumably */
		return wc;
	if (n == 0)
		return p[-1];	/* illegal, but what else to do? */
	if (c == EOF)
		return EOF;
	*p = 0;
	return chadd(buf, MBchar, Install);	/* add name even if haven't seen it */
}
#endif	/*UNICODE*/

void pushback(Tchar *b)
{
	Tchar *ob = b;

	while (*b++)
		;
	b--;
	while (b > ob && pbp < &pbbuf[NC-3])
		*pbp++ = *--b;
	if (pbp >= &pbbuf[NC-3]) {
		ERROR "pushback overflow" WARN;
		done(2);
	}
}

void cpushback(char *b)
{
	char *ob = b;

	while (*b++)
		;
	b--;
	while (b > ob && pbp < &pbbuf[NC-3])
		*pbp++ = *--b;
	if (pbp >= &pbbuf[NC-3]) {
		ERROR "cpushback overflow" WARN;
		done(2);
	}
}

int nextfile(void)
{
	char *p;

n0:
	if (ifile != stdin)
		fclose(ifile);
	if (ifi > 0 && !nx) {
		if (popf())
			goto n0; /* popf error */
		return(1);	 /* popf ok */
	}
	if (nx || nmfi < mflg) {
		p = mfiles[nmfi++];
		if (*p != 0)
			goto n1;
	}
	if (rargc-- <= 0) {
		if ((nfo -= mflg) && !stdi) {
			done(0);
}
		nfo++;
		numtabp[CD].val = stdi = mflg = 0;
		ifile = stdin;
		strcpy(cfname[ifi], "stdin");
		return(0);
	}
	p = (argp++)[0];
	if (rargc >= 0)
		cfname[ifi][0] = 0;
n1:
	numtabp[CD].val = 0;
	if (p[0] == '-' && p[1] == 0) {
		ifile = stdin;
		strcpy(cfname[ifi], "stdin");
	} else if ((ifile = fopen(unsharp(p), "r")) == NULL) {
		ERROR "cannot open file %s", p WARN;
		nfo -= mflg;
		done(02);
	} else
		strcpy(cfname[ifi],p);
	nfo++;
	return(0);
}

int
popf(void)
{
	--ifi;
	if (ifi < 0) {
		ERROR "popf went negative" WARN;
		return 1;
	}
	numtabp[CD].val = cfline[ifi];	/* restore line counter */
	ip = ipl[ifi];			/* input pointer */
	ifile = ifl[ifi];		/* input FILE * */
	return(0);
}


void flushi(void)
{
	if (nflush)
		return;
	ch = 0;
	copyf++;
	while (!nlflg) {
		if (donef && frame == stk)
			break;
		getch();
	}
	copyf--;
}

/*
 * return 16-bit, ascii/alphabetic character, ignore chars with more bits,
 * (internal names), spaces and special cookies (below 040).
 * Leave STX ETX ENQ ACK and BELL in to maintain compatibility with v7 troff.
 */
int
getach(void)
{
	Tchar i;
	int j;

	lgf++;
	j = cbits(i = getch());
        if (ismot(i)
	    || j > SHORTMASK
	    || (j <= 040 && j != 002	/*STX*/
			&& j != 003	/*ETX*/
			&& j != 005	/*ENQ*/
			&& j != 006	/*ACK*/
			&& j != 007)) {	/*BELL*/
		ch = i;
		j = 0;
	}
	lgf--;
	return j;
}


void casenx(void)
{
	lgf++;
	skip();
	getname();
	nx++;
	if (nmfi > 0)
		nmfi--;
	strcpy(mfiles[nmfi], nextf);
	nextfile();
	nlflg++;
	ip = 0;
	pendt = 0;
	frame = stk;
	nxf = frame + 1;
}

int
getname(void)
{
	int j, k;

	lgf++;
	for (k = 0; k < NS - 1; k++) {
		j = getach();
		if (!j)
			break;
		nextf[k] = j;
	}
	nextf[k] = 0;
	lgf--;
	return(nextf[0]);
}


void caseso(void)
{
	FILE *fp = 0;

	lgf++;
	nextf[0] = 0;
	if (skip() || !getname() || (fp = fopen(unsharp(nextf), "r")) == NULL || ifi >= NSO) {
		ERROR "can't open file %s", nextf WARN;
		done(02);
	}
	strcpy(cfname[ifi+1], nextf);
	cfline[ifi] = numtabp[CD].val;		/*hold line counter*/
	numtabp[CD].val = 0;
	flushi();
	ifl[ifi] = ifile;
	ifile = fp;
	ipl[ifi] = ip;
	ip = 0;
	nx++;
	nflush++;
	ifi++;
}

void caself(void)	/* set line number and file */
{
	int n;

	if (skip())
		return;
	n = atoi0();
	if (!nonumb)
		cfline[ifi] = numtabp[CD].val = n - 1;
	if (!skip())
		if (getname()) {	/* eats '\n' ? */
			strcpy(cfname[ifi], nextf);
			if (!nonumb)
				numtabp[CD].val--;
		}
}

void cpout(FILE *fin, char *token)
{
	int n;
	char buf[1024];

	if (token) {	/* BUG: There should be no NULL bytes in input */
		char *newl = buf;
		while ((fgets(buf, sizeof buf, fin)) != NULL) {
			if (newl) {
				numtabp[CD].val++; /* line number */
				if (strcmp(token, buf) == 0)
					return;
			}
			newl = strchr(buf, '\n');
			fputs(buf, ptid);
		}
	} else {
		while ((n = fread(buf, sizeof *buf, sizeof buf, fin)) > 0)
			fwrite(buf, n, 1, ptid);
		fclose(fin);
	}
}

void casecf(void)
{	/* copy file without change */
	FILE *fd;
	char *eof, *p;
	extern int hpos, esc, po;

	/* this may not make much sense in nroff... */

	lgf++;
	nextf[0] = 0;
	if (!skip() && getname()) {
		if (strncmp("<<", nextf, 2) != 0) {
			if ((fd = fopen(unsharp(nextf), "r")) == NULL) {
				ERROR "can't open file %s", nextf WARN;
				done(02);
			}
			eof = (char *) NULL;
		} else {	/* current file */
			if (pbp > lastpbp || ip) {
				ERROR "casecf: not reading from file" WARN;
				done(02);
			}
			eof = &nextf[2];
			if (!*eof)  {
				ERROR "casecf: missing end of input token" WARN;
				done(02);
			}
			p = eof;
			while(*++p)
				;
			*p++ = '\n';
			*p = 0;
			fd = ifile;
		}
	} else {
		ERROR "casecf: no argument" WARN;
		lgf--;
		return;
	}
	lgf--;

	/* make it into a clean state, be sure that everything is out */
	tbreak();
	hpos = po;
	esc = 0;
	ptesc();	/* to left margin */
	esc = un;
	ptesc();
	ptlead();
	ptps();
	ptfont();
	flusho();
	cpout(fd, eof);
	ptps();
	ptfont();
}

void getline(char *s, int n)	/* get rest of input line into s */
{
	int i;

	lgf++;
	copyf++;
	skip();
	for (i = 0; i < n-1; i++)
		if ((s[i] = cbits(getch())) == '\n' || s[i] == RIGHT)
			break;
	s[i] = 0;
	copyf--;
	lgf--;
}

void casesy(void)	/* call system */
{
	char sybuf[NTM];

	getline(sybuf, NTM);
	system(sybuf);
}


void getpn(char *a)
{
	int n, neg;

	if (*a == 0)
		return;
	neg = 0;
	for ( ; *a; a++)
		switch (*a) {
		case '+':
		case ',':
			continue;
		case '-':
			neg = 1;
			continue;
		default:
			n = 0;
			if (isdigit((uchar)*a)) {
				do
					n = 10 * n + *a++ - '0';
				while (isdigit((uchar)*a));
				a--;
			} else
				n = 9999;
			*pnp++ = neg ? -n : n;
			neg = 0;
			if (pnp >= &pnlist[NPN-2]) {
				ERROR "too many page numbers" WARN;
				done3(-3);
			}
		}
	if (neg)
		*pnp++ = -9999;
	*pnp = -INT_MAX;
	print = 0;
	pnp = pnlist;
	if (*pnp != -INT_MAX)
		chkpn();
}


void setrpt(void)
{
	Tchar i, j;

	copyf++;
	raw++;
	i = getch0();
	copyf--;
	raw--;
	if ((long) i < 0 || cbits(j = getch0()) == RPT)
		return;
	while (i > 0 && pbp < &pbbuf[NC-3]) {
		i--;
		*pbp++ = j;
	}
}
