static char *sccsid = "@(#)ul.c 4.1 (Berkeley) 10/1/80"; /* * 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[-1]); 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 = ""; #define nilstr(x) (x == NULL || *x == '\0') if (nilstr(chul)&&nilstr(stul)&&nilstr(endul)&&tgetflag("ul")) execv("/bin/cat",argv[-1]); break; default: fprintf(stderr,"ul: trouble reading termcap\n"); /* fall through to ... */ case 0: /* No such terminal type - assume dumb */ stul = endul = chul = ""; break; } fflush (stderr); 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, "ul: 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; }