cols.c (1773B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <assert.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <sys/ioctl.h> 7 #include <unistd.h> 8 9 #include "text.h" 10 #include "utf.h" 11 #include "util.h" 12 13 static long chars = 65; 14 static int cflag; 15 static struct linebuf b = EMPTY_LINEBUF; 16 17 static long n_columns; 18 static long n_rows; 19 20 static void 21 usage(void) 22 { 23 eprintf("usage: %s [-c chars] [file ...]\n", argv0); 24 } 25 26 int 27 main(int argc, char *argv[]) 28 { 29 long i, l, col; 30 size_t len, bytes; 31 int maxlen = 0; 32 struct winsize w; 33 FILE *fp; 34 35 ARGBEGIN { 36 case 'c': 37 cflag = 1; 38 chars = estrtol(EARGF(usage()), 0); 39 if (chars < 3) 40 eprintf("%d: too few character columns"); 41 break; 42 default: 43 usage(); 44 } ARGEND; 45 46 if (cflag == 0) { 47 ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); 48 if (w.ws_col != 0) 49 chars = w.ws_col; 50 } 51 52 if (argc == 0) { 53 getlines(stdin, &b); 54 } else for (; argc > 0; argc--, argv++) { 55 if (!(fp = fopen(argv[0], "r"))) 56 eprintf("fopen %s:", argv[0]); 57 getlines(fp, &b); 58 fclose(fp); 59 } 60 61 for (l = 0; l < b.nlines; ++l) { 62 len = utflen(b.lines[l]); 63 bytes = strlen(b.lines[l]); 64 if (len > 0 && b.lines[l][bytes-1] == '\n') { 65 b.lines[l][bytes-1] = '\0'; 66 --len; 67 } 68 if (len > maxlen) 69 maxlen = len; 70 if (maxlen > (chars - 1) / 2) 71 break; 72 } 73 74 n_columns = (chars + 1) / (maxlen + 1); 75 if (n_columns <= 1) { 76 for (l = 0; l < b.nlines; ++l) { 77 fputs(b.lines[l], stdout); 78 } 79 return 0; 80 } 81 82 n_rows = (b.nlines + (n_columns - 1)) / n_columns; 83 for (i = 0; i < n_rows; ++i) { 84 for (l = i, col = 1; l < b.nlines; l += n_rows, ++col) { 85 len = utflen(b.lines[l]); 86 fputs(b.lines[l], stdout); 87 if (col < n_columns) 88 printf("%*s", maxlen + 1 - (int)len, ""); 89 } 90 fputs("\n", stdout); 91 } 92 93 return 0; 94 }