1137 lines · 20.2 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* * n1.c * *	consume options, initialization, main loop, *	input routines, escape function calling */ #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	= stdin;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; main(int argc, char *argv[]){	char *p;	int j;	Tchar i;	char buf[100]; 	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--;			/* pointless */		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){	long 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++;

Lines 1–500 of 1137.