| 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 } |