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