1 /*
2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Case Larsen.
7 *
8 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char copyright[] =
13 "@(#) Copyright (c) 1989, 1993, 1994\n\
14 The Regents of the University of California. All rights reserved.\n";
15 #endif /* not lint */
16
17 #ifndef lint
18 static char sccsid[] = "@(#)comm.c 8.4 (Berkeley) 05/04/95";
19 #endif /* not lint */
20
21 #include <fcntl.h>
22 #include <limits.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28
29 #define MAXLINELEN (LINE_MAX + 1)
30
31 char *tabs[] = { "", "\t", "\t\t" };
32
33 FILE *file __P((char *));
34 void show __P((FILE *, char *, char *));
35 void usage __P((void));
36
37 int
main(argc,argv)38 main(argc, argv)
39 int argc;
40 char *argv[];
41 {
42 int comp, file1done, file2done, read1, read2;
43 int ch, flag1, flag2, flag3;
44 FILE *fp1, *fp2;
45 char *col1, *col2, *col3;
46 char **p, line1[MAXLINELEN], line2[MAXLINELEN];
47
48 flag1 = flag2 = flag3 = 1;
49 while ((ch = getopt(argc, argv, "-123")) != EOF)
50 switch(ch) {
51 case '-':
52 --optind;
53 goto done;
54 case '1':
55 flag1 = 0;
56 break;
57 case '2':
58 flag2 = 0;
59 break;
60 case '3':
61 flag3 = 0;
62 break;
63 case '?':
64 default:
65 usage();
66 }
67 done: argc -= optind;
68 argv += optind;
69
70 if (argc != 2)
71 usage();
72
73 fp1 = file(argv[0]);
74 fp2 = file(argv[1]);
75
76 /* for each column printed, add another tab offset */
77 p = tabs;
78 col1 = col2 = col3 = NULL;
79 if (flag1)
80 col1 = *p++;
81 if (flag2)
82 col2 = *p++;
83 if (flag3)
84 col3 = *p;
85
86 for (read1 = read2 = 1;;) {
87 /* read next line, check for EOF */
88 if (read1)
89 file1done = !fgets(line1, MAXLINELEN, fp1);
90 if (read2)
91 file2done = !fgets(line2, MAXLINELEN, fp2);
92
93 /* if one file done, display the rest of the other file */
94 if (file1done) {
95 if (!file2done && col2)
96 show(fp2, col2, line2);
97 break;
98 }
99 if (file2done) {
100 if (!file1done && col1)
101 show(fp1, col1, line1);
102 break;
103 }
104
105 /* lines are the same */
106 if (!(comp = strcmp(line1, line2))) {
107 read1 = read2 = 1;
108 if (col3)
109 (void)printf("%s%s", col3, line1);
110 continue;
111 }
112
113 /* lines are different */
114 if (comp < 0) {
115 read1 = 1;
116 read2 = 0;
117 if (col1)
118 (void)printf("%s%s", col1, line1);
119 } else {
120 read1 = 0;
121 read2 = 1;
122 if (col2)
123 (void)printf("%s%s", col2, line2);
124 }
125 }
126 exit(0);
127 }
128
129 void
show(fp,offset,buf)130 show(fp, offset, buf)
131 FILE *fp;
132 char *offset, *buf;
133 {
134
135 do {
136 (void)printf("%s%s", offset, buf);
137 } while (fgets(buf, MAXLINELEN, fp));
138 }
139
140 FILE *
file(name)141 file(name)
142 char *name;
143 {
144 FILE *fp;
145
146 if (!strcmp(name, "-"))
147 return (stdin);
148 if ((fp = fopen(name, "r")) == NULL) {
149 (void)fprintf(stderr, "comm: %s: %s\n", name, strerror(errno));
150 exit(1);
151 }
152 return (fp);
153 }
154
155 void
usage()156 usage()
157 {
158
159 (void)fprintf(stderr, "usage: comm [-123] file1 file2\n");
160 exit(1);
161 }
162