morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base
Log | Files | Refs

comm.c (1888B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <limits.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include "util.h"
      8 
      9 #define CLAMP(x, l, h) MIN(h, MAX(l, x))
     10 
     11 static int show = 0x07;
     12 
     13 static void
     14 printline(int pos, char *line)
     15 {
     16 	int i;
     17 
     18 	if (!(show & (0x1 << pos)))
     19 		return;
     20 
     21 	for (i = 0; i < pos; i++) {
     22 		if (show & (0x1 << i))
     23 			putchar('\t');
     24 	}
     25 	printf("%s", line);
     26 }
     27 
     28 static char *
     29 nextline(char *buf, int n, FILE *f, char *name)
     30 {
     31 	buf = fgets(buf, n, f);
     32 	if (!buf && !feof(f))
     33 		eprintf("%s: read error:", name);
     34 	if (buf && !strchr(buf, '\n'))
     35 		eprintf("%s: line too long\n", name);
     36 	return buf;
     37 }
     38 
     39 static void
     40 finish(int pos, FILE *f, char *name)
     41 {
     42 	char buf[LINE_MAX + 1];
     43 
     44 	while (nextline(buf, sizeof(buf), f, name))
     45 		printline(pos, buf);
     46 	exit(1);
     47 }
     48 
     49 static void
     50 usage(void)
     51 {
     52 	eprintf("usage: %s [-123] file1 file2\n", argv0);
     53 }
     54 
     55 int
     56 main(int argc, char *argv[])
     57 {
     58 	int i, diff = 0;
     59 	FILE *fp[2];
     60 	char lines[2][LINE_MAX + 1];
     61 
     62 	ARGBEGIN {
     63 	case '1':
     64 	case '2':
     65 	case '3':
     66 		show &= 0x07 ^ (1 << (ARGC() - '1'));
     67 		break;
     68 	default:
     69 		usage();
     70 	} ARGEND;
     71 
     72 	if (argc != 2)
     73 		usage();
     74 
     75 	for (i = 0; i < LEN(fp); i++) {
     76 		if (argv[i][0] == '-' && !argv[i][1])
     77 			argv[i] = "/dev/fd/0";
     78 		if (!(fp[i] = fopen(argv[i], "r")))
     79 			eprintf("fopen %s:", argv[i]);
     80 	}
     81 
     82 	for (;;) {
     83 		if (diff <= 0) {
     84 			lines[0][0] = '\0';
     85 			if (!nextline(lines[0], sizeof(lines[0]),
     86 				     fp[0], argv[0])) {
     87 				if (lines[1][0] != '\0')
     88 					printline(1, lines[1]);
     89 				finish(1, fp[1], argv[1]);
     90 			}
     91 		}
     92 		if (diff >= 0) {
     93 			lines[1][0] = '\0';
     94 			if (!nextline(lines[1], sizeof(lines[1]),
     95 				     fp[1], argv[1])) {
     96 				if (lines[0][0] != '\0')
     97 					printline(0, lines[0]);
     98 				finish(0, fp[0], argv[0]);
     99 			}
    100 		}
    101 		diff = strcmp(lines[0], lines[1]);
    102 		diff = CLAMP(diff, -1, 1);
    103 		printline((2-diff) % 3, lines[MAX(0, diff)]);
    104 	}
    105 
    106 	return 0;
    107 }