xref: /plan9/sys/src/cmd/comm.c (revision 9c74240406852a66155a96c0daa6f8bf6e19c93e)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 #define LB 2048
6 int	one;
7 int	two;
8 int	three;
9 
10 char	*ldr[3];
11 
12 Biobuf *ib1;
13 Biobuf *ib2;
14 Biobuf *openfil(char*);
15 int	rd(Biobuf*, char*);
16 void	wr(char*, int);
17 void	copy(Biobuf*, char*, int);
18 int	compare(char*, char*);
19 
20 void
main(int argc,char * argv[])21 main(int argc, char *argv[])
22 {
23 	int l;
24 	char	lb1[LB],lb2[LB];
25 
26 	ldr[0] = "";
27 	ldr[1] = "\t";
28 	ldr[2] = "\t\t";
29 	l = 1;
30 	ARGBEGIN{
31 	case '1':
32 		if(!one) {
33 			one = 1;
34 			ldr[1][0] =
35 			ldr[2][l--] = '\0';
36 		}
37 		break;
38 
39 	case '2':
40 		if(!two) {
41 			two = 1;
42 			ldr[2][l--] = '\0';
43 		}
44 		break;
45 
46 	case '3':
47 		three = 1;
48 		break;
49 
50 	default:
51 		goto Usage;
52 
53 	}ARGEND
54 
55 	if(argc < 2) {
56     Usage:
57 		fprint(2, "usage: comm [-123] file1 file2\n");
58 		exits("usage");
59 	}
60 
61 	ib1 = openfil(argv[0]);
62 	ib2 = openfil(argv[1]);
63 
64 
65 	if(rd(ib1,lb1) < 0){
66 		if(rd(ib2,lb2) < 0)
67 			exits(0);
68 		copy(ib2,lb2,2);
69 	}
70 	if(rd(ib2,lb2) < 0)
71 		copy(ib1,lb1,1);
72 
73 	for(;;){
74 		switch(compare(lb1,lb2)) {
75 		case 0:
76 			wr(lb1,3);
77 			if(rd(ib1,lb1) < 0) {
78 				if(rd(ib2,lb2) < 0)
79 					exits(0);
80 				copy(ib2,lb2,2);
81 			}
82 			if(rd(ib2,lb2) < 0)
83 				copy(ib1,lb1,1);
84 			continue;
85 
86 		case 1:
87 			wr(lb1,1);
88 			if(rd(ib1,lb1) < 0)
89 				copy(ib2,lb2,2);
90 			continue;
91 
92 		case 2:
93 			wr(lb2,2);
94 			if(rd(ib2,lb2) < 0)
95 				copy(ib1,lb1,1);
96 			continue;
97 		}
98 	}
99 }
100 
101 int
rd(Biobuf * file,char * buf)102 rd(Biobuf *file, char *buf)
103 {
104 	int i, c;
105 
106 	i = 0;
107 	while((c = Bgetc(file)) != Beof) {
108 		*buf = c;
109 		if(c == '\n' || i > LB-2) {
110 			*buf = '\0';
111 			return 0;
112 		}
113 		i++;
114 		buf++;
115 	}
116 	return -1;
117 }
118 
119 void
wr(char * str,int n)120 wr(char *str, int n)
121 {
122 
123 	switch(n){
124 		case 1:
125 			if(one)
126 				return;
127 			break;
128 
129 		case 2:
130 			if(two)
131 				return;
132 			break;
133 
134 		case 3:
135 			if(three)
136 				return;
137 	}
138 	print("%s%s\n", ldr[n-1],str);
139 }
140 
141 void
copy(Biobuf * ibuf,char * lbuf,int n)142 copy(Biobuf *ibuf, char *lbuf, int n)
143 {
144 	do
145 		wr(lbuf,n);
146 	while(rd(ibuf,lbuf) >= 0);
147 	exits(0);
148 }
149 
150 int
compare(char * a,char * b)151 compare(char *a, char *b)
152 {
153 	while(*a == *b){
154 		if(*a == '\0')
155 			return 0;
156 		a++;
157 		b++;
158 	}
159 	if(*a < *b)
160 		return 1;
161 	return 2;
162 }
163 
164 Biobuf*
openfil(char * s)165 openfil(char *s)
166 {
167 	Biobuf *b;
168 
169 	if(s[0]=='-' && s[1]==0)
170 		s = "/fd/0";
171 	b = Bopen(s, OREAD);
172 	if(b)
173 		return b;
174 	fprint(2,"comm: cannot open %s: %r\n",s);
175 	exits("open");
176 	return 0;	/* shut up ken */
177 }
178