Annotation of src/usr.bin/comm/comm.c, Revision 1.1.1.1
1.1 deraadt 1: /* $NetBSD: comm.c,v 1.10 1995/09/05 19:57:43 jtc Exp $ */
2:
3: /*
4: * Copyright (c) 1989, 1993, 1994
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * Case Larsen.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. Neither the name of the University nor the names of its contributors
23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
39: #ifndef lint
40: static char copyright[] =
41: "@(#) Copyright (c) 1989, 1993, 1994\n\
42: The Regents of the University of California. All rights reserved.\n";
43: #endif /* not lint */
44:
45: #ifndef lint
46: #if 0
47: static char sccsid[] = "@(#)comm.c 8.4 (Berkeley) 5/4/95";
48: #endif
49: static char rcsid[] = "$NetBSD: comm.c,v 1.10 1995/09/05 19:57:43 jtc Exp $";
50: #endif /* not lint */
51:
52: #include <err.h>
53: #include <limits.h>
54: #include <locale.h>
55: #include <stdio.h>
56: #include <stdlib.h>
57: #include <string.h>
58: #include <unistd.h>
59:
60: #define MAXLINELEN (LINE_MAX + 1)
61:
62: char *tabs[] = { "", "\t", "\t\t" };
63:
64: FILE *file __P((const char *));
65: void show __P((FILE *, char *, char *));
66: void usage __P((void));
67:
68: int
69: main(argc, argv)
70: int argc;
71: char **argv;
72: {
73: int comp, file1done, file2done, read1, read2;
74: int ch, flag1, flag2, flag3;
75: FILE *fp1, *fp2;
76: char *col1, *col2, *col3;
77: char **p, line1[MAXLINELEN], line2[MAXLINELEN];
78:
79: setlocale(LC_ALL, "");
80:
81: flag1 = flag2 = flag3 = 1;
82: while ((ch = getopt(argc, argv, "123")) != -1)
83: switch(ch) {
84: case '1':
85: flag1 = 0;
86: break;
87: case '2':
88: flag2 = 0;
89: break;
90: case '3':
91: flag3 = 0;
92: break;
93: case '?':
94: default:
95: usage();
96: }
97: argc -= optind;
98: argv += optind;
99:
100: if (argc != 2)
101: usage();
102:
103: fp1 = file(argv[0]);
104: fp2 = file(argv[1]);
105:
106: /* for each column printed, add another tab offset */
107: p = tabs;
108: col1 = col2 = col3 = NULL;
109: if (flag1)
110: col1 = *p++;
111: if (flag2)
112: col2 = *p++;
113: if (flag3)
114: col3 = *p;
115:
116: for (read1 = read2 = 1;;) {
117: /* read next line, check for EOF */
118: if (read1)
119: file1done = !fgets(line1, MAXLINELEN, fp1);
120: if (read2)
121: file2done = !fgets(line2, MAXLINELEN, fp2);
122:
123: /* if one file done, display the rest of the other file */
124: if (file1done) {
125: if (!file2done && col2)
126: show(fp2, col2, line2);
127: break;
128: }
129: if (file2done) {
130: if (!file1done && col1)
131: show(fp1, col1, line1);
132: break;
133: }
134:
135: /* lines are the same */
136: if (!(comp = strcoll(line1, line2))) {
137: read1 = read2 = 1;
138: if (col3)
139: if (printf("%s%s", col3, line1) < 0)
140: break;
141: continue;
142: }
143:
144: /* lines are different */
145: if (comp < 0) {
146: read1 = 1;
147: read2 = 0;
148: if (col1)
149: if (printf("%s%s", col1, line1) < 0)
150: break;
151: } else {
152: read1 = 0;
153: read2 = 1;
154: if (col2)
155: if (printf("%s%s", col2, line2) < 0)
156: break;
157: }
158: }
159:
160: if (ferror (stdout) || fclose (stdout) == EOF)
161: err(1, "stdout");
162:
163: exit(0);
164: }
165:
166: void
167: show(fp, offset, buf)
168: FILE *fp;
169: char *offset, *buf;
170: {
171: while (printf("%s%s", offset, buf) >= 0 && fgets(buf, MAXLINELEN, fp))
172: ;
173: }
174:
175: FILE *
176: file(name)
177: const char *name;
178: {
179: FILE *fp;
180:
181: if (!strcmp(name, "-"))
182: return (stdin);
183: if ((fp = fopen(name, "r")) == NULL)
184: err(1, "%s", name);
185: return (fp);
186: }
187:
188: void
189: usage()
190: {
191:
192: (void)fprintf(stderr, "usage: comm [-123] file1 file2\n");
193: exit(1);
194: }