sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit fbda47b96470c2c9278cf4902fb517a2882137b4
parent 64da0d1ebc6c00b3f1a939cdb6d3abe219850ed7
Author: FRIGN <dev@frign.de>
Date:   Mon, 16 Mar 2015 19:26:42 +0100

Rewrite foldline() in fold(1)

After the audit, I had this noted down as a TODO-item, but
considered the function to be tested enough to hold the line
until I came to rewrite it.
Admittedly, I didn't take a closer look at the previous loop
and there probably were some edge-cases which caused trouble, but
so far so good, the new version of this commit should be safe
and considered audited.

Diffstat:
Mfold.c | 78+++++++++++++++++++++++++++++++++++++-----------------------------------------
1 file changed, 37 insertions(+), 41 deletions(-)

diff --git a/fold.c b/fold.c @@ -3,6 +3,7 @@ #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "util.h" @@ -11,46 +12,41 @@ static int sflag = 0; static size_t width = 80; static void -foldline(const char *str) -{ - size_t i = 0, n = 0, col, j; - int space; - char c; - - do { - space = 0; - for (j = i, col = 0; str[j] && col <= width; j++) { - c = str[j]; - if (!UTF8_POINT(c) && !bflag) - continue; - if (sflag && isspace(c)) { - space = 1; - n = j + 1; - } else if (!space) { - n = j; - } +foldline(const char *str) { + const char *p, *spacesect = NULL; + size_t col, off; - if (!bflag && iscntrl(c)) { - switch(c) { - case '\b': - col--; - break; - case '\r': - col = 0; - break; - case '\t': - col += (col + 1) % 8; - break; - } - } else { - col++; + for (p = str, col = 0; *p && *p != '\n'; p++) { + if (!UTF8_POINT(*p) && !bflag) + continue; + if (col >= width) { + off = (sflag && spacesect) ? spacesect - str : p - str; + if (fwrite(str, 1, off, stdout) != off) + eprintf("fwrite <stdout>:"); + putchar('\n'); + spacesect = NULL; + col = 0; + p = str += off; + } + if (sflag && isspace(*p)) + spacesect = p + 1; + if (!bflag && iscntrl(*p)) { + switch(*p) { + case '\b': + col -= (col > 0); + break; + case '\r': + col = 0; + break; + case '\t': + col += (col + 1) % 8; + break; } + } else { + col++; } - if (fwrite(str + i, 1, n - i, stdout) != n - i) - eprintf("fwrite <stdout>:"); - if (str[n]) - putchar('\n'); - } while (str[i = n] && str[i] != '\n'); + } + fputs(str, stdout); } static void @@ -69,7 +65,7 @@ fold(FILE *fp, const char *fname) static void usage(void) { - eprintf("usage: %s [-bs] [-w width | -width] [FILE...]\n", argv0); + eprintf("usage: %s [-bs] [-w num | -num] [FILE ...]\n", argv0); } int @@ -102,10 +98,10 @@ main(int argc, char *argv[]) if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; - continue; + } else { + fold(fp, *argv); + fclose(fp); } - fold(fp, *argv); - fclose(fp); } }