cols.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
cols.c (2087B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <sys/ioctl.h> | |
3 | |
4 #include <limits.h> | |
5 #include <stdint.h> | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 #include <unistd.h> | |
10 | |
11 #include "text.h" | |
12 #include "util.h" | |
13 | |
14 static void | |
15 usage(void) | |
16 { | |
17 eprintf("usage: %s [-c num] [file ...]\n", argv0); | |
18 } | |
19 | |
20 int | |
21 main(int argc, char *argv[]) | |
22 { | |
23 FILE *fp; | |
24 struct winsize w; | |
25 struct linebuf b = EMPTY_LINEBUF; | |
26 size_t chars = 65, maxlen = 0, i, j, k, len, cols, rows; | |
27 int cflag = 0, ret = 0; | |
28 char *p; | |
29 | |
30 ARGBEGIN { | |
31 case 'c': | |
32 cflag = 1; | |
33 chars = estrtonum(EARGF(usage()), 1, MIN(LLONG_MAX, SIZE… | |
34 break; | |
35 default: | |
36 usage(); | |
37 } ARGEND | |
38 | |
39 if (!cflag) { | |
40 if ((p = getenv("COLUMNS"))) | |
41 chars = estrtonum(p, 1, MIN(LLONG_MAX, SIZE_MAX)… | |
42 else if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) && w.ws_c… | |
43 chars = w.ws_col; | |
44 } | |
45 | |
46 if (!argc) { | |
47 getlines(stdin, &b); | |
48 } else { | |
49 for (; *argv; argc--, argv++) { | |
50 if (!strcmp(*argv, "-")) { | |
51 *argv = "<stdin>"; | |
52 fp = stdin; | |
53 } else if (!(fp = fopen(*argv, "r"))) { | |
54 weprintf("fopen %s:", *argv); | |
55 ret = 1; | |
56 continue; | |
57 } | |
58 getlines(fp, &b); | |
59 if (fp != stdin && fshut(fp, *argv)) | |
60 ret = 1; | |
61 } | |
62 } | |
63 | |
64 for (i = 0; i < b.nlines; i++) { | |
65 for (j = 0, len = 0; j < b.lines[i].len; j++) { | |
66 if (UTF8_POINT(b.lines[i].data[j])) | |
67 len++; | |
68 } | |
69 if (len && b.lines[i].data[b.lines[i].len - 1] == '\n') { | |
70 b.lines[i].data[--(b.lines[i].len)] = '\0'; | |
71 len--; | |
72 } | |
73 if (len > maxlen) | |
74 maxlen = len; | |
75 } | |
76 | |
77 for (cols = 1; (cols + 1) * maxlen + cols <= chars; cols++); | |
78 rows = b.nlines / cols + (b.nlines % cols > 0); | |
79 | |
80 for (i = 0; i < rows; i++) { | |
81 for (j = 0; j < cols && i + j * rows < b.nlines; j++) { | |
82 for (k = 0, len = 0; k < b.lines[i + j * rows].l… | |
83 if (UTF8_POINT(b.lines[i + j * rows].dat… | |
84 len++; | |
85 } | |
86 fwrite(b.lines[i + j * rows].data, 1, | |
87 b.lines[i + j * rows].len, stdout); | |
88 if (j < cols - 1) | |
89 for (k = len; k < maxlen + 1; k++) | |
90 putchar(' '); | |
91 } | |
92 putchar('\n'); | |
93 } | |
94 | |
95 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>"); | |
96 | |
97 return ret; | |
98 } |