commit a4587b84f82a61fdcb22766163aa0a6c19dc8a84
parent 76ea3fdd52d306faffb8b40842c73639fbbfc957
Author: FRIGN <dev@frign.de>
Date: Wed, 11 Mar 2015 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:
M | 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;
}