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 }