X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/8a64a13b6c30f7d0202fc6d63bf86274ef454b2a..ad7871609881e73855d0b04da49b486cd93efca7:/usr/src/usr.bin/column/column.c diff --git a/usr/src/usr.bin/column/column.c b/usr/src/usr.bin/column/column.c index 37a9e77692..456a3a3341 100644 --- a/usr/src/usr.bin/column/column.c +++ b/usr/src/usr.bin/column/column.c @@ -1,51 +1,80 @@ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1989, 1993 + * 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #ifndef lint -char copyright[] = -"@(#) Copyright (c) 1989 The Regents of the University of California.\n\ - All rights reserved.\n"; +static char copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)column.c 5.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)column.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #include #include +#include #include -#include +#include +#include +#include + +void c_columnate __P((void)); +void *emalloc __P((int)); +void input __P((FILE *)); +void maketbl __P((void)); +void nomem __P((void)); +void print __P((void)); +void r_columnate __P((void)); +void usage __P((void)); int termwidth = 80; /* default terminal width */ -char **list; /* array of pointers to records */ int entries; /* number of records */ +int eval; /* exit value */ int maxlength; /* longest record */ +char **list; /* array of pointers to records */ +char *separator = "\t "; /* field separator for table option */ +int 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(); + int ch, tflag, xflag; + char *p; if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) { if (p = getenv("COLUMNS")) @@ -53,12 +82,18 @@ main(argc, argv) } else termwidth = win.ws_col; - xflag = 0; - while ((ch = getopt(argc, argv, "c:x")) != EOF) + tflag = xflag = 0; + while ((ch = getopt(argc, argv, "c:s:tx")) != EOF) switch(ch) { case 'c': termwidth = atoi(optarg); break; + case 's': + separator = optarg; + break; + case 't': + tflag = 1; + break; case 'x': xflag = 1; break; @@ -69,33 +104,34 @@ main(argc, argv) 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) + if (!*argv) + input(stdin); + else for (; *argv; ++argv) + if (fp = fopen(*argv, "r")) { + input(fp); (void)fclose(fp); - } while (*argv); + } else { + (void)fprintf(stderr, "column: %s: %s\n", *argv, + strerror(errno)); + eval = 1; + } if (!entries) - exit(0); + exit(eval); - if (maxlength >= termwidth) + if (tflag) + maketbl(); + else if (maxlength >= termwidth) print(); else if (xflag) c_columnate(); else r_columnate(); - exit(0); + exit(eval); } #define TAB 8 +void c_columnate() { register int chcnt, col, cnt, numcols; @@ -125,6 +161,7 @@ c_columnate() putchar('\n'); } +void r_columnate() { register int base, chcnt, cnt, col; @@ -152,59 +189,125 @@ r_columnate() } } +void print() { register int cnt; register char **lp; for (cnt = entries, lp = list; cnt--; ++lp) - printf("%s\n", *lp); + (void)printf("%s\n", *lp); +} + +typedef struct _tbl { + char **list; + int cols, *len; +} TBL; +#define DEFCOLS 25 + +void +maketbl() +{ + register TBL *t; + register int coloff, cnt; + register char *p, **lp; + int *lens, maxcols; + TBL *tbl; + char **cols; + + t = tbl = emalloc(entries * sizeof(TBL)); + cols = emalloc((maxcols = DEFCOLS) * sizeof(char *)); + lens = emalloc(maxcols * sizeof(int)); + for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) { + for (coloff = 0, p = *lp; cols[coloff] = strtok(p, separator); + p = NULL) + if (++coloff == maxcols) { + if (!(cols = realloc(cols, (u_int)maxcols + + DEFCOLS * sizeof(char *))) || + !(lens = realloc(lens, + (u_int)maxcols + DEFCOLS * sizeof(int)))) + nomem(); + bzero((char *)lens + maxcols * sizeof(int), + DEFCOLS * sizeof(int)); + maxcols += DEFCOLS; + } + t->list = emalloc(coloff * sizeof(char *)); + t->len = emalloc(coloff * sizeof(int)); + for (t->cols = coloff; --coloff >= 0;) { + t->list[coloff] = cols[coloff]; + t->len[coloff] = strlen(cols[coloff]); + if (t->len[coloff] > lens[coloff]) + lens[coloff] = t->len[coloff]; + } + } + for (cnt = 0, t = tbl; cnt < entries; ++cnt, ++t) { + for (coloff = 0; coloff < t->cols - 1; ++coloff) + (void)printf("%s%*s", t->list[coloff], + lens[coloff] - t->len[coloff] + 2, " "); + (void)printf("%s\n", t->list[coloff]); + } } #define DEFNUM 1000 #define MAXLINELEN (2048 + 1) +void input(fp) register FILE *fp; { - static u_int maxentry; + static int maxentry; register int len; register char *p; - char buf[MAXLINELEN], *malloc(), *realloc(); + char buf[MAXLINELEN]; - if (!list && - !(list = (char **)malloc((maxentry = DEFNUM) * sizeof(char *)))) - nomem(); + if (!list) + list = emalloc((maxentry = DEFNUM) * sizeof(char *)); while (fgets(buf, MAXLINELEN, fp)) { - if (buf[0] == '\n') + for (p = buf; *p && isspace(*p); ++p); + if (!*p) + continue; + if (!(p = index(p, '\n'))) { + (void)fprintf(stderr, "column: line too long.\n"); + eval = 1; continue; + } + *p = '\0'; + len = p - buf; + if (maxlength < len) + maxlength = len; if (entries == maxentry) { maxentry += DEFNUM; - if (!(list = - (char **)realloc(list, maxentry * sizeof(char *)))) + if (!(list = realloc(list, + (u_int)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); } } +void * +emalloc(size) + int size; +{ + char *p; + + if (!(p = malloc(size))) + nomem(); + bzero(p, size); + return(p); +} + +void nomem() { (void)fprintf(stderr, "column: out of memory.\n"); exit(1); } +void usage() { (void)fprintf(stderr, - "usage: column [-x] [-c columns] [file ...]\n"); + "usage: column [-tx] [-c columns] [file ...]\n"); exit(1); }