date and time created 80/10/01 17:29:07 by bill
authorBill Joy <bill@ucbvax.Berkeley.EDU>
Thu, 2 Oct 1980 09:29:07 +0000 (01:29 -0800)
committerBill Joy <bill@ucbvax.Berkeley.EDU>
Thu, 2 Oct 1980 09:29:07 +0000 (01:29 -0800)
SCCS-vsn: usr.bin/ul/ul.c 4.1

usr/src/usr.bin/ul/ul.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/ul/ul.c b/usr/src/usr.bin/ul/ul.c
new file mode 100644 (file)
index 0000000..779927e
--- /dev/null
@@ -0,0 +1,286 @@
+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;
+}