comm.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       comm.c (1863B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <stdio.h>
            3 #include <stdlib.h>
            4 #include <string.h>
            5 
            6 #include "text.h"
            7 #include "util.h"
            8 
            9 static int show = 0x07;
           10 
           11 static void
           12 printline(int pos, struct line *line)
           13 {
           14         int i;
           15 
           16         if (!(show & (0x1 << pos)))
           17                 return;
           18 
           19         for (i = 0; i < pos; i++) {
           20                 if (show & (0x1 << i))
           21                         putchar('\t');
           22         }
           23         fwrite(line->data, 1, line->len, stdout);
           24 }
           25 
           26 static void
           27 usage(void)
           28 {
           29         eprintf("usage: %s [-123] file1 file2\n", argv0);
           30 }
           31 
           32 int
           33 main(int argc, char *argv[])
           34 {
           35         FILE *fp[2];
           36         static struct line line[2];
           37         size_t linecap[2] = { 0, 0 };
           38         ssize_t len;
           39         int ret = 0, i, diff = 0, seenline = 0;
           40 
           41         ARGBEGIN {
           42         case '1':
           43         case '2':
           44         case '3':
           45                 show &= 0x07 ^ (1 << (ARGC() - '1'));
           46                 break;
           47         default:
           48                 usage();
           49         } ARGEND
           50 
           51         if (argc != 2)
           52                 usage();
           53 
           54         for (i = 0; i < 2; i++) {
           55                 if (!strcmp(argv[i], "-")) {
           56                         argv[i] = "<stdin>";
           57                         fp[i] = stdin;
           58                 } else if (!(fp[i] = fopen(argv[i], "r"))) {
           59                         eprintf("fopen %s:", argv[i]);
           60                 }
           61         }
           62 
           63         for (;;) {
           64                 for (i = 0; i < 2; i++) {
           65                         if (diff && i == (diff < 0))
           66                                 continue;
           67                         if ((len = getline(&(line[i].data), &linecap[i],
           68                                            fp[i])) > 0) {
           69                                 line[i].len = len;
           70                                 seenline = 1;
           71                                 continue;
           72                         }
           73                         if (ferror(fp[i]))
           74                                 eprintf("getline %s:", argv[i]);
           75                         if ((diff || seenline) && line[!i].data[0])
           76                                 printline(!i, &line[!i]);
           77                         while ((len = getline(&(line[!i].data), &linecap[!i],
           78                                               fp[!i])) > 0) {
           79                                 line[!i].len = len;
           80                                 printline(!i, &line[!i]);
           81                         }
           82                         if (ferror(fp[!i]))
           83                                 eprintf("getline %s:", argv[!i]);
           84                         goto end;
           85                 }
           86                 diff = linecmp(&line[0], &line[1]);
           87                 LIMIT(diff, -1, 1);
           88                 seenline = 0;
           89                 printline((2 - diff) % 3, &line[MAX(0, diff)]);
           90         }
           91 end:
           92         ret |= fshut(fp[0], argv[0]);
           93         ret |= (fp[0] != fp[1]) && fshut(fp[1], argv[1]);
           94         ret |= fshut(stdout, "<stdout>");
           95 
           96         return ret;
           97 }