comm.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
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… | |
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 } |