commit f140403fcafaee00623e8310ffa1bb5311619447
parent 78187474cf6a45eeee8a5500eff665e473bc75c6
Author: FRIGN <dev@frign.de>
Date: Sun, 8 Mar 2015 19:33:46 +0100
Audit cols(1)
1) Refactor manpage.
2) De-globalize local values.
3) update usage().
4) sort local variable declarations.
5) fix wrong argument in strtonum (3 -> 1).
6) argc-argv style, boolean style.
7) check bytes > 0 before accessing b.lines[i][bytes - 1]
relying on len only makes sense but let's not push it.
7) don't break on maxlen > (chars - 1) / 2. This didn't even
make sense.
8) _correctly_ calculate cols and rows in a readable way.
9) Rewrite loop over rows and cols in a readable way and
using putchar in a loop instead of printf-magic or fputs
where not necessary.
Diffstat:
M | README | | | 2 | +- |
M | cols.1 | | | 19 | +++++++++---------- |
M | cols.c | | | 74 | +++++++++++++++++++++++++++++++++----------------------------------------- |
3 files changed, 43 insertions(+), 52 deletions(-)
diff --git a/README b/README
@@ -18,7 +18,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
=*| chroot non-posix none
=* cksum yes none
=* cmp yes none
-#* cols non-posix none
+#*| cols non-posix none
col yes none
=* comm yes none
=*| cp yes none (-i)
diff --git a/cols.1 b/cols.1
@@ -1,4 +1,4 @@
-.Dd February 19, 2015
+.Dd March 8, 2015
.Dt COLS 1
.Os sbase
.Sh NAME
@@ -15,7 +15,8 @@ reads each
in sequence and writes them to stdout, in as many vertical
columns as will fit in
.Ar num
-character columns. If no
+character columns.
+If no
.Ar file
is given,
.Nm
@@ -27,17 +28,15 @@ tries to figure out the width of the output
device. If that fails, it defaults to 65 chars.
.Sh OPTIONS
.Bl -tag -width Ds
-.It Fl c Ar chars
-Set the maximum number of character columns to use
-(unless the input contains lines longer than
-.Ar num
-characters).
+.It Fl c Ar num
+Set maximum number of character columns to
+.Ar num ,
+unless input lines exceed this limit.
.El
.Sh ENVIRONMENT
-.Bl -tag -width COLUMNS
+.Bl -tag -width Ds
.It COLUMNS
-If this variable is set, the value is used as the
-width of the output device.
+The width of the output device.
.El
.Sh HISTORY
.Nm
diff --git a/cols.c b/cols.c
@@ -12,82 +12,74 @@
#include "utf.h"
#include "util.h"
-static size_t chars = 65;
-static int cflag;
-static struct linebuf b = EMPTY_LINEBUF;
-
-static size_t n_columns;
-static size_t n_rows;
-
static void
usage(void)
{
- eprintf("usage: %s [-c chars] [file ...]\n", argv0);
+ eprintf("usage: %s [-c num] [file ...]\n", argv0);
}
int
main(int argc, char *argv[])
{
- size_t i, l, col, len, bytes, maxlen = 0;
- struct winsize w;
FILE *fp;
+ struct winsize w;
+ struct linebuf b = EMPTY_LINEBUF;
+ size_t chars = 65, maxlen = 0, i, j, k, len, bytes, cols, rows;
+ int cflag = 0;
char *p;
ARGBEGIN {
case 'c':
cflag = 1;
- chars = estrtonum(EARGF(usage()), 3, MIN(LLONG_MAX, SIZE_MAX));
+ chars = estrtonum(EARGF(usage()), 1, MIN(LLONG_MAX, SIZE_MAX));
break;
default:
usage();
} ARGEND;
- if (cflag == 0) {
+ if (!cflag) {
if ((p = getenv("COLUMNS")))
chars = estrtonum(p, 1, MIN(LLONG_MAX, SIZE_MAX));
else if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) && w.ws_col > 0)
chars = w.ws_col;
}
- if (argc == 0) {
+ if (!argc) {
getlines(stdin, &b);
- } else for (; argc > 0; argc--, argv++) {
- if (!(fp = fopen(argv[0], "r")))
- eprintf("fopen %s:", argv[0]);
- getlines(fp, &b);
- fclose(fp);
+ } else {
+ for (; *argv; argc--, argv++) {
+ if (!(fp = fopen(*argv, "r"))) {
+ weprintf("fopen %s:", *argv);
+ continue;
+ }
+ getlines(fp, &b);
+ fclose(fp);
+ }
}
- for (l = 0; l < b.nlines; ++l) {
- len = utflen(b.lines[l]);
- bytes = strlen(b.lines[l]);
- if (len > 0 && b.lines[l][bytes - 1] == '\n') {
- b.lines[l][bytes - 1] = '\0';
- --len;
+ for (i = 0; i < b.nlines; i++) {
+ len = utflen(b.lines[i]);
+ bytes = strlen(b.lines[i]);
+ if (len && bytes && b.lines[i][bytes - 1] == '\n') {
+ b.lines[i][bytes - 1] = '\0';
+ len--;
}
if (len > maxlen)
maxlen = len;
- if (maxlen > (chars - 1) / 2)
- break;
}
- n_columns = (chars + 1) / (maxlen + 1);
- if (n_columns <= 1) {
- for (l = 0; l < b.nlines; ++l) {
- fputs(b.lines[l], stdout);
- }
- return 0;
- }
+ for (cols = 1; (cols + 1) * maxlen + cols <= chars; cols++);
+ rows = b.nlines / cols + (b.nlines % cols > 0);
- n_rows = (b.nlines + (n_columns - 1)) / n_columns;
- for (i = 0; i < n_rows; ++i) {
- for (l = i, col = 1; l < b.nlines; l += n_rows, ++col) {
- len = utflen(b.lines[l]);
- fputs(b.lines[l], stdout);
- if (col < n_columns)
- printf("%*s", (int)(maxlen + 1 - len), "");
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols && i + j * rows < b.nlines; j++) {
+ len = utflen(b.lines[i + j * rows]);
+ fputs(b.lines[i + j * rows], stdout);
+ if (j < cols - 1)
+ for (k = len; k < maxlen + 1; k++)
+ putchar(' ');
}
- fputs("\n", stdout);
+ putchar('\n');
}
return 0;