[hackers] [sbase] Optimizing comm(1) with the second sent in patch. || Christoph Lohmann

From: <git_AT_suckless.org>
Date: Wed, 19 Jun 2013 21:11:40 +0200

commit 7f88cf7021dc4d221b77bb9359422ae988f8e4ee
Author: Christoph Lohmann <20h_AT_r-36.net>
Date: Wed Jun 19 21:09:50 2013 +0200

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

diff --git a/comm.c b/comm.c
index e693461..586de78 100644
--- a/comm.c
+++ b/comm.c
_AT_@ -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)
_AT_@ -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 = " ";
- 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(' ');
+ }
+ 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 = " ";
- if (sflags & Suppress1)
- tabs = " ";
- 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, '
'))
+ eprintf("comm: '%s': line too long.
", 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
index 86adf77..620390a 100644
--- a/util.h
+++ b/util.h
_AT_@ -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 *));
+
Received on Wed Jun 19 2013 - 21:11:40 CEST

This archive was generated by hypermail 2.3.0 : Wed Jun 19 2013 - 21:12:12 CEST