sbase

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

commit a4587b84f82a61fdcb22766163aa0a6c19dc8a84
parent 76ea3fdd52d306faffb8b40842c73639fbbfc957
Author: FRIGN <dev@frign.de>
Date:   Wed Mar 11 13:39:08 +0100

Audit comm(1)

1) Use the LIMIT()-macro in util.h instead of defining our own.
2) Drop nextline() and finish(), not needed anymore. Use
   fputs in printline instead of printf.
   --> BUGFIX: Finish exited with status 1, but actually should
               exit with status 0 if ferror(f) == 0.
3) Don't use /dev/fd/0 and use idiomatic <stdin> and fp = stdin
   instead.
4) Refactor loop to use getline() instead of some handrolled
   nextline-function.
   --> BUGFIX: Line-length was limited to LINE_MAX before, now
               it's factually unlimited.
5) Combine diff >= 0 and diff <= 0 into one loop with a beginning
   continue-condition (diff && i == (diff < 0)).
6) BUGFIX: If diff == 0, don't print one buffer after EOFing on the
           other.

Diffstat:
comm.c | 79++++++++++++++++++++++++++++---------------------------------------------------
1 file changed, 28 insertions(+), 51 deletions(-)
diff --git a/comm.c b/comm.c @@ -5,8 +5,6 @@ #include "util.h" -#define CLAMP(x, l, h) MIN(h, MAX(l, x)) - static int show = 0x07; static void @@ -21,28 +19,7 @@ printline(int pos, char *line) if (show & (0x1 << i)) putchar('\t'); } - printf("%s", line); -} - -static char * -nextline(char *buf, int n, FILE *f, char *name) -{ - buf = fgets(buf, n, f); - if (!buf && !feof(f)) - eprintf("%s: read error:", name); - if (buf && !strchr(buf, '\n')) - eprintf("%s: line too long\n", name); - return buf; -} - -static void -finish(int pos, FILE *f, char *name) -{ - char buf[LINE_MAX + 1]; - - while (nextline(buf, sizeof(buf), f, name)) - printline(pos, buf); - exit(1); + fputs(line, stdout); } static void @@ -54,9 +31,10 @@ usage(void) int main(int argc, char *argv[]) { - int i, diff = 0; FILE *fp[2]; - char lines[2][LINE_MAX + 1]; + size_t linelen[2] = { 0, 0 }; + int i, diff = 0; + char *line[2] = { NULL, NULL }; ARGBEGIN { case '1': @@ -71,36 +49,35 @@ main(int argc, char *argv[]) if (argc != 2) usage(); - for (i = 0; i < LEN(fp); i++) { - if (argv[i][0] == '-' && !argv[i][1]) - argv[i] = "/dev/fd/0"; - if (!(fp[i] = fopen(argv[i], "r"))) + for (i = 0; i < 2; i++) { + if (argv[i][0] == '-' && !argv[i][1]) { + argv[i] = "<stdin>"; + fp[i] = stdin; + } else if (!(fp[i] = fopen(argv[i], "r"))) { eprintf("fopen %s:", argv[i]); + } } for (;;) { - if (diff <= 0) { - lines[0][0] = '\0'; - if (!nextline(lines[0], sizeof(lines[0]), - fp[0], argv[0])) { - if (lines[1][0] != '\0') - printline(1, lines[1]); - finish(1, fp[1], argv[1]); - } - } - if (diff >= 0) { - lines[1][0] = '\0'; - if (!nextline(lines[1], sizeof(lines[1]), - fp[1], argv[1])) { - if (lines[0][0] != '\0') - printline(0, lines[0]); - finish(0, fp[0], argv[0]); - } + for (i = 0; i < 2; i++) { + if (diff && i == (diff < 0)) + continue; + if (getline(&line[i], &linelen[i], fp[i]) >= 0) + continue; + if (ferror(fp[i])) + eprintf("getline %s:", argv[i]); + if (diff && strlen(line[!i])) + printline(!i, line[!i]); + while (getline(&line[!i], &linelen[!i], fp[!i]) >= 0) + printline(!i, line[!i]); + if (ferror(fp[!i])) + eprintf("getline %s:", argv[!i]); + goto end; } - diff = strcmp(lines[0], lines[1]); - diff = CLAMP(diff, -1, 1); - printline((2-diff) % 3, lines[MAX(0, diff)]); + diff = strcmp(line[0], line[1]); + LIMIT(diff, -1, 1); + printline((2-diff) % 3, line[MAX(0, diff)]); } - +end: return 0; }