diff --git a/Makefile b/Makefile index d567b1f..7fda874 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ SRC = \ chvt.c \ cksum.c \ cmp.c \ + comm.c \ cp.c \ date.c \ dirname.c \ diff --git a/comm.c b/comm.c new file mode 100644 index 0000000..75cbff2 --- /dev/null +++ b/comm.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include "util.h" + +#define CLAMP(x, l, h) MIN(h, MAX(l, x)) + +static void printline(int, char*); +static char *nextline(char*, int, FILE*, char*); +static void finish(int, FILE*, char*); + +static int show[] = {1, 1, 1}; + +static void +usage(void) +{ + eprintf("usage: comm [-123] file1 file2\n"); +} + +int +main(int argc, char **argv) +{ + int x, dif = 0; + char lines[2][LINE_MAX+1]; + FILE *files[2]; + + ARGBEGIN { + case '1': + case '2': + case '3': + show[ARGC()-'1'] = 0; + break; + default: + usage(); + } ARGEND; + + if(argc != 2) + usage(); + + for(x = 0; x < LEN(files); x++) + if(!(files[x] = fopen(argv[x], "r"))) + eprintf("comm: '%s':", argv[x]); + + for(;;){ + if(dif <= 0) + if(!nextline(lines[0], sizeof *lines, files[0], argv[0])) + finish(1, files[1], argv[1]); + if(dif >= 0) + if(!nextline(lines[1], sizeof *lines, files[1], argv[1])) + finish(0, files[0], argv[0]); + dif = strcmp(lines[0], lines[1]); + dif = CLAMP(dif, -1, 1); + printline((2-dif)%3, lines[MAX(0, dif)]); + } + return 0; +} + +void +printline(int pos, char *line) +{ + int x; + if(!show[pos]) + return; + for(x=0; x