|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)column.c 5.6 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/types.h> ! 31: #include <sys/ioctl.h> ! 32: #include <stdio.h> ! 33: #include <string.h> ! 34: #include <ctype.h> ! 35: ! 36: int termwidth = 80; /* default terminal width */ ! 37: ! 38: int entries; /* number of records */ ! 39: int eval; /* exit value */ ! 40: int maxlength; /* longest record */ ! 41: char **list; /* array of pointers to records */ ! 42: char *separator = "\t "; /* field separator for table option */ ! 43: ! 44: main(argc, argv) ! 45: int argc; ! 46: char **argv; ! 47: { ! 48: extern char *optarg; ! 49: extern int errno, optind; ! 50: struct winsize win; ! 51: FILE *fp; ! 52: int ch, tflag, xflag; ! 53: char *p, *getenv(); ! 54: ! 55: if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) { ! 56: if (p = getenv("COLUMNS")) ! 57: termwidth = atoi(p); ! 58: } else ! 59: termwidth = win.ws_col; ! 60: ! 61: xflag = 0; ! 62: while ((ch = getopt(argc, argv, "c:s:tx")) != EOF) ! 63: switch(ch) { ! 64: case 'c': ! 65: termwidth = atoi(optarg); ! 66: break; ! 67: case 's': ! 68: separator = optarg; ! 69: break; ! 70: case 't': ! 71: tflag = 1; ! 72: break; ! 73: case 'x': ! 74: xflag = 1; ! 75: break; ! 76: case '?': ! 77: default: ! 78: usage(); ! 79: } ! 80: argc -= optind; ! 81: argv += optind; ! 82: ! 83: if (!*argv) ! 84: input(stdin); ! 85: else for (; *argv; ++argv) ! 86: if (fp = fopen(*argv, "r")) { ! 87: input(fp); ! 88: (void)fclose(fp); ! 89: } else { ! 90: (void)fprintf(stderr, "column: %s: %s\n", *argv, ! 91: strerror(errno)); ! 92: eval = 1; ! 93: } ! 94: ! 95: if (!entries) ! 96: exit(eval); ! 97: ! 98: if (tflag) ! 99: maketbl(); ! 100: else { ! 101: if (maxlength >= termwidth) ! 102: print(); ! 103: if (xflag) ! 104: c_columnate(); ! 105: else ! 106: r_columnate(); ! 107: } ! 108: exit(eval); ! 109: } ! 110: ! 111: #define TAB 8 ! 112: c_columnate() ! 113: { ! 114: register int chcnt, col, cnt, numcols; ! 115: int endcol; ! 116: char **lp; ! 117: ! 118: maxlength = (maxlength + TAB) & ~(TAB - 1); ! 119: numcols = termwidth / maxlength; ! 120: endcol = maxlength; ! 121: for (chcnt = col = 0, lp = list;; ++lp) { ! 122: chcnt += printf("%s", *lp); ! 123: if (!--entries) ! 124: break; ! 125: if (++col == numcols) { ! 126: chcnt = col = 0; ! 127: endcol = maxlength; ! 128: putchar('\n'); ! 129: } else { ! 130: while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) { ! 131: (void)putchar('\t'); ! 132: chcnt = cnt; ! 133: } ! 134: endcol += maxlength; ! 135: } ! 136: } ! 137: if (chcnt) ! 138: putchar('\n'); ! 139: } ! 140: ! 141: r_columnate() ! 142: { ! 143: register int base, chcnt, cnt, col; ! 144: int endcol, numcols, numrows, row; ! 145: ! 146: maxlength = (maxlength + TAB) & ~(TAB - 1); ! 147: numcols = termwidth / maxlength; ! 148: numrows = entries / numcols; ! 149: if (entries % numcols) ! 150: ++numrows; ! 151: ! 152: for (row = 0; row < numrows; ++row) { ! 153: endcol = maxlength; ! 154: for (base = row, chcnt = col = 0; col < numcols; ++col) { ! 155: chcnt += printf("%s", list[base]); ! 156: if ((base += numrows) >= entries) ! 157: break; ! 158: while ((cnt = (chcnt + TAB & ~(TAB - 1))) <= endcol) { ! 159: (void)putchar('\t'); ! 160: chcnt = cnt; ! 161: } ! 162: endcol += maxlength; ! 163: } ! 164: putchar('\n'); ! 165: } ! 166: } ! 167: ! 168: print() ! 169: { ! 170: register int cnt; ! 171: register char **lp; ! 172: ! 173: for (cnt = entries, lp = list; cnt--; ++lp) ! 174: (void)printf("%s\n", *lp); ! 175: } ! 176: ! 177: typedef struct _tbl { ! 178: char **list; ! 179: int cols, *len; ! 180: } TBL; ! 181: #define DEFCOLS 25 ! 182: ! 183: maketbl() ! 184: { ! 185: register TBL *t; ! 186: register int coloff, cnt; ! 187: register char *p, **lp; ! 188: int *lens, maxcols; ! 189: TBL *tbl; ! 190: char **cols, *emalloc(), *realloc(); ! 191: ! 192: t = tbl = (TBL *)emalloc(entries * sizeof(TBL)); ! 193: cols = (char **)emalloc((maxcols = DEFCOLS) * sizeof(char *)); ! 194: lens = (int *)emalloc(maxcols * sizeof(int)); ! 195: for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) { ! 196: for (coloff = 0, p = *lp; cols[coloff] = strtok(p, separator); ! 197: p = NULL) ! 198: if (++coloff == maxcols) { ! 199: if (!(cols = (char **)realloc((char *)cols, ! 200: (u_int)maxcols + DEFCOLS * sizeof(char *))) || ! 201: !(lens = (int *)realloc((char *)lens, ! 202: (u_int)maxcols + DEFCOLS * sizeof(int)))) ! 203: nomem(); ! 204: bzero((char *)lens + maxcols * sizeof(int), ! 205: DEFCOLS * sizeof(int)); ! 206: maxcols += DEFCOLS; ! 207: } ! 208: t->list = (char **)emalloc(coloff * sizeof(char *)); ! 209: t->len = (int *)emalloc(coloff * sizeof(int)); ! 210: for (t->cols = coloff; --coloff >= 0;) { ! 211: t->list[coloff] = cols[coloff]; ! 212: t->len[coloff] = strlen(cols[coloff]); ! 213: if (t->len[coloff] > lens[coloff]) ! 214: lens[coloff] = t->len[coloff]; ! 215: } ! 216: } ! 217: for (cnt = 0, t = tbl; cnt < entries; ++cnt, ++t) { ! 218: for (coloff = 0; coloff < t->cols - 1; ++coloff) ! 219: (void)printf("%s%*s", t->list[coloff], ! 220: lens[coloff] - t->len[coloff] + 2, " "); ! 221: (void)printf("%s\n", t->list[coloff]); ! 222: } ! 223: } ! 224: ! 225: #define DEFNUM 1000 ! 226: #define MAXLINELEN (2048 + 1) ! 227: ! 228: input(fp) ! 229: register FILE *fp; ! 230: { ! 231: static int maxentry; ! 232: register int len; ! 233: register char *p; ! 234: char buf[MAXLINELEN], *emalloc(), *realloc(); ! 235: ! 236: if (!list) ! 237: list = (char **)emalloc((maxentry = DEFNUM) * sizeof(char *)); ! 238: while (fgets(buf, MAXLINELEN, fp)) { ! 239: for (p = buf; *p && isspace(*p); ++p); ! 240: if (!*p) ! 241: continue; ! 242: if (!(p = index(p, '\n'))) { ! 243: (void)fprintf(stderr, "column: line too long.\n"); ! 244: eval = 1; ! 245: continue; ! 246: } ! 247: *p = '\0'; ! 248: len = p - buf; ! 249: if (maxlength < len) ! 250: maxlength = len; ! 251: if (entries == maxentry) { ! 252: maxentry += DEFNUM; ! 253: if (!(list = ! 254: (char **)realloc((char *)list, ! 255: (u_int)maxentry * sizeof(char *)))) ! 256: nomem(); ! 257: } ! 258: list[entries++] = strdup(buf); ! 259: } ! 260: } ! 261: ! 262: char * ! 263: emalloc(size) ! 264: int size; ! 265: { ! 266: char *p, *malloc(); ! 267: ! 268: /* NOSTRICT */ ! 269: if (!(p = malloc((u_int)size))) ! 270: nomem(); ! 271: bzero(p, size); ! 272: return(p); ! 273: } ! 274: ! 275: nomem() ! 276: { ! 277: (void)fprintf(stderr, "column: out of memory.\n"); ! 278: exit(1); ! 279: } ! 280: ! 281: usage() ! 282: { ! 283: (void)fprintf(stderr, ! 284: "usage: column [-tx] [-c columns] [file ...]\n"); ! 285: exit(1); ! 286: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.