date and time created 80/10/01 17:29:07 by bill
[unix-history] / usr / src / usr.bin / ul / ul.c
static char *sccsid = "@(#)ul.c 4.1 (Berkeley) %G%";
/*
* ul
*/
#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)
int argc;
char **argv;
{
register int i;
char *cp;
FILE *f;
argc--, argv++;
termtype = getenv("TERM");
if (termtype == NULL)
termtype = "dumb";
while (argc > 0 && argv[0][0] == '-') {
switch(argv[0][1]) {
case 't':
case 'T': /* for nroff compatibility */
if (argv[0][2])
termtype = &argv[0][2];
else {
termtype = argv[1];
argc--;
argv++;
}
break;
case 'i':
argc--, argv++;
iul(argc, argv);
exit(0);
default:
printf("Usage: ul [ -i ] [ -tTerm ] file...\n");
exit(1);
}
}
switch(tgetent(termcap, termtype)) {
case 1:
if (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 && !tgetflag("ul") &&
(!*chul) && (stul=tgetstr("so",&cp)) == NULL)
stul = "";
if ((endul=tgetstr("ue",&cp)) == NULL && !tgetflag("ul") &&
(!*chul) && (endul=tgetstr("se",&cp)) == NULL)
endul = "";
if (chul==0&&stul==0&&endul==0&&tgetflag("ul"))
execv("/bin/cat",argv);
break;
default:
fprintf(stderr,"trouble reading termcap");
/* fall through to ... */
case 0:
/* No such terminal type - assume dumb */
stul = endul = chul = "";
break;
}
if (argc == 0)
filter(stdin);
else for (i=0; i<argc; i++) {
f = fopen(argv[i],"r");
if (f == NULL) {
perror(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];
putchar(buf[p]);
if (isul[p] && *chul) {
printf("%s",backspace);
tputs(chul, 1, outc);
}
}
if (c==EOF) break;
}
}
outc(c)
char c;
{
putchar(c);
}
#define BACKSPACE 0
#define QUOTE 0200
char linebuf[BUFSIZ], genbuf[BUFSIZ];
char *strcpy();
iul(argc, argv)
int argc;
char *argv[];
{
register c;
register char *lp;
do {
if (argc > 0) {
if (freopen(argv[0], "r", stdin) == NULL) {
perror(argv[0]);
exit(1);
}
argc--; argv++;
}
while (fgets(linebuf, sizeof linebuf, stdin) != 0) {
for (lp = linebuf; *lp; lp++)
continue;
*--lp = 0;
doulg();
dographic();
if (genbuf[0])
printf("\n%s", genbuf);
putchar('\n');
fflush(stdout);
}
} while (argc > 0);
exit(0);
}
dographic()
{
register char *lp;
register c;
for (lp = linebuf; c = *lp++;) {
switch (c) {
case '\b':
if (BACKSPACE == 0)
c = '?';
break;
default:
if (c < ' ' || c == 0177)
c = '?';
break;
case '\t':
break;
}
putchar(c);
}
}
doulg()
{
register char *lp, *gp;
char *maxgp;
register c;
char csw;
int col;
gp = genbuf;
*gp = 0;
maxgp = gp;
col = 0;
for (lp = linebuf; c = *lp++;) {
switch (c) {
case '\t':
while ((col & 7) != 7) {
*gp++ = ' ';
if (gp >= &genbuf[BUFSIZ - 2])
goto ovflo;
col++;
}
break;
default:
if (gp >= maxgp)
break;
c |= (*gp & QUOTE);
break;
case '_':
if (gp >= maxgp)
c = QUOTE;
else
c = *gp | QUOTE;
break;
case '\b':
if (gp > genbuf) {
gp--;
col--;
}
continue;
}
if (gp >= &genbuf[BUFSIZ - 2]) {
ovflo:
fprintf(stderr, "Line too long\n");
exit(1);
}
*gp++ = c;
if (gp > maxgp)
maxgp = gp;
col++;
}
*maxgp = 0;
strcpy(linebuf, genbuf);
for (lp = linebuf, gp = genbuf; c = *lp; gp++, lp++)
if (c & QUOTE) {
c &= 0177;
if (c == 0)
*lp = '_', *gp = ' ';
else
*lp = c, *gp = '-';
} else
*gp = ' ';
--gp;
while (gp >= genbuf && *gp == ' ')
--gp;
gp[1] = 0;
}