BSD 3 release
[unix-history] / usr / src / cmd / ul.c
/*
*
* ul - General underline filter. Converts underlines by
* the standard backspacing method to the code used by the
* particular terminal to underline.
*
*/
#include <stdio.h>
char buf[BUFSIZ];
char isul[BUFSIZ];
char termcap[1024];
char ulbuf[BUFSIZ];
char *stul, *endul, *chul;
char *backspace;
char *termtype;
int outc();
char *tgetstr();
char *getenv();
main(argc,argv) char **argv; {
register int i;
char *cp;
FILE *f;
/* Figure out kind of terminal and set up special strings. */
termtype = getenv("TERM");
if (termtype == NULL)
termtype = "dumb";
while (argc >= 2 && argv[1][0] == '-') {
switch(argv[1][1]) {
case 't':
case 'T': /* for nroff compatibility */
if (argv[1][2])
termtype = &argv[1][2];
else {
termtype = argv[2];
argc--;
argv++;
}
break;
default:
printf("Bad switch: %s\n",argv[1]);
exit(1);
}
}
switch(tgetent(termcap, termtype)) {
case 1: /* All is well */
/* Terminals that don't need any help. */
if (tgetflag("ul") || tgetflag("os"))
execv("/bin/cat",argv);
cp = ulbuf;
if ((backspace = tgetstr("bc",&cp)) == NULL)
backspace = "\b";
/*
* Handle terminals that have start underline/stop
* underline sequences, as well as those with
* underline char sequences (we assume the sequence
* moves the cursor forward one character).
* If we can't find underline sequences, we
* settle for standout sequences.
*/
if ( (chul=tgetstr("uc",&cp)) == NULL)
chul = "";
if ( (stul=tgetstr("us",&cp)) == NULL &&
(!*chul) && (stul=tgetstr("so",&cp)) == NULL)
stul = "";
if ( (endul=tgetstr("ue",&cp)) == NULL &&
(!*chul) && (endul=tgetstr("se",&cp)) == NULL)
endul = "";
break;
default:/* error opening/reading termcap */
fprintf(stderr,"trouble reading termcap");
/* fall through to ... */
case 0: /* No such terminal type - assume dumb */
stul = endul = chul = "";
break;
}
if (argc < 2) filter(stdin);
else for (i=1; i<argc; i++) {
f = fopen(argv[i],"r");
if (f == NULL) {
printf("Can't open %s\n",argv[i]);
exit(1);
} else filter(f);
}
exit(0);
}
filter(f)
FILE *f;
{
register int p, n;
register char c;
int state;
n = 0;
for (;;) {
p = 0;
for (p=0; p<n; p++) {
buf[p] = '\0';
isul[p] = 0;
}
p = n = 0;
for (;;) {
c = getc(f);
if (c==EOF) break;
if (c=='\b') {
if (p > 0) {
p--;
}
} else if (c=='_' && isul[p]==0 && buf[p]) {
isul[p] = 1;
p++;
} else {
if (buf[p] == '_') {
isul[p] = 1;
}
buf[p] = c;
p++;
if (n < p) n = p;
}
if (c=='\n') break;
}
state = 0;
for (p=0; p<n; p++) {
if (isul[p] != state)
tputs(isul[p] ? stul : endul, 1, outc);
state = isul[p];
outc(buf[p]);
if (isul[p] && *chul) {
printf("%s",backspace);
tputs(chul, 1, outc);
}
}
if (c==EOF) break;
}
}
outc(c)
char c;
{
putchar(c);
}