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

📄 roff.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* roff - text justifier		Author: George L. Sicherman *//* *	roff - C version. *	the Colonel.  19 May 1983. * *	Copyright 1983 by G. L. Sicherman. *	You may use and alter this software freely for noncommercial ends *	so long as you leave this message alone. * *	Fix by Tim Maroney, 31 Dec 1984. *	.hc implemented, 8 Feb 1985. *	Fix to hyphenating with underlining, 12 Feb 1985. *	Fixes to long-line hang and .bp by Dave Tutelman, 30 Mar 1985. *	Fix to centering valve with long input lines, 4 May 1987. */#include <sys/types.h>#include <sys/stat.h>#include <termios.h>#include <signal.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <stdio.h>#define SUFTAB	"/usr/lib/suftab"#define TXTLEN	(o_pl-o_m1-o_m2-o_m3-o_m4-2)#define IDTLEN	(o_ti>=0?o_ti:o_in)#define MAXMAC	64#define MAXDEPTH 10#define MAXLENGTH 255#define UNDERL	'\200'char cumbuf[BUFSIZ];char spacechars[] = " \t\n";int sflag, hflag, startpage, stoppage;char holdword[MAXLENGTH], *holdp;char assyline[MAXLENGTH];int assylen;char ehead[100], efoot[100], ohead[100], ofoot[100];struct macrotype {  char mname[3];  long int moff;} macro[MAXMAC];int n_macros;int depth;int adjtoggle;int isrequest = 0;char o_tr[40][2];		/* OUTPUT TRANSLATION TABLE */int o_cc = '.';			/* CONTROL CHARACTER */int o_hc = -1;			/* HYPHENATION CHARACTER */int o_tc = ' ';			/* TABULATION CHARACTER */int o_in = 0;			/* INDENT SIZE */int o_ix = -1;			/* NEXT INDENT SIZE */int o_ta[20] = {	9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105,	113, 121, 129, 137, 145, 153, 161};int n_ta = 20;			/* #TAB STOPS */int o_ll = 65, o_ad = 1, o_po = 0, o_ls = 1, o_ig = 0, o_fi = 1;int o_pl = 66, o_ro = 0, o_hx = 0, o_bl = 0, o_sp = 0, o_sk = 0;int o_ce = 0, o_m1 = 2, o_m2 = 2, o_m3 = 1, o_m4 = 3, o_ul = 0;int o_li = 0, o_n1 = 0, o_n2 = 0, o_bp = -1, o_hy = 1;int o_ni = 1;			/* LINE-NUMBER INDENT */int o_nn = 0;			/* #LINES TO SUPPRESS NUMBERING */int o_ti = -1;			/* TEMPORARY INDENT */int page_no = -1;int line_no = 9999;int n_outwords;FILE *File, *Macread, *Macwrite;FILE *Save;long int teller[MAXDEPTH];char *request[] = {	   "ad", "ar", "bl", "bp", "br", "cc", "ce", "de",	 "ds", "ef", "eh", "fi", "fo", "hc", "he", "hx", "hy", "ig",	   "in", "ix", "li", "ll", "ls", "m1", "m2", "m3", "m4",	 "n1", "n2", "na", "ne", "nf", "ni", "nn", "nx", "of", "oh",	 "pa", "pl", "po", "ro", "sk", "sp", "ss", "ta", "tc", "ti",	   "tr", "ul", 0};char *mfilnam = "/tmp/rtmXXXXXX";int c;				/* LAST CHAR READ */struct termios tty;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void mesg, (int f));_PROTOTYPE(void readfile, (void));_PROTOTYPE(int readline, (void));_PROTOTYPE(void bumpword, (void));_PROTOTYPE(void dehyph, (char *s));_PROTOTYPE(int reallen, (char *s));_PROTOTYPE(void tabulate, (void));_PROTOTYPE(int readreq, (void));_PROTOTYPE(void snset, (int *par));_PROTOTYPE(int tread, (char *s));_PROTOTYPE(void nread, (int *i));_PROTOTYPE(int snread, (int *i, int *s, int sdef));_PROTOTYPE(int cread, (int *k));_PROTOTYPE(void defmac, (void));_PROTOTYPE(void openmac, (void));_PROTOTYPE(int copyline, (void));_PROTOTYPE(void submac, (int r));_PROTOTYPE(void endmac, (void));_PROTOTYPE(void do_ta, (void));_PROTOTYPE(void do_tr, (void));_PROTOTYPE(void do_nx, (void));_PROTOTYPE(int skipsp, (void));_PROTOTYPE(void writebreak, (void));_PROTOTYPE(void blankline, (void));_PROTOTYPE(void writeline, (int adflag, int flushflag));_PROTOTYPE(void fillline, (void));_PROTOTYPE(void insrt, (int p));_PROTOTYPE(void newpage, (void));_PROTOTYPE(void beginpage, (void));_PROTOTYPE(void endpage, (void));_PROTOTYPE(void blankpage, (void));_PROTOTYPE(void waitawhile, (void));_PROTOTYPE(void nix, (int sig));_PROTOTYPE(void writetitle, (char *t));_PROTOTYPE(char *pgform, (void));_PROTOTYPE(int titlen, (char *t, int c, int k));_PROTOTYPE(void spits, (char *s));_PROTOTYPE(void spit, (int c));_PROTOTYPE(int suck, (void));_PROTOTYPE(char *strhas, (char *p, int c));_PROTOTYPE(char *strend, (char *p));_PROTOTYPE(int isspace, (int c));_PROTOTYPE(int isalnum, (int c));_PROTOTYPE(int isdigit, (int c));_PROTOTYPE(int islegal, (int c));_PROTOTYPE(void bomb, (void));int main(argc, argv)int argc;char **argv;{  if (!isatty(1)) setbuf(stdout, cumbuf);  while (--argc) switch (**++argv) {	    case '+':	startpage = atoi(++*argv);	break;	    case '-':		++*argv;		if (isdigit(**argv))			stoppage = atoi(*argv);		else			switch (**argv) {			    case 's':	sflag++;	break;			    case 'h':	hflag++;	break;			    default:	bomb();			}		break;	    default:		argc++;		goto endargs;	}endargs:  if (sflag) tcgetattr(0, &tty);  mesg(0);			/* BLOCK OUT MESSAGES */  assylen = 0;  assyline[0] = '\0';  if (!argc) {	File = stdin;	readfile();  } else	while (--argc) {		File = fopen(*argv, "r");		if (NULL == File) {			fprintf(stderr, "roff: cannot read %s\n", *argv);			exit(1);		}		readfile();		fclose(File);		argv++;	}  writebreak();  endpage();  for (; o_sk; o_sk--) blankpage();  mesg(1);			/* ALLOW MESSAGES */  return(0);}void mesg(f)int f;{  static int mode;  struct stat cbuf;  if (!isatty(1)) return;  if (!f) {	fstat(1,&cbuf);	mode = cbuf.st_mode;	chmod(ttyname(1),mode & ~022);  }  else chmod(ttyname(1),mode);/* ------- end of mesg */}void readfile(){  while (readline()) {	if (isrequest) continue;	if (o_ce || !o_fi) {		if (assylen)			writeline(0, 1);		else			blankline();		if (o_ce) o_ce--;	}  }}int readline(){  int startline, doingword;  isrequest = 0;  startline = 1;  doingword = 0;  c = suck();  if (c == '\n') {	o_sp = 1;	writebreak();	goto out;  } else if (isspace(c))	writebreak();  for (;;) {	if (c == EOF) {		if (doingword) bumpword();		break;	}	if (c != o_cc && o_ig) {		while (c != '\n' && c != EOF) c = suck();		break;	}	if (isspace(c) && !doingword) {		startline = 0;		switch (c) {		    case ' ':			assyline[assylen++] = ' ';			break;		    case '\t':	tabulate();	break;		    case '\n':	goto out;		}		c = suck();		continue;	}	if (isspace(c) && doingword) {		bumpword();		if (c == '\t')			tabulate();		else if (assylen)			assyline[assylen++] = ' ';		doingword = 0;		if (c == '\n') break;	}	if (!isspace(c)) {		if (doingword)			*holdp++ = o_ul ? c | UNDERL : c;		else if (startline && c == o_cc && !o_li) {			isrequest = 1;			return readreq();		} else {			doingword = 1;			holdp = holdword;			*holdp++ = o_ul ? c | UNDERL : c;		}	}	startline = 0;	c = suck();  }out:  if (o_ul) o_ul--;  if (o_li) o_li--;  return c != EOF;}/* *	bumpword - add word to current line. */void bumpword(){  char *hc;  *holdp = '\0';/* *	Tutelman's fix #1, modified by the Colonel. */  if (!o_fi || o_ce) goto giveup;/* *	We use a while-loop in case of ridiculously long words with *	multiple hyphenation indicators. */  if (assylen + reallen(holdword) > o_ll - IDTLEN) {	if (!o_hy)		writeline(o_ad, 0);	else		while (assylen + reallen(holdword) > o_ll - IDTLEN) {/* *	Try hyphenating it. */			if (o_hc && strhas(holdword, o_hc)) {/* *	There are hyphenation marks.  Use them! */				for (hc = strend(holdword); hc >= holdword; hc--) {					if ((*hc & ~UNDERL) != o_hc)						continue;					*hc = '\0';					if (assylen + reallen(holdword) + 1 >					    o_ll - IDTLEN) {						*hc = o_hc;						continue;					}/* *	Yay - it fits! */					dehyph(holdword);					strcpy(&assyline[assylen], holdword);					strcat(assyline, "-");					assylen += strlen(holdword) + 1;					strcpy(holdword, ++hc);					break;	/* STOP LOOKING */				}	/* for *//* *	It won't fit, or we've succeeded in breaking the word. */				writeline(o_ad, 0);				if (hc < holdword) goto giveup;			} else {/* *	If no hyphenation marks, give up. *	Let somebody else implement it. */				writeline(o_ad, 0);				goto giveup;			}		}		/* while */  }giveup:/* *	remove hyphenation marks, even if hyphenation is disabled. */  if (o_hc) dehyph(holdword);  strcpy(&assyline[assylen], holdword);  assylen += strlen(holdword);  holdp = holdword;}/* *	dehyph - remove hyphenation marks. */void dehyph(s)char *s;{  char *t;  for (t = s; *s; s++)	if ((*s & ~UNDERL) != o_hc) *t++ = *s;  *t = '\0';}/* *	reallen - length of a word, excluding hyphenation marks. */int reallen(s)char *s;{  register n;  n = 0;  while (*s) n += (o_hc != (~UNDERL & *s++));  return n;}void tabulate(){  int j;  for (j = 0; j < n_ta; j++)	if (o_ta[j] - 1 > assylen + IDTLEN) {		for (; assylen + IDTLEN < o_ta[j] - 1; assylen++)			assyline[assylen] = o_tc;		return;	}  /* NO TAB STOPS REMAIN */  assyline[assylen++] = o_tc;}int readreq(){  char req[3];  int r, s;  if (skipsp()) return c != EOF;  c = suck();  if (c == EOF || c == '\n') return c != EOF;  if (c == '.') {	o_ig = 0;	do		(c = suck());	while (c != EOF && c != '\n');	if (depth) endmac();	return c != EOF;  }  if (o_ig) {	while (c != EOF && c != '\n') c = suck();	return c != EOF;  }  req[0] = c;  c = suck();  if (c == EOF || c == '\n')	req[1] = '\0';  else	req[1] = c;  req[2] = '\0';  for (r = 0; r < n_macros; r++)	if (!strcmp(macro[r].mname, req)) {		submac(r);		goto reqflsh;	}  for (r = 0; request[r]; r++)	if (!strcmp(request[r], req)) break;  if (!request[r]) {	do		(c = suck());	while (c != EOF && c != '\n');	return c != EOF;  }  switch (r) {      case 0:			/* ad */	o_ad = 1;	writebreak();	break;      case 1:			/* ar */	o_ro = 0;	break;      case 2:			/* bl */	nread(&o_bl);	writebreak();	break;      case 3:			/* bp */      case 37:			/* pa */	c = snread(&r, &s, 1);/* *	Tutelman's fix #2 - the signs were reversed! */	if (s > 0)		o_bp = page_no + r;	else if (s < 0)		o_bp = page_no - r;	else		o_bp = r;	writebreak();	if (line_no) {		endpage();		beginpage();	}	break;      case 4:			/* br */	writebreak();	break;      case 5:			/* cc */	c = cread(&o_cc);	break;      case 6:			/* ce *//* *	Fix to centering.  Set counter _after_ breaking!  --G.L.S. */	nread(&r);	writebreak();	o_ce = r;	break;      case 7:			/* de */	defmac();	break;      case 8:			/* ds */	o_ls = 2;	writebreak();	break;      case 9:			/* ef */	c = tread(efoot);	break;      case 10:			/* eh */	c = tread(ehead);	break;      case 11:			/* fi */	o_fi = 1;	writebreak();	break;      case 12:			/* fo */	c = tread(efoot);	strcpy(ofoot, efoot);	break;      case 13:			/* hc */	c = cread(&o_hc);	break;      case 14:			/* he */	c = tread(ehead);	strcpy(ohead, ehead);	break;      case 15:			/* hx */	o_hx = 1;	break;      case 16:			/* hy */	nread(&o_hy);	break;      case 17:			/* ig */	o_ig = 1;	break;      case 18:			/* in */	writebreak();	snset(&o_in);	o_ix = -1;	break;      case 19:			/* ix */	snset(&o_ix);	if (!n_outwords) o_in = o_ix;	break;      case 20:			/* li */	nread(&o_li);	break;      case 21:			/* ll */	snset(&o_ll);	break;      case 22:			/* ls */	snset(&o_ls);	break;      case 23:			/* m1 */	nread(&o_m1);	break;      case 24:			/* m2 */	nread(&o_m2);	break;      case 25:			/* m3 */	nread(&o_m3);	break;      case 26:			/* m4 */	nread(&o_m4);	break;      case 27:			/* n1 */	o_n1 = 1;	break;      case 28:			/* n2 */	nread(&o_n2);	break;      case 29:			/* na */	o_ad = 0;	writebreak();	break;      case 30:			/* ne */	nread(&r);	if (line_no + (r - 1) * o_ls + 1 > TXTLEN) {		writebreak();		endpage();		beginpage();	}	break;      case 31:			/* nf */	o_fi = 0;	writebreak();	break;      case 32:			/* ni */	snset(&o_ni);	break;      case 33:			/* nn */	snset(&o_nn);	break;      case 34:			/* nx */	do_nx();	c = '\n';		/* SO WE DON'T FLUSH THE FIRST LINE */	break;      case 35:			/* of */	c = tread(ofoot);	break;      case 36:			/* oh */	c = tread(ohead);	break;      case 38:			/* pl */	snset(&o_pl);	break;      case 39:			/* po */	snset(&o_po);	break;      case 40:			/* ro */	o_ro = 1;	break;      case 41:			/* sk */	nread(&o_sk);	break;      case 42:			/* sp */	nread(&o_sp);	writebreak();	break;      case 43:			/* ss */	writebreak();	o_ls = 1;	break;      case 44:			/* ta */	do_ta();	break;      case 45:			/* tc */	c = cread(&o_tc);	break;      case 46:			/* ti */	writebreak();	c = snread(&r, &s, 0);	if (s > 0)		o_ti = o_in + r;	else if (s < 0)		o_ti = o_in - r;	else		o_ti = r;	break;      case 47:			/* tr */	do_tr();	break;      case 48:			/* ul */	nread(&o_ul);	break;  }reqflsh:  while (c != EOF && c != '\n') c = suck();  return c != EOF;}void snset(par)int *par;{  int r, s;  c = snread(&r, &s, 0);  if (s > 0)	*par += r;  else if (s < 0)	*par -= r;  else	*par = r;}int tread(s)char *s;{  int leadbl;  leadbl = 0;  for (;;) {	c = suck();	if (c == ' ' && !leadbl) continue;	if (c == EOF || c == '\n') {		*s = '\0';		return c;	}	*s++ = c;	leadbl++;  }}void nread(i)int *i;{  int f;  f = 0;  *i = 0;  if (!skipsp()) for (;;) {		c = suck();		if (c == EOF) break;		if (isspace(c)) break;		if (isdigit(c)) {			f++;			*i = *i * 10 + c - '0';		} else			break;	}  if (!f) *i = 1;}int snread(i, s, sdef)int *i, *s, sdef;{

⌨️ 快捷键说明

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