#ident "$Revision: 1.11 $" #include #define IESC '\033' #define SO '\016' #define SI '\017' #define HFWD '9' #define HREV '8' #define FREV '7' #define MAXBUF 4096 #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 __getopt(int, char **, char *); 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; } ; char buf[BUFSIZ]; struct CHAR obuf[MAXBUF]; int col, maxcol, tcol; int mode; int halfpos; int upln; int iflag; /* * In the case of multiple attrs (e.g. ul + bold), output bold instead of * the default reverse video. This is used by the man command to output * the SVR4 man pages in a more attractive manner. */ int bflag; main(argc, argv) int argc; char **argv; { int c, tgv; char *cp, *termtype; FILE *f; char termcap[1024]; char *getenv(); extern int optind; extern char *optarg; termtype = getenv("TERM"); if (termtype == NULL || (argv[0][0] == 'c' && !isatty(1))) termtype = "lpr"; while ((c=__getopt(argc, argv, "ibt:T:")) != EOF) switch(c) { case 't': case 'T': /* for nroff compatibility */ termtype = optarg; break; case 'i': iflag = 1; break; case 'b': bflag = 1; break; default: fprintf(stderr, "Usage: %s [ -ib ] [ -tTerm ] file...\n", argv[0]); exit(1); } /* hack attempt to keep libcurses termcap emulation from doing ioctls * that change tty modes, since we don't need or want them */ c = dup(2); if (c != -1) close(2); tgv = tgetent(termcap, termtype); if (c != -1) dup2(c,2); switch(tgv) { case 1: break; default: fprintf(stderr,"trouble reading termcap"); /* fall through to ... */ case 0: /* No such terminal type - assume dumb */ 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; setbuf(stdout, buf); initbuf(); if (optind == argc) filter(stdin); else for (; optind 0 && !lastwasspec) col--, tcol--; lastwasspec = 0; continue; case '\t': { /* if due to overstrikes we are already at the 'correct' * character position then at least move forward 1 space */ int tomove = ((tcol+8) & ~07) - tcol; if (tomove == 0) tomove++; col += tomove; tcol += tomove; if (col > maxcol) maxcol = col; lastwasspec = 0; continue; } case '\r': col = tcol = 0; lastwasspec = 0; continue; case SO: mode |= ALTSET; lastwasspec++; continue; case SI: mode &= ~ALTSET; lastwasspec++; continue; case IESC: lastwasspec++; 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); } /* NOTREACHED */ case '_': /* * an _ aftger a character means underline that char and * advance */ if (obuf[col].c_char) { if (obuf[col].c_char == '_') obuf[col].c_mode |= BOLD | mode; else obuf[col].c_mode |= UNDERL | mode; } else obuf[col].c_char = '_'; /* FALL THROUGH */ case ' ': lastwasspec = 0; col++, tcol++; if (col > maxcol) maxcol = col; continue; case '\n': lastwasspec = 0; flushln(); 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 { /* overstrike -- output only the second character */ obuf[col].c_char = c; obuf[col].c_mode = mode; } col++, tcol++; lastwasspec = 0; if (col > maxcol) maxcol = col; continue; } if (maxcol) flushln(); } flushln() { register lastmode; register i; int hadmodes = 0; lastmode = NORMAL; for (i=0; i= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return EOF; else if (strcmp(argv[optind], "--") == NULL) { optind++; return EOF; } else if (strcmp(argv[optind], "-?") == NULL) { optind++; return '?'; } c = argv[optind][sp]; if (c == ':' || (cp=index(opts, c)) == NULL) { ERR (": illegal option -- ", c); if (argv[optind][++sp] == '\0') { optind++; sp = 1; } return '?'; } if (*++cp == ':') { if (argv[optind][2] != '\0') optarg = &argv[optind++][sp+1]; else if (++optind >= argc) { ERR (": option requires an argument -- ", c); sp = 1; return '?'; } else optarg = argv[optind++]; sp = 1; } else if (argv[optind][++sp] == '\0') { sp = 1; optind++; } return c; }