ul.c revision 28789
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1980, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
3528454Scharnierstatic const char copyright[] =
361590Srgrimes"@(#) Copyright (c) 1980, 1993\n\
371590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381590Srgrimes#endif /* not lint */
391590Srgrimes
401590Srgrimes#ifndef lint
4128454Scharnier#if 0
421590Srgrimesstatic char sccsid[] = "@(#)ul.c	8.1 (Berkeley) 6/6/93";
4328454Scharnier#endif
4428454Scharnierstatic const char rcsid[] =
4528789Scharnier	"$Id: ul.c,v 1.4 1997/08/20 11:01:59 charnier Exp $";
461590Srgrimes#endif /* not lint */
471590Srgrimes
4828454Scharnier#include <err.h>
491590Srgrimes#include <stdio.h>
5028454Scharnier#include <stdlib.h>
5128454Scharnier#include <string.h>
5228454Scharnier#include <termcap.h>
5328454Scharnier#include <unistd.h>
541590Srgrimes
551590Srgrimes#define	IESC	'\033'
561590Srgrimes#define	SO	'\016'
571590Srgrimes#define	SI	'\017'
581590Srgrimes#define	HFWD	'9'
591590Srgrimes#define	HREV	'8'
601590Srgrimes#define	FREV	'7'
611590Srgrimes#define	MAXBUF	512
621590Srgrimes
631590Srgrimes#define	NORMAL	000
641590Srgrimes#define	ALTSET	001	/* Reverse */
651590Srgrimes#define	SUPERSC	002	/* Dim */
661590Srgrimes#define	SUBSC	004	/* Dim | Ul */
671590Srgrimes#define	UNDERL	010	/* Ul */
681590Srgrimes#define	BOLD	020	/* Bold */
691590Srgrimes
701590Srgrimesint	must_use_uc, must_overstrike;
711590Srgrimeschar	*CURS_UP, *CURS_RIGHT, *CURS_LEFT,
721590Srgrimes	*ENTER_STANDOUT, *EXIT_STANDOUT, *ENTER_UNDERLINE, *EXIT_UNDERLINE,
731590Srgrimes	*ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES;
741590Srgrimes
751590Srgrimesstruct	CHAR	{
761590Srgrimes	char	c_mode;
771590Srgrimes	char	c_char;
781590Srgrimes} ;
791590Srgrimes
801590Srgrimesstruct	CHAR	obuf[MAXBUF];
811590Srgrimesint	col, maxcol;
821590Srgrimesint	mode;
831590Srgrimesint	halfpos;
841590Srgrimesint	upln;
851590Srgrimesint	iflag;
861590Srgrimes
8728454Scharnierstatic void usage __P((void));
8828454Scharniervoid setnewmode __P((int));
8928454Scharniervoid initcap __P((void));
9028454Scharniervoid reverse __P((void));
9128454Scharnierint outchar __P((int));
9228454Scharniervoid fwd __P((void));
9328454Scharniervoid initbuf __P((void));
9428454Scharniervoid iattr __P((void));
9528454Scharniervoid overstrike __P((void));
9628454Scharniervoid flushln __P((void));
9728454Scharniervoid filter __P((FILE *));
9828454Scharniervoid outc __P((int));
9928454Scharnier
1001590Srgrimes#define	PRINT(s)	if (s == NULL) /* void */; else tputs(s, 1, outchar)
1011590Srgrimes
10228789Scharnierint
1031590Srgrimesmain(argc, argv)
1041590Srgrimes	int argc;
1051590Srgrimes	char **argv;
1061590Srgrimes{
1071590Srgrimes	int c;
1081590Srgrimes	char *termtype;
1091590Srgrimes	FILE *f;
1101590Srgrimes	char termcap[1024];
1111590Srgrimes
1121590Srgrimes	termtype = getenv("TERM");
1131590Srgrimes	if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1)))
1141590Srgrimes		termtype = "lpr";
11524360Simp	while ((c=getopt(argc, argv, "it:T:")) != -1)
1161590Srgrimes		switch(c) {
1171590Srgrimes
1181590Srgrimes		case 't':
1191590Srgrimes		case 'T': /* for nroff compatibility */
1201590Srgrimes				termtype = optarg;
1211590Srgrimes			break;
1221590Srgrimes		case 'i':
1231590Srgrimes			iflag = 1;
1241590Srgrimes			break;
1251590Srgrimes		default:
12628454Scharnier			usage();
1271590Srgrimes		}
1281590Srgrimes
1291590Srgrimes	switch(tgetent(termcap, termtype)) {
1301590Srgrimes
1311590Srgrimes	case 1:
1321590Srgrimes		break;
1331590Srgrimes
1341590Srgrimes	default:
13528454Scharnier		warnx("trouble reading termcap");
1361590Srgrimes		/* fall through to ... */
1371590Srgrimes
1381590Srgrimes	case 0:
1391590Srgrimes		/* No such terminal type - assume dumb */
1401590Srgrimes		(void)strcpy(termcap, "dumb:os:col#80:cr=^M:sf=^J:am:");
1411590Srgrimes		break;
1421590Srgrimes	}
1431590Srgrimes	initcap();
1441590Srgrimes	if (    (tgetflag("os") && ENTER_BOLD==NULL ) ||
1451590Srgrimes		(tgetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL))
1461590Srgrimes			must_overstrike = 1;
1471590Srgrimes	initbuf();
1481590Srgrimes	if (optind == argc)
1491590Srgrimes		filter(stdin);
1501590Srgrimes	else for (; optind<argc; optind++) {
1511590Srgrimes		f = fopen(argv[optind],"r");
15228454Scharnier		if (f == NULL)
15328454Scharnier			err(1, "%s", argv[optind]);
15428454Scharnier		else
1551590Srgrimes			filter(f);
1561590Srgrimes	}
1571590Srgrimes	exit(0);
1581590Srgrimes}
1591590Srgrimes
16028454Scharnierstatic void
16128454Scharnierusage()
16228454Scharnier{
16328454Scharnier	fprintf(stderr, "usage: ul [-i] [-t terminal] file...\n");
16428454Scharnier	exit(1);
16528454Scharnier}
16628454Scharnier
16728454Scharniervoid
1681590Srgrimesfilter(f)
1691590Srgrimes	FILE *f;
1701590Srgrimes{
1711590Srgrimes	register c;
1721590Srgrimes
1731590Srgrimes	while ((c = getc(f)) != EOF) switch(c) {
1741590Srgrimes
1751590Srgrimes	case '\b':
1761590Srgrimes		if (col > 0)
1771590Srgrimes			col--;
1781590Srgrimes		continue;
1791590Srgrimes
1801590Srgrimes	case '\t':
1811590Srgrimes		col = (col+8) & ~07;
1821590Srgrimes		if (col > maxcol)
1831590Srgrimes			maxcol = col;
1841590Srgrimes		continue;
1851590Srgrimes
1861590Srgrimes	case '\r':
1871590Srgrimes		col = 0;
1881590Srgrimes		continue;
1891590Srgrimes
1901590Srgrimes	case SO:
1911590Srgrimes		mode |= ALTSET;
1921590Srgrimes		continue;
1931590Srgrimes
1941590Srgrimes	case SI:
1951590Srgrimes		mode &= ~ALTSET;
1961590Srgrimes		continue;
1971590Srgrimes
1981590Srgrimes	case IESC:
1991590Srgrimes		switch (c = getc(f)) {
2001590Srgrimes
2011590Srgrimes		case HREV:
2021590Srgrimes			if (halfpos == 0) {
2031590Srgrimes				mode |= SUPERSC;
2041590Srgrimes				halfpos--;
2051590Srgrimes			} else if (halfpos > 0) {
2061590Srgrimes				mode &= ~SUBSC;
2071590Srgrimes				halfpos--;
2081590Srgrimes			} else {
2091590Srgrimes				halfpos = 0;
2101590Srgrimes				reverse();
2111590Srgrimes			}
2121590Srgrimes			continue;
2131590Srgrimes
2141590Srgrimes		case HFWD:
2151590Srgrimes			if (halfpos == 0) {
2161590Srgrimes				mode |= SUBSC;
2171590Srgrimes				halfpos++;
2181590Srgrimes			} else if (halfpos < 0) {
2191590Srgrimes				mode &= ~SUPERSC;
2201590Srgrimes				halfpos++;
2211590Srgrimes			} else {
2221590Srgrimes				halfpos = 0;
2231590Srgrimes				fwd();
2241590Srgrimes			}
2251590Srgrimes			continue;
2261590Srgrimes
2271590Srgrimes		case FREV:
2281590Srgrimes			reverse();
2291590Srgrimes			continue;
2301590Srgrimes
2311590Srgrimes		default:
23228454Scharnier			errx(1, "unknown escape sequence in input: %o, %o", IESC, c);
2331590Srgrimes		}
2341590Srgrimes		continue;
2351590Srgrimes
2361590Srgrimes	case '_':
2371590Srgrimes		if (obuf[col].c_char)
2381590Srgrimes			obuf[col].c_mode |= UNDERL | mode;
2391590Srgrimes		else
2401590Srgrimes			obuf[col].c_char = '_';
2411590Srgrimes	case ' ':
2421590Srgrimes		col++;
2431590Srgrimes		if (col > maxcol)
2441590Srgrimes			maxcol = col;
2451590Srgrimes		continue;
2461590Srgrimes
2471590Srgrimes	case '\n':
2481590Srgrimes		flushln();
2491590Srgrimes		continue;
2501590Srgrimes
2511590Srgrimes	case '\f':
2521590Srgrimes		flushln();
2531590Srgrimes		putchar('\f');
2541590Srgrimes		continue;
2551590Srgrimes
2561590Srgrimes	default:
2571590Srgrimes		if (c < ' ')	/* non printing */
2581590Srgrimes			continue;
2591590Srgrimes		if (obuf[col].c_char == '\0') {
2601590Srgrimes			obuf[col].c_char = c;
2611590Srgrimes			obuf[col].c_mode = mode;
2621590Srgrimes		} else if (obuf[col].c_char == '_') {
2631590Srgrimes			obuf[col].c_char = c;
2641590Srgrimes			obuf[col].c_mode |= UNDERL|mode;
2651590Srgrimes		} else if (obuf[col].c_char == c)
2661590Srgrimes			obuf[col].c_mode |= BOLD|mode;
2671590Srgrimes		else
2681590Srgrimes			obuf[col].c_mode = mode;
2691590Srgrimes		col++;
2701590Srgrimes		if (col > maxcol)
2711590Srgrimes			maxcol = col;
2721590Srgrimes		continue;
2731590Srgrimes	}
2741590Srgrimes	if (maxcol)
2751590Srgrimes		flushln();
2761590Srgrimes}
2771590Srgrimes
27828454Scharniervoid
2791590Srgrimesflushln()
2801590Srgrimes{
2811590Srgrimes	register lastmode;
2821590Srgrimes	register i;
2831590Srgrimes	int hadmodes = 0;
2841590Srgrimes
2851590Srgrimes	lastmode = NORMAL;
2861590Srgrimes	for (i=0; i<maxcol; i++) {
2871590Srgrimes		if (obuf[i].c_mode != lastmode) {
2881590Srgrimes			hadmodes++;
28928454Scharnier			setnewmode(obuf[i].c_mode);
2901590Srgrimes			lastmode = obuf[i].c_mode;
2911590Srgrimes		}
2921590Srgrimes		if (obuf[i].c_char == '\0') {
2931590Srgrimes			if (upln)
2941590Srgrimes				PRINT(CURS_RIGHT);
2951590Srgrimes			else
2961590Srgrimes				outc(' ');
2971590Srgrimes		} else
2981590Srgrimes			outc(obuf[i].c_char);
2991590Srgrimes	}
3001590Srgrimes	if (lastmode != NORMAL) {
30128454Scharnier		setnewmode(0);
3021590Srgrimes	}
3031590Srgrimes	if (must_overstrike && hadmodes)
3041590Srgrimes		overstrike();
3051590Srgrimes	putchar('\n');
3061590Srgrimes	if (iflag && hadmodes)
3071590Srgrimes		iattr();
3081590Srgrimes	(void)fflush(stdout);
3091590Srgrimes	if (upln)
3101590Srgrimes		upln--;
3111590Srgrimes	initbuf();
3121590Srgrimes}
3131590Srgrimes
3141590Srgrimes/*
3151590Srgrimes * For terminals that can overstrike, overstrike underlines and bolds.
3161590Srgrimes * We don't do anything with halfline ups and downs, or Greek.
3171590Srgrimes */
31828454Scharniervoid
3191590Srgrimesoverstrike()
3201590Srgrimes{
3211590Srgrimes	register int i;
3221590Srgrimes	char lbuf[256];
3231590Srgrimes	register char *cp = lbuf;
3241590Srgrimes	int hadbold=0;
3251590Srgrimes
3261590Srgrimes	/* Set up overstrike buffer */
3271590Srgrimes	for (i=0; i<maxcol; i++)
3281590Srgrimes		switch (obuf[i].c_mode) {
3291590Srgrimes		case NORMAL:
3301590Srgrimes		default:
3311590Srgrimes			*cp++ = ' ';
3321590Srgrimes			break;
3331590Srgrimes		case UNDERL:
3341590Srgrimes			*cp++ = '_';
3351590Srgrimes			break;
3361590Srgrimes		case BOLD:
3371590Srgrimes			*cp++ = obuf[i].c_char;
3381590Srgrimes			hadbold=1;
3391590Srgrimes			break;
3401590Srgrimes		}
3411590Srgrimes	putchar('\r');
3421590Srgrimes	for (*cp=' '; *cp==' '; cp--)
3431590Srgrimes		*cp = 0;
3441590Srgrimes	for (cp=lbuf; *cp; cp++)
3451590Srgrimes		putchar(*cp);
3461590Srgrimes	if (hadbold) {
3471590Srgrimes		putchar('\r');
3481590Srgrimes		for (cp=lbuf; *cp; cp++)
3491590Srgrimes			putchar(*cp=='_' ? ' ' : *cp);
3501590Srgrimes		putchar('\r');
3511590Srgrimes		for (cp=lbuf; *cp; cp++)
3521590Srgrimes			putchar(*cp=='_' ? ' ' : *cp);
3531590Srgrimes	}
3541590Srgrimes}
3551590Srgrimes
35628454Scharniervoid
3571590Srgrimesiattr()
3581590Srgrimes{
3591590Srgrimes	register int i;
3601590Srgrimes	char lbuf[256];
3611590Srgrimes	register char *cp = lbuf;
3621590Srgrimes
3631590Srgrimes	for (i=0; i<maxcol; i++)
3641590Srgrimes		switch (obuf[i].c_mode) {
3651590Srgrimes		case NORMAL:	*cp++ = ' '; break;
3661590Srgrimes		case ALTSET:	*cp++ = 'g'; break;
3671590Srgrimes		case SUPERSC:	*cp++ = '^'; break;
3681590Srgrimes		case SUBSC:	*cp++ = 'v'; break;
3691590Srgrimes		case UNDERL:	*cp++ = '_'; break;
3701590Srgrimes		case BOLD:	*cp++ = '!'; break;
3711590Srgrimes		default:	*cp++ = 'X'; break;
3721590Srgrimes		}
3731590Srgrimes	for (*cp=' '; *cp==' '; cp--)
3741590Srgrimes		*cp = 0;
3751590Srgrimes	for (cp=lbuf; *cp; cp++)
3761590Srgrimes		putchar(*cp);
3771590Srgrimes	putchar('\n');
3781590Srgrimes}
3791590Srgrimes
38028454Scharniervoid
3811590Srgrimesinitbuf()
3821590Srgrimes{
3831590Srgrimes
3841590Srgrimes	bzero((char *)obuf, sizeof (obuf));	/* depends on NORMAL == 0 */
3851590Srgrimes	col = 0;
3861590Srgrimes	maxcol = 0;
3871590Srgrimes	mode &= ALTSET;
3881590Srgrimes}
3891590Srgrimes
39028454Scharniervoid
3911590Srgrimesfwd()
3921590Srgrimes{
3931590Srgrimes	register oldcol, oldmax;
3941590Srgrimes
3951590Srgrimes	oldcol = col;
3961590Srgrimes	oldmax = maxcol;
3971590Srgrimes	flushln();
3981590Srgrimes	col = oldcol;
3991590Srgrimes	maxcol = oldmax;
4001590Srgrimes}
4011590Srgrimes
40228454Scharniervoid
4031590Srgrimesreverse()
4041590Srgrimes{
4051590Srgrimes	upln++;
4061590Srgrimes	fwd();
4071590Srgrimes	PRINT(CURS_UP);
4081590Srgrimes	PRINT(CURS_UP);
4091590Srgrimes	upln++;
4101590Srgrimes}
4111590Srgrimes
41228454Scharniervoid
4131590Srgrimesinitcap()
4141590Srgrimes{
4151590Srgrimes	static char tcapbuf[512];
4161590Srgrimes	char *bp = tcapbuf;
4171590Srgrimes
4181590Srgrimes	/* This nonsense attempts to work with both old and new termcap */
4191590Srgrimes	CURS_UP =		tgetstr("up", &bp);
4201590Srgrimes	CURS_RIGHT =		tgetstr("ri", &bp);
4211590Srgrimes	if (CURS_RIGHT == NULL)
4221590Srgrimes		CURS_RIGHT =	tgetstr("nd", &bp);
4231590Srgrimes	CURS_LEFT =		tgetstr("le", &bp);
4241590Srgrimes	if (CURS_LEFT == NULL)
4251590Srgrimes		CURS_LEFT =	tgetstr("bc", &bp);
4261590Srgrimes	if (CURS_LEFT == NULL && tgetflag("bs"))
4271590Srgrimes		CURS_LEFT =	"\b";
4281590Srgrimes
4291590Srgrimes	ENTER_STANDOUT =	tgetstr("so", &bp);
4301590Srgrimes	EXIT_STANDOUT =		tgetstr("se", &bp);
4311590Srgrimes	ENTER_UNDERLINE =	tgetstr("us", &bp);
4321590Srgrimes	EXIT_UNDERLINE =	tgetstr("ue", &bp);
4331590Srgrimes	ENTER_DIM =		tgetstr("mh", &bp);
4341590Srgrimes	ENTER_BOLD =		tgetstr("md", &bp);
4351590Srgrimes	ENTER_REVERSE =		tgetstr("mr", &bp);
4361590Srgrimes	EXIT_ATTRIBUTES =	tgetstr("me", &bp);
4371590Srgrimes
4381590Srgrimes	if (!ENTER_BOLD && ENTER_REVERSE)
4391590Srgrimes		ENTER_BOLD = ENTER_REVERSE;
4401590Srgrimes	if (!ENTER_BOLD && ENTER_STANDOUT)
4411590Srgrimes		ENTER_BOLD = ENTER_STANDOUT;
4421590Srgrimes	if (!ENTER_UNDERLINE && ENTER_STANDOUT) {
4431590Srgrimes		ENTER_UNDERLINE = ENTER_STANDOUT;
4441590Srgrimes		EXIT_UNDERLINE = EXIT_STANDOUT;
4451590Srgrimes	}
4461590Srgrimes	if (!ENTER_DIM && ENTER_STANDOUT)
4471590Srgrimes		ENTER_DIM = ENTER_STANDOUT;
4481590Srgrimes	if (!ENTER_REVERSE && ENTER_STANDOUT)
4491590Srgrimes		ENTER_REVERSE = ENTER_STANDOUT;
4501590Srgrimes	if (!EXIT_ATTRIBUTES && EXIT_STANDOUT)
4511590Srgrimes		EXIT_ATTRIBUTES = EXIT_STANDOUT;
4528874Srgrimes
4531590Srgrimes	/*
4541590Srgrimes	 * Note that we use REVERSE for the alternate character set,
4551590Srgrimes	 * not the as/ae capabilities.  This is because we are modelling
4561590Srgrimes	 * the model 37 teletype (since that's what nroff outputs) and
4571590Srgrimes	 * the typical as/ae is more of a graphics set, not the greek
4581590Srgrimes	 * letters the 37 has.
4591590Srgrimes	 */
4601590Srgrimes
4611590Srgrimes	UNDER_CHAR =		tgetstr("uc", &bp);
4621590Srgrimes	must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE);
4631590Srgrimes}
4641590Srgrimes
46528454Scharnierint
4661590Srgrimesoutchar(c)
4671590Srgrimes	int c;
4681590Srgrimes{
46928454Scharnier	return(putchar(c & 0177));
4701590Srgrimes}
4711590Srgrimes
4721590Srgrimesstatic int curmode = 0;
4731590Srgrimes
47428454Scharniervoid
4751590Srgrimesoutc(c)
4761590Srgrimes	int c;
4771590Srgrimes{
4781590Srgrimes	putchar(c);
4791590Srgrimes	if (must_use_uc && (curmode&UNDERL)) {
4801590Srgrimes		PRINT(CURS_LEFT);
4811590Srgrimes		PRINT(UNDER_CHAR);
4821590Srgrimes	}
4831590Srgrimes}
4841590Srgrimes
48528454Scharniervoid
48628454Scharniersetnewmode(newmode)
4871590Srgrimes	int newmode;
4881590Srgrimes{
4891590Srgrimes	if (!iflag) {
4901590Srgrimes		if (curmode != NORMAL && newmode != NORMAL)
49128454Scharnier			setnewmode(NORMAL);
4921590Srgrimes		switch (newmode) {
4931590Srgrimes		case NORMAL:
4941590Srgrimes			switch(curmode) {
4951590Srgrimes			case NORMAL:
4961590Srgrimes				break;
4971590Srgrimes			case UNDERL:
4981590Srgrimes				PRINT(EXIT_UNDERLINE);
4991590Srgrimes				break;
5001590Srgrimes			default:
5011590Srgrimes				/* This includes standout */
5021590Srgrimes				PRINT(EXIT_ATTRIBUTES);
5031590Srgrimes				break;
5041590Srgrimes			}
5051590Srgrimes			break;
5061590Srgrimes		case ALTSET:
5071590Srgrimes			PRINT(ENTER_REVERSE);
5081590Srgrimes			break;
5091590Srgrimes		case SUPERSC:
5101590Srgrimes			/*
5111590Srgrimes			 * This only works on a few terminals.
5121590Srgrimes			 * It should be fixed.
5131590Srgrimes			 */
5141590Srgrimes			PRINT(ENTER_UNDERLINE);
5151590Srgrimes			PRINT(ENTER_DIM);
5161590Srgrimes			break;
5171590Srgrimes		case SUBSC:
5181590Srgrimes			PRINT(ENTER_DIM);
5191590Srgrimes			break;
5201590Srgrimes		case UNDERL:
5211590Srgrimes			PRINT(ENTER_UNDERLINE);
5221590Srgrimes			break;
5231590Srgrimes		case BOLD:
5241590Srgrimes			PRINT(ENTER_BOLD);
5251590Srgrimes			break;
5261590Srgrimes		default:
5271590Srgrimes			/*
5281590Srgrimes			 * We should have some provision here for multiple modes
5291590Srgrimes			 * on at once.  This will have to come later.
5301590Srgrimes			 */
5311590Srgrimes			PRINT(ENTER_STANDOUT);
5321590Srgrimes			break;
5331590Srgrimes		}
5341590Srgrimes	}
5351590Srgrimes	curmode = newmode;
5361590Srgrimes}
537