[hackers] [sbase] Audit cols(1) || FRIGN

From: <git_AT_suckless.org>
Date: Sun, 8 Mar 2015 20:15:33 +0100 (CET)

commit 8db0329b8b779342e38135396bf579304c612c2b
Author: FRIGN <dev_AT_frign.de>
Date: Sun Mar 8 19:33:46 2015 +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.

diff --git a/README b/README
index d9d488e..a58fdcf 100644
--- a/README
+++ b/README
_AT_@ -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
index 179ff0a..8bf70fc 100644
--- a/cols.1
+++ b/cols.1
_AT_@ -1,4 +1,4 @@
-.Dd February 19, 2015
+.Dd March 8, 2015
 .Dt COLS 1
 .Os sbase
 .Sh NAME
_AT_@ -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
_AT_@ -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
index a48c576..2833e2f 100644
--- a/cols.c
+++ b/cols.c
_AT_@ -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;
Received on Sun Mar 08 2015 - 20:15:33 CET

This archive was generated by hypermail 2.3.0 : Sun Mar 08 2015 - 20:24:08 CET