sbase

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

commit 7f88cf7021dc4d221b77bb9359422ae988f8e4ee
parent e28c17c7cc4955dd0a4b1b2d9f17faa05f9b238e
Author: Christoph Lohmann <20h@r-36.net>
Date:   Wed Jun 19 21:09:50 +0200

Optimizing comm(1) with the second sent in patch.

Diffstat:
comm.c | 146+++++++++++++++++++++++++++++++++----------------------------------------------
util.h | 1+
2 files changed, 61 insertions(+), 86 deletions(-)
diff --git a/comm.c b/comm.c @@ -3,12 +3,16 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <limits.h> #include "util.h" -enum { Suppress1 = 1, Suppress2 = 2, Suppress3 = 4 }; +#define CLAMP(x, l, h) MIN(h, MAX(l, x)) -static void comm(FILE *fp1, const char *s1, FILE *fp2, - const char *s2, int sflags); +static void printline(int, char *); +static char *nextline(char *, int, FILE *, char *); +static void finish(int, FILE *, char *); + +static int show = 0x07; static void usage(void) @@ -19,114 +23,84 @@ usage(void) int main(int argc, char *argv[]) { - int sflags = 0; - FILE *fp1, *fp2; + int i, dif = 0; + FILE *fp[2]; + char lines[2][LINE_MAX+1]; ARGBEGIN { case '1': - sflags |= Suppress1; - break; case '2': - sflags |= Suppress2; - break; case '3': - sflags |= Suppress3; + show &= 0x07 ^ (1 << (ARGC() - '1')); break; default: usage(); } ARGEND; - if (argc < 2) + if(argc != 2) usage(); - if (!(fp1 = fopen(argv[0], "r"))) - eprintf("fopen %s:", argv[0]); - if (!(fp2 = fopen(argv[1], "r"))) - eprintf("fopen %s:", argv[1]); + for(i = 0; i < LEN(fp); i++) { + if(!(fp[i] = fopen(argv[i], "r"))) + eprintf("comm: '%s':", argv[i]); + } - comm(fp1, argv[0], fp2, argv[1], sflags); + for(;;) { + if(dif <= 0) { + if(!nextline(lines[0], sizeof(lines[0]), + fp[0], argv[0])) { + finish(1, fp[1], argv[1]); + } + } + if(dif >= 0) { + if(!nextline(lines[1], sizeof(lines[1]), + fp[1], argv[1])) { + finish(0, fp[0], argv[0]); + } + } + dif = strcmp(lines[0], lines[1]); + dif = CLAMP(dif, -1, 1); + printline((2-dif) % 3, lines[MAX(0, dif)]); + } return 0; } -static void -print_col1(const char *s, int sflags) +void +printline(int pos, char *line) { - if (sflags & Suppress1) - return; - printf("%s", s); -} + int i; -static void -print_col2(const char *s, int sflags) -{ - const char *tabs = "\t"; - if (sflags & Suppress1) - tabs = ""; - if (sflags & Suppress2) + if(!(show & (0x1 << pos))) return; - printf("%s%s", tabs, s); + + for(i = 0; i < pos; i++) { + if(show & (0x1 << i)) + putchar('\t'); + } + printf("%s", line); } -static void -print_col3(const char *s, int sflags) +char * +nextline(char *buf, int n, FILE *f, char *name) { - const char *tabs = "\t\t"; - if (sflags & Suppress1) - tabs = "\t"; - if (sflags & Suppress2) - tabs = ""; - if (sflags & Suppress3) - return; - printf("%s%s", tabs, s); + buf = fgets(buf, n, f); + if(!buf && !feof(f)) + eprintf("comm: '%s':", name); + if(buf && !strchr(buf, '\n')) + eprintf("comm: '%s': line too long.\n", name); + + return buf; } -static void -comm(FILE *fp1, const char *s1, FILE *fp2, const char *s2, int sflags) +void +finish(int pos, FILE *f, char *name) { - char buf1[BUFSIZ], buf2[BUFSIZ]; - bool eof1 = false, eof2 = false; - bool r1 = true, r2 = true; - int ret; - - for (;;) { - if (r1) - if (!fgets(buf1, sizeof buf1, fp1)) - eof1 = true; - if (r2) - if (!fgets(buf2, sizeof buf2, fp2)) - eof2 = true; - - /* If we reached EOF on fp1 then just dump fp2 */ - if (eof1) { - do { - print_col2(buf2, sflags); - } while (fgets(buf2, sizeof buf2, fp2)); - return; - } - /* If we reached EOF on fp2 then just dump fp1 */ - if (eof2) { - do { - print_col1(buf1, sflags); - } while (fgets(buf1, sizeof buf1, fp1)); - return; - } + char buf[LINE_MAX+1]; - ret = strcmp(buf1, buf2); - if (!ret) { - r1 = r2 = true; - print_col3(buf1, sflags); - continue; - } else if (ret < 0) { - r1 = true; - r2 = false; - print_col1(buf1, sflags); - continue; - } else { - r1 = false; - r2 = true; - print_col2(buf2, sflags); - continue; - } - } + while(nextline(buf, sizeof(buf), f, name)) + printline(pos, buf); + + exit(1); } + diff --git a/util.h b/util.h @@ -20,3 +20,4 @@ long estrtol(const char *, int); void fnck(const char *, const char *, int (*)(const char *, const char *)); void putword(const char *); void recurse(const char *, void (*)(const char *)); +