shithub: riscv

ref: d457233c70ef6aa28861dd2978e92968ffba0920
dir: /sys/src/cmd/comm.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>

#define LB 2048
int	one;
int	two;
int	three;

char	*ldr[3];

Biobuf *ib1;
Biobuf *ib2;
Biobuf *openfil(char*);
int	rd(Biobuf*, char*);
void	wr(char*, int);
void	copy(Biobuf*, char*, int);
int	compare(char*, char*);

void
main(int argc, char *argv[])
{
	int l;
	char	lb1[LB],lb2[LB];

	ldr[0] = "";
	ldr[1] = "\t";
	ldr[2] = "\t\t";
	l = 1;
	ARGBEGIN{
	case '1':
		if(!one) {
			one = 1;
			ldr[1][0] =
			ldr[2][l--] = '\0';
		}
		break;

	case '2':
		if(!two) {
			two = 1;
			ldr[2][l--] = '\0';
		}
		break;

	case '3':
		three = 1;
		break;

	default:
		goto Usage;

	}ARGEND

	if(argc < 2) {
    Usage:
		fprint(2, "usage: comm [-123] file1 file2\n");
		exits("usage");
	}

	ib1 = openfil(argv[0]);
	ib2 = openfil(argv[1]);


	if(rd(ib1,lb1) < 0){
		if(rd(ib2,lb2) < 0)
			exits(0);
		copy(ib2,lb2,2);
	}
	if(rd(ib2,lb2) < 0)
		copy(ib1,lb1,1);

	for(;;){
		switch(compare(lb1,lb2)) {
		case 0:
			wr(lb1,3);
			if(rd(ib1,lb1) < 0) {
				if(rd(ib2,lb2) < 0)
					exits(0);
				copy(ib2,lb2,2);
			}
			if(rd(ib2,lb2) < 0)
				copy(ib1,lb1,1);
			continue;

		case 1:
			wr(lb1,1);
			if(rd(ib1,lb1) < 0)
				copy(ib2,lb2,2);
			continue;

		case 2:
			wr(lb2,2);
			if(rd(ib2,lb2) < 0)
				copy(ib1,lb1,1);
			continue;
		}
	}
}

int
rd(Biobuf *file, char *buf)
{
	int i, c;

	i = 0;
	while((c = Bgetc(file)) != Beof) {
		*buf = c;
		if(c == '\n' || i > LB-2) {
			*buf = '\0';
			return 0;
		}
		i++;
		buf++;
	}
	return -1;
}

void
wr(char *str, int n)
{

	switch(n){
		case 1:
			if(one)
				return;
			break;

		case 2:
			if(two)
				return;
			break;

		case 3:
			if(three)
				return;
	}
	print("%s%s\n", ldr[n-1],str);
}

void
copy(Biobuf *ibuf, char *lbuf, int n)
{
	do
		wr(lbuf,n);
	while(rd(ibuf,lbuf) >= 0);
	exits(0);
}

int
compare(char *a, char *b)
{
	while(*a == *b){
		if(*a == '\0')
			return 0;
		a++;
		b++;
	}
	if(*a < *b)
		return 1;
	return 2;
}

Biobuf*
openfil(char *s)
{
	Biobuf *b;

	if(s[0]=='-' && s[1]==0)
		s = "/fd/0";
	b = Bopen(s, OREAD);
	if(b)
		return b;
	fprint(2,"comm: cannot open %s: %r\n",s);
	exits("open");
	return 0;	/* shut up ken */
}