[BACK]Return to column.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / column

Annotation of src/usr.bin/column/column.c, Revision 1.1

1.1     ! deraadt     1: /*     $NetBSD: column.c,v 1.4 1995/09/02 05:53:03 jtc Exp $   */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1989, 1993, 1994
        !             5:  *     The Regents of the University of California.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *     This product includes software developed by the University of
        !            18:  *     California, Berkeley and its contributors.
        !            19:  * 4. Neither the name of the University nor the names of its contributors
        !            20:  *    may be used to endorse or promote products derived from this software
        !            21:  *    without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            33:  * SUCH DAMAGE.
        !            34:  */
        !            35:
        !            36: #ifndef lint
        !            37: static char copyright[] =
        !            38: "@(#) Copyright (c) 1989, 1993, 1994\n\
        !            39:        The Regents of the University of California.  All rights reserved.\n";
        !            40: #endif /* not lint */
        !            41:
        !            42: #ifndef lint
        !            43: #if 0
        !            44: static char sccsid[] = "@(#)column.c   8.4 (Berkeley) 5/4/95";
        !            45: #endif
        !            46: static char rcsid[] = "$NetBSD: column.c,v 1.4 1995/09/02 05:53:03 jtc Exp $";
        !            47: #endif /* not lint */
        !            48:
        !            49: #include <sys/types.h>
        !            50: #include <sys/ioctl.h>
        !            51:
        !            52: #include <ctype.h>
        !            53: #include <err.h>
        !            54: #include <limits.h>
        !            55: #include <stdio.h>
        !            56: #include <stdlib.h>
        !            57: #include <string.h>
        !            58: #include <unistd.h>
        !            59:
        !            60: void  c_columnate __P((void));
        !            61: void *emalloc __P((int));
        !            62: void  input __P((FILE *));
        !            63: void  maketbl __P((void));
        !            64: void  print __P((void));
        !            65: void  r_columnate __P((void));
        !            66: void  usage __P((void));
        !            67:
        !            68: int termwidth = 80;            /* default terminal width */
        !            69:
        !            70: int entries;                   /* number of records */
        !            71: int eval;                      /* exit value */
        !            72: int maxlength;                 /* longest record */
        !            73: char **list;                   /* array of pointers to records */
        !            74: char *separator = "\t ";       /* field separator for table option */
        !            75:
        !            76: int
        !            77: main(argc, argv)
        !            78:        int argc;
        !            79:        char **argv;
        !            80: {
        !            81:        struct winsize win;
        !            82:        FILE *fp;
        !            83:        int ch, tflag, xflag;
        !            84:        char *p;
        !            85:
        !            86:        if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) {
        !            87:                if (p = getenv("COLUMNS"))
        !            88:                        termwidth = atoi(p);
        !            89:        } else
        !            90:                termwidth = win.ws_col;
        !            91:
        !            92:        tflag = xflag = 0;
        !            93:        while ((ch = getopt(argc, argv, "c:s:tx")) != EOF)
        !            94:                switch(ch) {
        !            95:                case 'c':
        !            96:                        termwidth = atoi(optarg);
        !            97:                        break;
        !            98:                case 's':
        !            99:                        separator = optarg;
        !           100:                        break;
        !           101:                case 't':
        !           102:                        tflag = 1;
        !           103:                        break;
        !           104:                case 'x':
        !           105:                        xflag = 1;
        !           106:                        break;
        !           107:                case '?':
        !           108:                default:
        !           109:                        usage();
        !           110:                }
        !           111:        argc -= optind;
        !           112:        argv += optind;
        !           113:
        !           114:        if (!*argv)
        !           115:                input(stdin);
        !           116:        else for (; *argv; ++argv)
        !           117:                if (fp = fopen(*argv, "r")) {
        !           118:                        input(fp);
        !           119:                        (void)fclose(fp);
        !           120:                } else {
        !           121:                        warn("%s", *argv);
        !           122:                        eval = 1;
        !           123:                }
        !           124:
        !           125:        if (!entries)
        !           126:                exit(eval);
        !           127:
        !           128:        if (tflag)
        !           129:                maketbl();
        !           130:        else if (maxlength >= termwidth)
        !           131:                print();
        !           132:        else if (xflag)
        !           133:                c_columnate();
        !           134:        else
        !           135:                r_columnate();
        !           136:        exit(eval);
        !           137: }
        !           138:
        !           139: #define        TAB     8
        !           140: void
        !           141: c_columnate()
        !           142: {
        !           143:        int chcnt, col, cnt, endcol, numcols;
        !           144:        char **lp;
        !           145:
        !           146:        maxlength = (maxlength + TAB) & ~(TAB - 1);
        !           147:        numcols = termwidth / maxlength;
        !           148:        endcol = maxlength;
        !           149:        for (chcnt = col = 0, lp = list;; ++lp) {
        !           150:                chcnt += printf("%s", *lp);
        !           151:                if (!--entries)
        !           152:                        break;
        !           153:                if (++col == numcols) {
        !           154:                        chcnt = col = 0;
        !           155:                        endcol = maxlength;
        !           156:                        putchar('\n');
        !           157:                } else {
        !           158:                        while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
        !           159:                                (void)putchar('\t');
        !           160:                                chcnt = cnt;
        !           161:                        }
        !           162:                        endcol += maxlength;
        !           163:                }
        !           164:        }
        !           165:        if (chcnt)
        !           166:                putchar('\n');
        !           167: }
        !           168:
        !           169: void
        !           170: r_columnate()
        !           171: {
        !           172:        int base, chcnt, cnt, col, endcol, numcols, numrows, row;
        !           173:
        !           174:        maxlength = (maxlength + TAB) & ~(TAB - 1);
        !           175:        numcols = termwidth / maxlength;
        !           176:        numrows = entries / numcols;
        !           177:        if (entries % numcols)
        !           178:                ++numrows;
        !           179:
        !           180:        for (row = 0; row < numrows; ++row) {
        !           181:                endcol = maxlength;
        !           182:                for (base = row, chcnt = col = 0; col < numcols; ++col) {
        !           183:                        chcnt += printf("%s", list[base]);
        !           184:                        if ((base += numrows) >= entries)
        !           185:                                break;
        !           186:                        while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) {
        !           187:                                (void)putchar('\t');
        !           188:                                chcnt = cnt;
        !           189:                        }
        !           190:                        endcol += maxlength;
        !           191:                }
        !           192:                putchar('\n');
        !           193:        }
        !           194: }
        !           195:
        !           196: void
        !           197: print()
        !           198: {
        !           199:        int cnt;
        !           200:        char **lp;
        !           201:
        !           202:        for (cnt = entries, lp = list; cnt--; ++lp)
        !           203:                (void)printf("%s\n", *lp);
        !           204: }
        !           205:
        !           206: typedef struct _tbl {
        !           207:        char **list;
        !           208:        int cols, *len;
        !           209: } TBL;
        !           210: #define        DEFCOLS 25
        !           211:
        !           212: void
        !           213: maketbl()
        !           214: {
        !           215:        TBL *t;
        !           216:        int coloff, cnt;
        !           217:        char *p, **lp;
        !           218:        int *lens, maxcols;
        !           219:        TBL *tbl;
        !           220:        char **cols;
        !           221:
        !           222:        t = tbl = emalloc(entries * sizeof(TBL));
        !           223:        cols = emalloc((maxcols = DEFCOLS) * sizeof(char *));
        !           224:        lens = emalloc(maxcols * sizeof(int));
        !           225:        for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) {
        !           226:                for (coloff = 0, p = *lp; cols[coloff] = strtok(p, separator);
        !           227:                    p = NULL)
        !           228:                        if (++coloff == maxcols) {
        !           229:                                if (!(cols = realloc(cols, (u_int)maxcols +
        !           230:                                    DEFCOLS * sizeof(char *))) ||
        !           231:                                    !(lens = realloc(lens,
        !           232:                                    (u_int)maxcols + DEFCOLS * sizeof(int))))
        !           233:                                        err(1, NULL);
        !           234:                                memset((char *)lens + maxcols * sizeof(int),
        !           235:                                    0, DEFCOLS * sizeof(int));
        !           236:                                maxcols += DEFCOLS;
        !           237:                        }
        !           238:                t->list = emalloc(coloff * sizeof(char *));
        !           239:                t->len = emalloc(coloff * sizeof(int));
        !           240:                for (t->cols = coloff; --coloff >= 0;) {
        !           241:                        t->list[coloff] = cols[coloff];
        !           242:                        t->len[coloff] = strlen(cols[coloff]);
        !           243:                        if (t->len[coloff] > lens[coloff])
        !           244:                                lens[coloff] = t->len[coloff];
        !           245:                }
        !           246:        }
        !           247:        for (cnt = 0, t = tbl; cnt < entries; ++cnt, ++t) {
        !           248:                for (coloff = 0; coloff < t->cols  - 1; ++coloff)
        !           249:                        (void)printf("%s%*s", t->list[coloff],
        !           250:                            lens[coloff] - t->len[coloff] + 2, " ");
        !           251:                (void)printf("%s\n", t->list[coloff]);
        !           252:        }
        !           253: }
        !           254:
        !           255: #define        DEFNUM          1000
        !           256: #define        MAXLINELEN      (LINE_MAX + 1)
        !           257:
        !           258: void
        !           259: input(fp)
        !           260:        FILE *fp;
        !           261: {
        !           262:        static int maxentry;
        !           263:        int len;
        !           264:        char *p, buf[MAXLINELEN];
        !           265:
        !           266:        if (!list)
        !           267:                list = emalloc((maxentry = DEFNUM) * sizeof(char *));
        !           268:        while (fgets(buf, MAXLINELEN, fp)) {
        !           269:                for (p = buf; *p && isspace(*p); ++p);
        !           270:                if (!*p)
        !           271:                        continue;
        !           272:                if (!(p = strchr(p, '\n'))) {
        !           273:                        warnx("line too long");
        !           274:                        eval = 1;
        !           275:                        continue;
        !           276:                }
        !           277:                *p = '\0';
        !           278:                len = p - buf;
        !           279:                if (maxlength < len)
        !           280:                        maxlength = len;
        !           281:                if (entries == maxentry) {
        !           282:                        maxentry += DEFNUM;
        !           283:                        if (!(list = realloc(list,
        !           284:                            (u_int)maxentry * sizeof(char *))))
        !           285:                                err(1, NULL);
        !           286:                }
        !           287:                list[entries++] = strdup(buf);
        !           288:        }
        !           289: }
        !           290:
        !           291: void *
        !           292: emalloc(size)
        !           293:        int size;
        !           294: {
        !           295:        char *p;
        !           296:
        !           297:        if (!(p = malloc(size)))
        !           298:                err(1, NULL);
        !           299:        memset(p, 0, size);
        !           300:        return (p);
        !           301: }
        !           302:
        !           303: void
        !           304: usage()
        !           305: {
        !           306:
        !           307:        (void)fprintf(stderr,
        !           308:            "usage: column [-tx] [-c columns] [file ...]\n");
        !           309:        exit(1);
        !           310: }