morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base
Log | Files | Refs

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 }