sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
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[!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 }