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.
This commit is contained in:
parent
76ea3fdd52
commit
a4587b84f8
79
comm.c
79
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]);
|
||||
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(line[0], line[1]);
|
||||
LIMIT(diff, -1, 1);
|
||||
printline((2-diff) % 3, line[MAX(0, diff)]);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
}
|
||||
diff = strcmp(lines[0], lines[1]);
|
||||
diff = CLAMP(diff, -1, 1);
|
||||
printline((2-diff) % 3, lines[MAX(0, diff)]);
|
||||
}
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user