ul.c revision 200462
1231990Smp/* 259243Sobrien * Copyright (c) 1980, 1993 359243Sobrien * The Regents of the University of California. All rights reserved. 459243Sobrien * 559243Sobrien * Redistribution and use in source and binary forms, with or without 659243Sobrien * modification, are permitted provided that the following conditions 759243Sobrien * are met: 859243Sobrien * 1. Redistributions of source code must retain the above copyright 959243Sobrien * notice, this list of conditions and the following disclaimer. 1059243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1159243Sobrien * notice, this list of conditions and the following disclaimer in the 1259243Sobrien * documentation and/or other materials provided with the distribution. 1359243Sobrien * 3. All advertising materials mentioning features or use of this software 1459243Sobrien * must display the following acknowledgement: 1559243Sobrien * This product includes software developed by the University of 1659243Sobrien * California, Berkeley and its contributors. 17100616Smp * 4. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien 3459243Sobrien#ifndef lint 35231990Smpstatic const char copyright[] = 3659243Sobrien"@(#) Copyright (c) 1980, 1993\n\ 3759243Sobrien The Regents of the University of California. All rights reserved.\n"; 3859243Sobrien#endif /* not lint */ 3959243Sobrien 4059243Sobrien#ifndef lint 4159243Sobrien#if 0 4259243Sobrienstatic char sccsid[] = "@(#)ul.c 8.1 (Berkeley) 6/6/93"; 4359243Sobrien#endif 4459243Sobrienstatic const char rcsid[] = 4559243Sobrien "$FreeBSD: head/usr.bin/ul/ul.c 200462 2009-12-13 03:14:06Z delphij $"; 4659243Sobrien#endif /* not lint */ 4759243Sobrien 4859243Sobrien#include <err.h> 4959243Sobrien#include <locale.h> 5059243Sobrien#include <stdio.h> 51145479Smp#include <stdlib.h> 52145479Smp#include <string.h> 5359243Sobrien#include <termcap.h> 5459243Sobrien#include <unistd.h> 55167465Smp#include <wchar.h> 5659243Sobrien#include <wctype.h> 5759243Sobrien 5859243Sobrien#define IESC '\033' 5959243Sobrien#define SO '\016' 6059243Sobrien#define SI '\017' 6159243Sobrien#define HFWD '9' 6259243Sobrien#define HREV '8' 6359243Sobrien#define FREV '7' 6459243Sobrien#define MAXBUF 512 6559243Sobrien 6659243Sobrien#define NORMAL 000 6759243Sobrien#define ALTSET 001 /* Reverse */ 6859243Sobrien#define SUPERSC 002 /* Dim */ 6959243Sobrien#define SUBSC 004 /* Dim | Ul */ 7059243Sobrien#define UNDERL 010 /* Ul */ 7159243Sobrien#define BOLD 020 /* Bold */ 7259243Sobrien 7359243Sobrienint must_use_uc, must_overstrike; 7459243Sobrienconst char 7559243Sobrien *CURS_UP, *CURS_RIGHT, *CURS_LEFT, 7659243Sobrien *ENTER_STANDOUT, *EXIT_STANDOUT, *ENTER_UNDERLINE, *EXIT_UNDERLINE, 7759243Sobrien *ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES; 7859243Sobrien 7959243Sobrienstruct CHAR { 8059243Sobrien char c_mode; 8159243Sobrien wchar_t c_char; 8259243Sobrien int c_width; /* width or -1 if multi-column char. filler */ 8359243Sobrien} ; 8459243Sobrien 8559243Sobrienstruct CHAR obuf[MAXBUF]; 8659243Sobrienint col, maxcol; 8759243Sobrienint mode; 8859243Sobrienint halfpos; 8959243Sobrienint upln; 9059243Sobrienint iflag; 9159243Sobrien 9259243Sobrienstatic void usage(void); 9359243Sobrienvoid setnewmode(int); 9459243Sobrienvoid initcap(void); 9559243Sobrienvoid reverse(void); 9659243Sobrienint outchar(int); 9759243Sobrienvoid fwd(void); 9859243Sobrienvoid initbuf(void); 9959243Sobrienvoid iattr(void); 10059243Sobrienvoid overstrike(void); 10159243Sobrienvoid flushln(void); 10259243Sobrienvoid filter(FILE *); 10359243Sobrienvoid outc(wint_t, int); 10459243Sobrien 10559243Sobrien#define PRINT(s) if (s == NULL) /* void */; else tputs(s, 1, outchar) 10659243Sobrien 10759243Sobrienint 10859243Sobrienmain(int argc, char **argv) 10959243Sobrien{ 11059243Sobrien int c; 111167465Smp const char *termtype; 11259243Sobrien FILE *f; 113167465Smp char termcap[1024]; 114145479Smp 11559243Sobrien setlocale(LC_ALL, ""); 116167465Smp 11759243Sobrien termtype = getenv("TERM"); 11859243Sobrien if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1))) 11959243Sobrien termtype = "lpr"; 12059243Sobrien while ((c=getopt(argc, argv, "it:T:")) != -1) 12159243Sobrien switch(c) { 12259243Sobrien 12359243Sobrien case 't': 12459243Sobrien case 'T': /* for nroff compatibility */ 12559243Sobrien termtype = optarg; 12659243Sobrien break; 12759243Sobrien case 'i': 12859243Sobrien iflag = 1; 12959243Sobrien break; 13059243Sobrien default: 13159243Sobrien usage(); 13259243Sobrien } 13359243Sobrien 13459243Sobrien switch(tgetent(termcap, termtype)) { 13559243Sobrien 13659243Sobrien case 1: 13759243Sobrien break; 13859243Sobrien 13959243Sobrien default: 14059243Sobrien warnx("trouble reading termcap"); 14159243Sobrien /* FALLTHROUGH */ 14259243Sobrien 14359243Sobrien case 0: 144167465Smp /* No such terminal type - assume dumb */ 145167465Smp (void)strcpy(termcap, "dumb:os:col#80:cr=^M:sf=^J:am:"); 146167465Smp break; 14759243Sobrien } 148167465Smp initcap(); 149145479Smp if ( (tgetflag("os") && ENTER_BOLD==NULL ) || 15059243Sobrien (tgetflag("ul") && ENTER_UNDERLINE==NULL && UNDER_CHAR==NULL)) 15159243Sobrien must_overstrike = 1; 15259243Sobrien initbuf(); 15359243Sobrien if (optind == argc) 154167465Smp filter(stdin); 155167465Smp else for (; optind<argc; optind++) { 15659243Sobrien f = fopen(argv[optind],"r"); 15759243Sobrien if (f == NULL) 158167465Smp err(1, "%s", argv[optind]); 15959243Sobrien else 160167465Smp filter(f); 161167465Smp } 162145479Smp exit(0); 16359243Sobrien} 16459243Sobrien 16559243Sobrienstatic void 16659243Sobrienusage(void) 16759243Sobrien{ 16859243Sobrien fprintf(stderr, "usage: ul [-i] [-t terminal] [file ...]\n"); 16959243Sobrien exit(1); 170167465Smp} 171167465Smp 17259243Sobrienvoid 173167465Smpfilter(FILE *f) 174167465Smp{ 175167465Smp wint_t c; 176167465Smp int i, w; 177167465Smp 178167465Smp while ((c = getwc(f)) != WEOF && col < MAXBUF) switch(c) { 179167465Smp 180167465Smp case '\b': 181167465Smp if (col > 0) 182167465Smp col--; 183167465Smp continue; 184167465Smp 18559243Sobrien case '\t': 18659243Sobrien col = (col+8) & ~07; 18759243Sobrien if (col > maxcol) 188167465Smp maxcol = col; 18959243Sobrien continue; 190167465Smp 19159243Sobrien case '\r': 19259243Sobrien col = 0; 19359243Sobrien continue; 19459243Sobrien 19559243Sobrien case SO: 196167465Smp mode |= ALTSET; 197100616Smp continue; 198167465Smp 19959243Sobrien case SI: 200167465Smp mode &= ~ALTSET; 20159243Sobrien continue; 20259243Sobrien 20359243Sobrien case IESC: 20459243Sobrien switch (c = getwc(f)) { 20559243Sobrien 206145479Smp case HREV: 207167465Smp if (halfpos == 0) { 208167465Smp mode |= SUPERSC; 209167465Smp halfpos--; 210167465Smp } else if (halfpos > 0) { 211167465Smp mode &= ~SUBSC; 212167465Smp halfpos--; 213167465Smp } else { 21459243Sobrien halfpos = 0; 21559243Sobrien reverse(); 216231990Smp } 217231990Smp continue; 218231990Smp 21959243Sobrien case HFWD: 22059243Sobrien if (halfpos == 0) { 22159243Sobrien mode |= SUBSC; 22259243Sobrien halfpos++; 22359243Sobrien } else if (halfpos < 0) { 224167465Smp mode &= ~SUPERSC; 22559243Sobrien halfpos++; 22659243Sobrien } else { 227167465Smp halfpos = 0; 22859243Sobrien fwd(); 22959243Sobrien } 230167465Smp continue; 23159243Sobrien 23259243Sobrien case FREV: 233167465Smp reverse(); 234167465Smp continue; 23559243Sobrien 23659243Sobrien default: 23759243Sobrien errx(1, "unknown escape sequence in input: %o, %o", IESC, c); 23859243Sobrien } 23959243Sobrien continue; 24059243Sobrien 24159243Sobrien case '_': 24259243Sobrien if (obuf[col].c_char || obuf[col].c_width < 0) { 24359243Sobrien while (col > 0 && obuf[col].c_width < 0) 24459243Sobrien col--; 24559243Sobrien w = obuf[col].c_width; 24659243Sobrien for (i = 0; i < w; i++) 24759243Sobrien obuf[col++].c_mode |= UNDERL | mode; 24859243Sobrien if (col > maxcol) 24959243Sobrien maxcol = col; 25059243Sobrien continue; 25159243Sobrien } 25259243Sobrien obuf[col].c_char = '_'; 25359243Sobrien obuf[col].c_width = 1; 25459243Sobrien /* FALLTHROUGH */ 25559243Sobrien case ' ': 25659243Sobrien col++; 25759243Sobrien if (col > maxcol) 25859243Sobrien maxcol = col; 25959243Sobrien continue; 26059243Sobrien 26159243Sobrien case '\n': 262167465Smp flushln(); 263167465Smp continue; 264167465Smp 265167465Smp case '\f': 266167465Smp flushln(); 267167465Smp putwchar('\f'); 268167465Smp continue; 269167465Smp 270167465Smp default: 271167465Smp if ((w = wcwidth(c)) <= 0) /* non printing */ 272167465Smp continue; 27359243Sobrien if (obuf[col].c_char == '\0') { 274167465Smp obuf[col].c_char = c; 275167465Smp for (i = 0; i < w; i++) 276167465Smp obuf[col + i].c_mode = mode; 277167465Smp obuf[col].c_width = w; 27859243Sobrien for (i = 1; i < w; i++) 27959243Sobrien obuf[col + i].c_width = -1; 280167465Smp } else if (obuf[col].c_char == '_') { 281167465Smp obuf[col].c_char = c; 28259243Sobrien for (i = 0; i < w; i++) 28359243Sobrien obuf[col + i].c_mode |= UNDERL|mode; 28459243Sobrien obuf[col].c_width = w; 285167465Smp for (i = 1; i < w; i++) 28659243Sobrien obuf[col + i].c_width = -1; 287167465Smp } else if (obuf[col].c_char == c) { 288167465Smp for (i = 0; i < w; i++) 28959243Sobrien obuf[col + i].c_mode |= BOLD|mode; 29059243Sobrien } else { 29159243Sobrien w = obuf[col].c_width; 29259243Sobrien for (i = 0; i < w; i++) 29359243Sobrien obuf[col + i].c_mode = mode; 29459243Sobrien } 29559243Sobrien col += w; 29659243Sobrien if (col > maxcol) 297167465Smp maxcol = col; 29859243Sobrien continue; 29959243Sobrien } 300167465Smp if (ferror(f)) 30159243Sobrien err(1, NULL); 30259243Sobrien if (maxcol) 30359243Sobrien flushln(); 30459243Sobrien} 30559243Sobrien 306167465Smpvoid 307167465Smpflushln(void) 308167465Smp{ 30959243Sobrien int lastmode; 31059243Sobrien int i; 311167465Smp int hadmodes = 0; 312167465Smp 31359243Sobrien lastmode = NORMAL; 31459243Sobrien for (i=0; i<maxcol; i++) { 315167465Smp if (obuf[i].c_mode != lastmode) { 316167465Smp hadmodes++; 31759243Sobrien setnewmode(obuf[i].c_mode); 318167465Smp lastmode = obuf[i].c_mode; 31959243Sobrien } 32059243Sobrien if (obuf[i].c_char == '\0') { 321167465Smp if (upln) 322167465Smp PRINT(CURS_RIGHT); 323167465Smp else 324167465Smp outc(' ', 1); 325167465Smp } else 326145479Smp outc(obuf[i].c_char, obuf[i].c_width); 327167465Smp if (obuf[i].c_width > 1) 328167465Smp i += obuf[i].c_width - 1; 32959243Sobrien } 330167465Smp if (lastmode != NORMAL) { 33159243Sobrien setnewmode(0); 33259243Sobrien } 33359243Sobrien if (must_overstrike && hadmodes) 33459243Sobrien overstrike(); 33559243Sobrien putwchar('\n'); 33659243Sobrien if (iflag && hadmodes) 33759243Sobrien iattr(); 33859243Sobrien (void)fflush(stdout); 33959243Sobrien if (upln) 34059243Sobrien upln--; 34159243Sobrien initbuf(); 34259243Sobrien} 34359243Sobrien 34459243Sobrien/* 34559243Sobrien * For terminals that can overstrike, overstrike underlines and bolds. 346167465Smp * We don't do anything with halfline ups and downs, or Greek. 347167465Smp */ 34859243Sobrienvoid 34959243Sobrienoverstrike(void) 35059243Sobrien{ 35159243Sobrien int i; 35259243Sobrien wchar_t lbuf[256]; 35359243Sobrien wchar_t *cp = lbuf; 35459243Sobrien int hadbold=0; 35559243Sobrien 35659243Sobrien /* Set up overstrike buffer */ 35759243Sobrien for (i=0; i<maxcol; i++) 35859243Sobrien switch (obuf[i].c_mode) { 35959243Sobrien case NORMAL: 36069408Sache default: 361145479Smp *cp++ = ' '; 36259243Sobrien break; 363167465Smp case UNDERL: 364167465Smp *cp++ = '_'; 36559243Sobrien break; 366167465Smp case BOLD: 367167465Smp *cp++ = obuf[i].c_char; 368167465Smp if (obuf[i].c_width > 1) 369167465Smp i += obuf[i].c_width - 1; 370167465Smp hadbold=1; 371167465Smp break; 372167465Smp } 37369408Sache putwchar('\r'); 37459243Sobrien for (*cp=' '; *cp==' '; cp--) 37559243Sobrien *cp = 0; 37659243Sobrien for (cp=lbuf; *cp; cp++) 37759243Sobrien putwchar(*cp); 378145479Smp if (hadbold) { 379145479Smp putwchar('\r'); 380145479Smp for (cp=lbuf; *cp; cp++) 381145479Smp putwchar(*cp=='_' ? ' ' : *cp); 382145479Smp putwchar('\r'); 383145479Smp for (cp=lbuf; *cp; cp++) 384145479Smp putwchar(*cp=='_' ? ' ' : *cp); 385145479Smp } 386145479Smp} 387145479Smp 388167465Smpvoid 389145479Smpiattr(void) 39059243Sobrien{ 39159243Sobrien int i; 39259243Sobrien wchar_t lbuf[256]; 39359243Sobrien wchar_t *cp = lbuf; 39459243Sobrien 39559243Sobrien for (i=0; i<maxcol; i++) 39659243Sobrien switch (obuf[i].c_mode) { 39759243Sobrien case NORMAL: *cp++ = ' '; break; 39859243Sobrien case ALTSET: *cp++ = 'g'; break; 39959243Sobrien case SUPERSC: *cp++ = '^'; break; 40059243Sobrien case SUBSC: *cp++ = 'v'; break; 40159243Sobrien case UNDERL: *cp++ = '_'; break; 40259243Sobrien case BOLD: *cp++ = '!'; break; 40359243Sobrien default: *cp++ = 'X'; break; 40459243Sobrien } 40559243Sobrien for (*cp=' '; *cp==' '; cp--) 40659243Sobrien *cp = 0; 40759243Sobrien for (cp=lbuf; *cp; cp++) 40859243Sobrien putwchar(*cp); 40959243Sobrien putwchar('\n'); 41059243Sobrien} 41159243Sobrien 41259243Sobrienvoid 41359243Sobrieninitbuf(void) 41459243Sobrien{ 41559243Sobrien 41659243Sobrien bzero((char *)obuf, sizeof (obuf)); /* depends on NORMAL == 0 */ 41759243Sobrien col = 0; 418167465Smp maxcol = 0; 419167465Smp mode &= ALTSET; 420167465Smp} 42159243Sobrien 42259243Sobrienvoid 42359243Sobrienfwd(void) 42459243Sobrien{ 42559243Sobrien int oldcol, oldmax; 42659243Sobrien 427167465Smp oldcol = col; 428167465Smp oldmax = maxcol; 429167465Smp flushln(); 43059243Sobrien col = oldcol; 431167465Smp maxcol = oldmax; 432167465Smp} 43359243Sobrien 434167465Smpvoid 435167465Smpreverse(void) 43659243Sobrien{ 437167465Smp upln++; 438167465Smp fwd(); 43959243Sobrien PRINT(CURS_UP); 44059243Sobrien PRINT(CURS_UP); 441167465Smp upln++; 442167465Smp} 443167465Smp 44459243Sobrienvoid 44559243Sobrieninitcap(void) 44659243Sobrien{ 44759243Sobrien static char tcapbuf[512]; 44859243Sobrien char *bp = tcapbuf; 44959243Sobrien 450167465Smp /* This nonsense attempts to work with both old and new termcap */ 451167465Smp CURS_UP = tgetstr("up", &bp); 452167465Smp CURS_RIGHT = tgetstr("ri", &bp); 45359243Sobrien if (CURS_RIGHT == NULL) 45459243Sobrien CURS_RIGHT = tgetstr("nd", &bp); 45559243Sobrien CURS_LEFT = tgetstr("le", &bp); 45659243Sobrien if (CURS_LEFT == NULL) 45759243Sobrien CURS_LEFT = tgetstr("bc", &bp); 458167465Smp if (CURS_LEFT == NULL && tgetflag("bs")) 459167465Smp CURS_LEFT = "\b"; 46059243Sobrien 46159243Sobrien ENTER_STANDOUT = tgetstr("so", &bp); 462231990Smp EXIT_STANDOUT = tgetstr("se", &bp); 463231990Smp ENTER_UNDERLINE = tgetstr("us", &bp); 464231990Smp EXIT_UNDERLINE = tgetstr("ue", &bp); 465231990Smp ENTER_DIM = tgetstr("mh", &bp); 466231990Smp ENTER_BOLD = tgetstr("md", &bp); 46759243Sobrien ENTER_REVERSE = tgetstr("mr", &bp); 46859243Sobrien EXIT_ATTRIBUTES = tgetstr("me", &bp); 46959243Sobrien 470167465Smp if (!ENTER_BOLD && ENTER_REVERSE) 471167465Smp ENTER_BOLD = ENTER_REVERSE; 472167465Smp if (!ENTER_BOLD && ENTER_STANDOUT) 47359243Sobrien ENTER_BOLD = ENTER_STANDOUT; 47459243Sobrien if (!ENTER_UNDERLINE && ENTER_STANDOUT) { 47559243Sobrien ENTER_UNDERLINE = ENTER_STANDOUT; 47659243Sobrien EXIT_UNDERLINE = EXIT_STANDOUT; 47759243Sobrien } 478167465Smp if (!ENTER_DIM && ENTER_STANDOUT) 479167465Smp ENTER_DIM = ENTER_STANDOUT; 48059243Sobrien if (!ENTER_REVERSE && ENTER_STANDOUT) 48159243Sobrien ENTER_REVERSE = ENTER_STANDOUT; 48259243Sobrien if (!EXIT_ATTRIBUTES && EXIT_STANDOUT) 483167465Smp EXIT_ATTRIBUTES = EXIT_STANDOUT; 48459243Sobrien 48559243Sobrien /* 486167465Smp * Note that we use REVERSE for the alternate character set, 487167465Smp * not the as/ae capabilities. This is because we are modelling 488167465Smp * the model 37 teletype (since that's what nroff outputs) and 48959243Sobrien * the typical as/ae is more of a graphics set, not the greek 49059243Sobrien * letters the 37 has. 491167465Smp */ 49259243Sobrien 49359243Sobrien UNDER_CHAR = tgetstr("uc", &bp); 494167465Smp must_use_uc = (UNDER_CHAR && !ENTER_UNDERLINE); 495167465Smp} 496167465Smp 49759243Sobrienint 49859243Sobrienoutchar(int c) 499167465Smp{ 500167465Smp return (putwchar(c) != WEOF ? c : EOF); 501167465Smp} 50259243Sobrien 50359243Sobrienstatic int curmode = 0; 504167465Smp 505167465Smpvoid 506167465Smpoutc(wint_t c, int width) 50759243Sobrien{ 50859243Sobrien int i; 50959243Sobrien 51059243Sobrien putwchar(c); 51159243Sobrien if (must_use_uc && (curmode&UNDERL)) { 51259243Sobrien for (i = 0; i < width; i++) 51359243Sobrien PRINT(CURS_LEFT); 51459243Sobrien for (i = 0; i < width; i++) 51559243Sobrien PRINT(UNDER_CHAR); 51659243Sobrien } 51759243Sobrien} 51859243Sobrien 51959243Sobrienvoid 52059243Sobriensetnewmode(int newmode) 52159243Sobrien{ 52259243Sobrien if (!iflag) { 52359243Sobrien if (curmode != NORMAL && newmode != NORMAL) 52459243Sobrien setnewmode(NORMAL); 52559243Sobrien switch (newmode) { 52659243Sobrien case NORMAL: 52759243Sobrien switch(curmode) { 52859243Sobrien case NORMAL: 529100616Smp break; 530100616Smp case UNDERL: 531100616Smp PRINT(EXIT_UNDERLINE); 532100616Smp break; 533100616Smp default: 534167465Smp /* This includes standout */ 535100616Smp PRINT(EXIT_ATTRIBUTES); 536100616Smp break; 537231990Smp } 538231990Smp break; 539167465Smp case ALTSET: 540167465Smp PRINT(ENTER_REVERSE); 541167465Smp break; 542100616Smp case SUPERSC: 543100616Smp /* 54459243Sobrien * This only works on a few terminals. 54559243Sobrien * It should be fixed. 546167465Smp */ 547167465Smp PRINT(ENTER_UNDERLINE); 54859243Sobrien PRINT(ENTER_DIM); 54959243Sobrien break; 550167465Smp case SUBSC: 551167465Smp PRINT(ENTER_DIM); 552100616Smp break; 55359243Sobrien case UNDERL: 55459243Sobrien PRINT(ENTER_UNDERLINE); 555167465Smp break; 55659243Sobrien case BOLD: 55759243Sobrien PRINT(ENTER_BOLD); 55859243Sobrien break; 55959243Sobrien default: 56059243Sobrien /* 56159243Sobrien * We should have some provision here for multiple modes 56259243Sobrien * on at once. This will have to come later. 563167465Smp */ 56459243Sobrien PRINT(ENTER_STANDOUT); 56559243Sobrien break; 56659243Sobrien } 56759243Sobrien } 56859243Sobrien curmode = newmode; 56959243Sobrien} 57059243Sobrien