⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 n1.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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      "???"#endifchar	*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--;		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++;		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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -