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

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

diff --git a/usr/src/usr.bin/col/col.c b/usr/src/usr.bin/col/col.c
new file mode 100644 (file)
index 0000000..17935f8
--- /dev/null
@@ -0,0 +1,310 @@
+static char *sccsid = "@(#)col.c       4.1 (Berkeley) %G%";
+# include <stdio.h>
+# define PL 256
+# define ESC '\033'
+# define RLF '\013'
+# define SI '\017'
+# define SO '\016'
+# define GREEK 0200
+# define LINELN 800
+
+char *page[PL];
+char lbuff [LINELN], *line;
+int bflag, hflag, fflag;
+int half;
+int cp, lp;
+int ll, llh, mustwr;
+int pcp = 0;
+char *pgmname;
+char   *strcpy();
+
+main (argc, argv)
+       int argc; char **argv;
+{
+       int i;
+       int greek;
+       register int c;
+       char fbuff[BUFSIZ];
+
+       setbuf (stdout, fbuff);
+       pgmname = argv[0];
+
+       for (i = 1; i < argc; i++) {
+               register char *p;
+               if (*argv[i] != '-') {
+                       fprintf (stderr, "%s: bad option %s\n",
+                               pgmname, argv[i]);
+                       exit (2);
+               }
+               for (p = argv[i]+1; *p; p++) {
+                       switch (*p) {
+                       case 'b':
+                               bflag++;
+                               break;
+
+                       case 'h':
+                               hflag++;
+                               break;
+
+                       case 'f':
+                               fflag++;
+                               break;
+
+                       default:
+                               fprintf (stderr, "%s: bad option letter %c\n",
+                                       pgmname, *p);
+                               exit (2);
+                       }
+               }
+       }
+
+       for (ll=0; ll<PL; ll++)
+               page[ll] = 0;
+
+       cp = 0;
+       ll = 0;
+       greek = 0;
+       mustwr = PL;
+       line = lbuff;
+
+       while ((c = getchar()) != EOF) {
+               switch (c) {
+               case '\n':
+                       incr();
+                       incr();
+                       cp = 0;
+                       continue;
+
+               case '\0':
+                       continue;
+
+               case ESC:
+                       c = getchar();
+                       switch (c) {
+                       case '7':       /* reverse full line feed */
+                               decr();
+                               decr();
+                               break;
+
+                       case '8':       /* reverse half line feed */
+                               if (fflag)
+                                       decr();
+                               else {
+                                       if (--half < -1) {
+                                               decr();
+                                               decr();
+                                               half += 2;
+                                       }
+                               }
+                               break;
+
+                       case '9':       /* forward half line feed */
+                               if (fflag)
+                                       incr();
+                               else {
+                                       if (++half > 0) {
+                                               incr();
+                                               incr();
+                                               half -= 2;
+                                       }
+                               }
+                               break;
+                       }
+                       continue;
+
+               case SO:
+                       greek = GREEK;
+                       continue;
+
+               case SI:
+                       greek = 0;
+                       continue;
+
+               case RLF:
+                       decr();
+                       decr();
+                       continue;
+
+               case '\r':
+                       cp = 0;
+                       continue;
+
+               case '\t':
+                       cp = (cp + 8) & -8;
+                       continue;
+
+               case '\b':
+                       if (cp > 0)
+                               cp--;
+                       continue;
+
+               case ' ':
+                       cp++;
+                       continue;
+
+               default:
+                       c &= 0177;
+                       if (c > 040 && c < 0177) {      /* if printable */
+                               outc(c | greek);
+                               cp++;
+                       }
+                       continue;
+               }
+       }
+
+       for (i=0; i<PL; i++)
+               if (page[(mustwr+i)%PL] != 0)
+                       emit (page[(mustwr+i) % PL], mustwr+i-PL);
+       emit (" ", (llh + 1) & -2);
+       exit(0);
+}
+
+outc (c)
+       register char c;
+{
+       if (lp > cp) {
+               line = lbuff;
+               lp = 0;
+       }
+
+       while (lp < cp) {
+               switch (*line) {
+               case '\0':
+                       *line = ' ';
+                       lp++;
+                       break;
+
+               case '\b':
+                       lp--;
+                       break;
+
+               default:
+                       lp++;
+               }
+               line++;
+       }
+       while (*line == '\b') {
+               line += 2;
+       }
+       if (bflag || *line == '\0' || *line == ' ')
+               *line = c;
+       else {
+               register char c1, c2, c3;
+               c1 = *++line;
+               *line++ = '\b';
+               c2 = *line;
+               *line++ = c;
+               while (c1) {
+                       c3 = *line;
+                       *line++ = c1;
+                       c1 = c2;
+                       c2 = c3;
+               }
+               lp = 0;
+               line = lbuff;
+       }
+}
+
+store (lno)
+{
+       char *malloc();
+
+       lno %= PL;
+       if (page[lno] != 0)
+               free (page[lno]);
+       page[lno] = malloc((unsigned)strlen(lbuff) + 2);
+       if (page[lno] == 0) {
+               fprintf (stderr, "%s: no storage\n", pgmname);
+               exit (2);
+       }
+       strcpy (page[lno],lbuff);
+}
+
+fetch(lno)
+{
+       register char *p;
+
+       lno %= PL;
+       p = lbuff;
+       while (*p)
+               *p++ = '\0';
+       line = lbuff;
+       lp = 0;
+       if (page[lno])
+               strcpy (line, page[lno]);
+}
+emit (s, lineno)
+       char *s;
+       int lineno;
+{
+       static int cline = 0;
+       register int ncp;
+       register char *p;
+       static int gflag = 0;
+
+       if (*s) {
+               while (cline < lineno - 1) {
+                       putchar ('\n');
+                       pcp = 0;
+                       cline += 2;
+               }
+               if (cline != lineno) {
+                       putchar (ESC);
+                       putchar ('9');
+                       cline++;
+               }
+               if (pcp)
+                       putchar ('\r');
+               pcp = 0;
+               p = s;
+               while (*p) {
+                       ncp = pcp;
+                       while (*p++ == ' ') {
+                               if ((++ncp & 7) == 0 && hflag) {
+                                       pcp = ncp;
+                                       putchar ('\t');
+                               }
+                       }
+                       if (!*--p)
+                               break;
+                       while (pcp < ncp) {
+                               putchar (' ');
+                               pcp++;
+                       }
+                       if (gflag != (*p & GREEK) && *p != '\b') {
+                               if (gflag)
+                                       putchar (SI);
+                               else
+                                       putchar (SO);
+                               gflag ^= GREEK;
+                       }
+                       putchar (*p & ~GREEK);
+                       if (*p++ == '\b')
+                               pcp--;
+                       else
+                               pcp++;
+               }
+       }
+}
+
+incr()
+{
+       store (ll++);
+       if (ll > llh)
+               llh = ll;
+       if (ll >= mustwr && page[ll%PL]) {
+               emit (page[ll%PL], ll - PL);
+               mustwr++;
+               free (page[ll%PL]);
+               page[ll%PL] = 0;
+       }
+       fetch (ll);
+}
+
+decr()
+{
+       if (ll > mustwr - PL) {
+               store (ll--);
+               fetch (ll);
+       }
+}