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