date and time created 89/06/25 13:27:28 by bostic
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Mon, 26 Jun 1989 04:27:28 +0000 (20:27 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Mon, 26 Jun 1989 04:27:28 +0000 (20:27 -0800)
SCCS-vsn: usr.bin/column/column.c 5.1

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

diff --git a/usr/src/usr.bin/column/column.c b/usr/src/usr.bin/column/column.c
new file mode 100644 (file)
index 0000000..37a9e77
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)column.c   5.1 (Berkeley) %G%";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <strings.h>
+
+int termwidth = 80;            /* default terminal width */
+
+char **list;                   /* array of pointers to records */
+int entries;                   /* number of records */
+int maxlength;                 /* longest record */
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       extern char *optarg;
+       extern int errno, optind;
+       struct winsize win;
+       FILE *fp;
+       int ch, xflag;
+       char *p, *getenv();
+
+       if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) {
+               if (p = getenv("COLUMNS"))
+                       termwidth = atoi(p);
+       } else
+               termwidth = win.ws_col;
+
+       xflag = 0;
+       while ((ch = getopt(argc, argv, "c:x")) != EOF)
+               switch(ch) {
+               case 'c':
+                       termwidth = atoi(optarg);
+                       break;
+               case 'x':
+                       xflag = 1;
+                       break;
+               case '?':
+               default:
+                       usage();
+               }
+       argc -= optind;
+       argv += optind;
+
+       fp = stdin;
+       do {
+               if (*argv)
+                       if (!(fp = fopen(*argv, "r"))) {
+                               (void)fprintf(stderr, "column: %s: %s\n",
+                                   *argv, strerror(errno));
+                               continue;
+                       } else
+                               ++argv;
+               input(fp);
+               if (fp != stdin)
+                       (void)fclose(fp);
+       } while (*argv);
+
+       if (!entries)
+               exit(0);
+
+       if (maxlength >= termwidth)
+               print();
+       else if (xflag)
+               c_columnate();
+       else
+               r_columnate();
+       exit(0);
+}
+
+#define        TAB     8
+c_columnate()
+{
+       register int chcnt, col, cnt, numcols;
+       int endcol;
+       char **lp;
+
+       maxlength = (maxlength + TAB) & ~(TAB - 1);
+       numcols = termwidth / maxlength;
+       endcol = maxlength;
+       for (chcnt = col = 0, lp = list;; ++lp) {
+               chcnt += printf("%s", *lp);
+               if (!--entries)
+                       break;
+               if (++col == numcols) {
+                       chcnt = col = 0;
+                       endcol = maxlength;
+                       putchar('\n');
+               } else {
+                       while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
+                               (void)putchar('\t');
+                               chcnt = cnt;
+                       }
+                       endcol += maxlength;
+               }
+       }
+       if (chcnt)
+               putchar('\n');
+}
+
+r_columnate()
+{
+       register int base, chcnt, cnt, col;
+       int endcol, numcols, numrows, row;
+
+       maxlength = (maxlength + TAB) & ~(TAB - 1);
+       numcols = termwidth / maxlength;
+       numrows = entries / numcols;
+       if (entries % numcols)
+               ++numrows;
+
+       for (row = 0; row < numrows; ++row) {
+               endcol = maxlength;
+               for (base = row, chcnt = col = 0; col < numcols; ++col) {
+                       chcnt += printf("%s", list[base]);
+                       if ((base += numrows) >= entries)
+                               break;
+                       while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
+                               (void)putchar('\t');
+                               chcnt = cnt;
+                       }
+                       endcol += maxlength;
+               }
+               putchar('\n');
+       }
+}
+
+print()
+{
+       register int cnt;
+       register char **lp;
+
+       for (cnt = entries, lp = list; cnt--; ++lp)
+               printf("%s\n", *lp);
+}
+
+#define        DEFNUM          1000
+#define        MAXLINELEN      (2048 + 1)
+
+input(fp)
+       register FILE *fp;
+{
+       static u_int maxentry;
+       register int len;
+       register char *p;
+       char buf[MAXLINELEN], *malloc(), *realloc();
+
+       if (!list &&
+           !(list = (char **)malloc((maxentry = DEFNUM) * sizeof(char *))))
+               nomem();
+       while (fgets(buf, MAXLINELEN, fp)) {
+               if (buf[0] == '\n')
+                       continue;
+               if (entries == maxentry) {
+                       maxentry += DEFNUM;
+                       if (!(list =
+                           (char **)realloc(list, maxentry * sizeof(char *))))
+                               nomem();
+               }
+               if (p = index(buf, '\n')) {
+                       *p = '\0';
+                       len = p - buf;
+               }
+               else
+                       len = strlen(buf);
+               if (maxlength < len)
+                       maxlength = len;
+               list[entries++] = strdup(buf);
+       }
+}
+
+nomem()
+{
+       (void)fprintf(stderr, "column: out of memory.\n");
+       exit(1);
+}
+
+usage()
+{
+       (void)fprintf(stderr,
+           "usage: column [-x] [-c columns] [file ...]\n");
+       exit(1);
+}