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

📄 ul.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1980, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1980, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)ul.c	8.1 (Berkeley) 6/6/93";#endif /* not lint */#include <stdio.h>#define	IESC	'\033'#define	SO	'\016'#define	SI	'\017'#define	HFWD	'9'#define	HREV	'8'#define	FREV	'7'#define	MAXBUF	512#define	NORMAL	000#define	ALTSET	001	/* Reverse */#define	SUPERSC	002	/* Dim */#define	SUBSC	004	/* Dim | Ul */#define	UNDERL	010	/* Ul */#define	BOLD	020	/* Bold */int	must_use_uc, must_overstrike;char	*CURS_UP, *CURS_RIGHT, *CURS_LEFT,	*ENTER_STANDOUT, *EXIT_STANDOUT, *ENTER_UNDERLINE, *EXIT_UNDERLINE,	*ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES;struct	CHAR	{	char	c_mode;	char	c_char;} ;struct	CHAR	obuf[MAXBUF];int	col, maxcol;int	mode;int	halfpos;int	upln;int	iflag;int	outchar();#define	PRINT(s)	if (s == NULL) /* void */; else tputs(s, 1, outchar)main(argc, argv)	int argc;	char **argv;{	extern int optind;	extern char *optarg;	int c;	char *termtype;	FILE *f;	char termcap[1024];	char *getenv(), *strcpy();	termtype = getenv("TERM");	if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1)))		termtype = "lpr";	while ((c=getopt(argc, argv, "it:T:")) != EOF)		switch(c) {		case 't':		case 'T': /* for nroff compatibility */				termtype = optarg;			break;		case 'i':			iflag = 1;			break;		default:			fprintf(stderr,				"usage: %s [ -i ] [ -tTerm ] file...\n",				argv[0]);			exit(1);		}	switch(tgetent(termcap, termtype)) {	case 1:		break;	default:		fprintf(stderr,"trouble reading termcap");		/* fall through to ... */	case 0:		/* No such terminal type - assume dumb */		(void)strcpy(termcap, "dumb:os:col#80:cr=^M:sf=^J:am:");		break;	}	initcap();	if (    (tgetflag("os") && ENTER_BOLD==NULL ) ||		(tgetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))			must_overstrike = 1;	initbuf();	if (optind == argc)		filter(stdin);	else for (; optind<argc; optind++) {		f = fopen(argv[optind],"r");		if (f == NULL) {			perror(argv[optind]);			exit(1);		} else			filter(f);	}	exit(0);}filter(f)	FILE *f;{	register c;	while ((c = getc(f)) != EOF) switch(c) {	case '\b':		if (col > 0)			col--;		continue;	case '\t':		col = (col+8) & ~07;		if (col > maxcol)			maxcol = col;		continue;	case '\r':		col = 0;		continue;	case SO:		mode |= ALTSET;		continue;	case SI:		mode &= ~ALTSET;		continue;	case IESC:		switch (c = getc(f)) {		case HREV:			if (halfpos == 0) {				mode |= SUPERSC;				halfpos--;			} else if (halfpos > 0) {				mode &= ~SUBSC;				halfpos--;			} else {				halfpos = 0;				reverse();			}			continue;		case HFWD:			if (halfpos == 0) {				mode |= SUBSC;				halfpos++;			} else if (halfpos < 0) {				mode &= ~SUPERSC;				halfpos++;			} else {				halfpos = 0;				fwd();			}			continue;		case FREV:			reverse();			continue;		default:			fprintf(stderr,				"Unknown escape sequence in input: %o, %o\n",				IESC, c);			exit(1);		}		continue;	case '_':		if (obuf[col].c_char)			obuf[col].c_mode |= UNDERL | mode;		else			obuf[col].c_char = '_';	case ' ':		col++;		if (col > maxcol)			maxcol = col;		continue;	case '\n':		flushln();		continue;	case '\f':		flushln();		putchar('\f');		continue;	default:		if (c < ' ')	/* non printing */			continue;		if (obuf[col].c_char == '\0') {			obuf[col].c_char = c;			obuf[col].c_mode = mode;		} else if (obuf[col].c_char == '_') {			obuf[col].c_char = c;			obuf[col].c_mode |= UNDERL|mode;		} else if (obuf[col].c_char == c)			obuf[col].c_mode |= BOLD|mode;		else			obuf[col].c_mode = mode;		col++;		if (col > maxcol)			maxcol = col;		continue;	}	if (maxcol)		flushln();}flushln(){	register lastmode;	register i;	int hadmodes = 0;	lastmode = NORMAL;	for (i=0; i<maxcol; i++) {		if (obuf[i].c_mode != lastmode) {			hadmodes++;			setmode(obuf[i].c_mode);			lastmode = obuf[i].c_mode;		}		if (obuf[i].c_char == '\0') {			if (upln)				PRINT(CURS_RIGHT);			else				outc(' ');		} else			outc(obuf[i].c_char);	}	if (lastmode != NORMAL) {		setmode(0);	}	if (must_overstrike && hadmodes)		overstrike();	putchar('\n');	if (iflag && hadmodes)		iattr();	(void)fflush(stdout);	if (upln)		upln--;	initbuf();}/* * For terminals that can overstrike, overstrike underlines and bolds. * We don't do anything with halfline ups and downs, or Greek. */overstrike(){	register int i;	char lbuf[256];	register char *cp = lbuf;	int hadbold=0;	/* Set up overstrike buffer */	for (i=0; i<maxcol; i++)		switch (obuf[i].c_mode) {		case NORMAL:		default:			*cp++ = ' ';			break;		case UNDERL:			*cp++ = '_';			break;		case BOLD:			*cp++ = obuf[i].c_char;			hadbold=1;			break;		}	putchar('\r');	for (*cp=' '; *cp==' '; cp--)		*cp = 0;	for (cp=lbuf; *cp; cp++)		putchar(*cp);	if (hadbold) {		putchar('\r');		for (cp=lbuf; *cp; cp++)			putchar(*cp=='_' ? ' ' : *cp);		putchar('\r');		for (cp=lbuf; *cp; cp++)			putchar(*cp=='_' ? ' ' : *cp);	}}iattr(){	register int i;	char lbuf[256];	register char *cp = lbuf;	for (i=0; i<maxcol; i++)		switch (obuf[i].c_mode) {		case NORMAL:	*cp++ = ' '; break;		case ALTSET:	*cp++ = 'g'; break;		case SUPERSC:	*cp++ = '^'; break;		case SUBSC:	*cp++ = 'v'; break;		case UNDERL:	*cp++ = '_'; break;		case BOLD:	*cp++ = '!'; break;		default:	*cp++ = 'X'; break;		}	for (*cp=' '; *cp==' '; cp--)		*cp = 0;	for (cp=lbuf; *cp; cp++)		putchar(*cp);	putchar('\n');}initbuf(){	bzero((char *)obuf, sizeof (obuf));	/* depends on NORMAL == 0 */	col = 0;	maxcol = 0;	mode &= ALTSET;}fwd(){	register oldcol, oldmax;	oldcol = col;	oldmax = maxcol;	flushln();	col = oldcol;	maxcol = oldmax;}reverse(){	upln++;	fwd();	PRINT(CURS_UP);	PRINT(CURS_UP);	upln++;}initcap(){	static char tcapbuf[512];	char *bp = tcapbuf;	char *getenv(), *tgetstr();	/* This nonsense attempts to work with both old and new termcap */	CURS_UP =		tgetstr("up", &bp);	CURS_RIGHT =		tgetstr("ri", &bp);	if (CURS_RIGHT == NULL)		CURS_RIGHT =	tgetstr("nd", &bp);	CURS_LEFT =		tgetstr("le", &bp);	if (CURS_LEFT == NULL)		CURS_LEFT =	tgetstr("bc", &bp);	if (CURS_LEFT == NULL && tgetflag("bs"))		CURS_LEFT =	"\b";	ENTER_STANDOUT =	tgetstr("so", &bp);	EXIT_STANDOUT =		tgetstr("se", &bp);	ENTER_UNDERLINE =	tgetstr("us", &bp);	EXIT_UNDERLINE =	tgetstr("ue", &bp);	ENTER_DIM =		tgetstr("mh", &bp);	ENTER_BOLD =		tgetstr("md", &bp);	ENTER_REVERSE =		tgetstr("mr", &bp);	EXIT_ATTRIBUTES =	tgetstr("me", &bp);	if (!ENTER_BOLD && ENTER_REVERSE)		ENTER_BOLD = ENTER_REVERSE;	if (!ENTER_BOLD && ENTER_STANDOUT)		ENTER_BOLD = ENTER_STANDOUT;	if (!ENTER_UNDERLINE && ENTER_STANDOUT) {		ENTER_UNDERLINE = ENTER_STANDOUT;		EXIT_UNDERLINE = EXIT_STANDOUT;	}	if (!ENTER_DIM && ENTER_STANDOUT)		ENTER_DIM = ENTER_STANDOUT;	if (!ENTER_REVERSE && ENTER_STANDOUT)		ENTER_REVERSE = ENTER_STANDOUT;	if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)		EXIT_ATTRIBUTES = EXIT_STANDOUT;		/*	 * Note that we use REVERSE for the alternate character set,	 * not the as/ae capabilities.  This is because we are modelling	 * the model 37 teletype (since that's what nroff outputs) and	 * the typical as/ae is more of a graphics set, not the greek	 * letters the 37 has.	 */	UNDER_CHAR =		tgetstr("uc", &bp);	must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE);}outchar(c)	int c;{	putchar(c & 0177);}static int curmode = 0;outc(c)	int c;{	putchar(c);	if (must_use_uc && (curmode&UNDERL)) {		PRINT(CURS_LEFT);		PRINT(UNDER_CHAR);	}}setmode(newmode)	int newmode;{	if (!iflag) {		if (curmode != NORMAL && newmode != NORMAL)			setmode(NORMAL);		switch (newmode) {		case NORMAL:			switch(curmode) {			case NORMAL:				break;			case UNDERL:				PRINT(EXIT_UNDERLINE);				break;			default:				/* This includes standout */				PRINT(EXIT_ATTRIBUTES);				break;			}			break;		case ALTSET:			PRINT(ENTER_REVERSE);			break;		case SUPERSC:			/*			 * This only works on a few terminals.			 * It should be fixed.			 */			PRINT(ENTER_UNDERLINE);			PRINT(ENTER_DIM);			break;		case SUBSC:			PRINT(ENTER_DIM);			break;		case UNDERL:			PRINT(ENTER_UNDERLINE);			break;		case BOLD:			PRINT(ENTER_BOLD);			break;		default:			/*			 * We should have some provision here for multiple modes			 * on at once.  This will have to come later.			 */			PRINT(ENTER_STANDOUT);			break;		}	}	curmode = newmode;}

⌨️ 快捷键说明

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