use standard headers to get declarations; strdup is now in libc
[unix-history] / usr / src / usr.bin / comm / comm.c
CommitLineData
edb4a1e3
KB
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 *
f15db449 8 * %sccs.include.redist.c%
edb4a1e3
KB
9 */
10
11#ifndef lint
12char copyright[] =
13"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
14 All rights reserved.\n";
15#endif /* not lint */
16
17#ifndef lint
aef34388 18static char sccsid[] = "@(#)comm.c 5.7 (Berkeley) %G%";
edb4a1e3
KB
19#endif /* not lint */
20
21#include <sys/file.h>
eabb7d53 22#include <limits.h>
6fe4541f 23#include <stdio.h>
6fe4541f 24
7b82efbd 25#define MAXLINELEN (_POSIX2_LINE_MAX + 1)
edb4a1e3 26
eabb7d53 27char *tabs[] = { "", "\t", "\t\t" };
6fe4541f 28
6fe4541f 29main(argc,argv)
edb4a1e3 30 int argc;
eabb7d53 31 char *argv[];
6fe4541f 32{
edb4a1e3
KB
33 register int comp, file1done, file2done, read1, read2;
34 register char *col1, *col2, *col3;
35 int ch, flag1, flag2, flag3;
eabb7d53 36 FILE *fp1, *fp2, *file();
edb4a1e3 37 char **p, line1[MAXLINELEN], line2[MAXLINELEN];
eabb7d53 38 extern int optind;
edb4a1e3
KB
39
40 flag1 = flag2 = flag3 = 1;
41 while ((ch = getopt(argc, argv, "-123")) != EOF)
42 switch(ch) {
43 case '-':
44 --optind;
45 goto done;
46 case '1':
47 flag1 = 0;
48 break;
49 case '2':
50 flag2 = 0;
51 break;
52 case '3':
53 flag3 = 0;
54 break;
55 case '?':
56 default:
57 usage();
6fe4541f 58 }
edb4a1e3
KB
59done: argc -= optind;
60 argv += optind;
61
62 if (argc != 2)
63 usage();
64
65 fp1 = file(argv[0]);
66 fp2 = file(argv[1]);
67
68 /* for each column printed, add another tab offset */
69 p = tabs;
aef34388 70 col1 = col2 = col3 = NULL;
edb4a1e3
KB
71 if (flag1)
72 col1 = *p++;
73 if (flag2)
74 col2 = *p++;
75 if (flag3)
aef34388 76 col3 = *p;
edb4a1e3
KB
77
78 for (read1 = read2 = 1;;) {
79 /* read next line, check for EOF */
80 if (read1)
81 file1done = !fgets(line1, MAXLINELEN, fp1);
82 if (read2)
83 file2done = !fgets(line2, MAXLINELEN, fp2);
84
85 /* if one file done, display the rest of the other file */
86 if (file1done) {
87 if (!file2done && col2)
2eae07a1 88 show(fp2, col2, line2);
edb4a1e3
KB
89 break;
90 }
91 if (file2done) {
92 if (!file1done && col1)
2eae07a1 93 show(fp1, col1, line1);
edb4a1e3 94 break;
6fe4541f 95 }
6fe4541f 96
edb4a1e3
KB
97 /* lines are the same */
98 if (!(comp = strcmp(line1, line2))) {
99 read1 = read2 = 1;
100 if (col3)
101 (void)printf("%s%s", col3, line1);
102 continue;
103 }
6fe4541f 104
edb4a1e3
KB
105 /* lines are different */
106 if (comp < 0) {
107 read1 = 1;
108 read2 = 0;
109 if (col1)
110 (void)printf("%s%s", col1, line1);
111 } else {
112 read1 = 0;
113 read2 = 1;
114 if (col2)
115 (void)printf("%s%s", col2, line2);
6fe4541f 116 }
6fe4541f 117 }
edb4a1e3 118 exit(0);
6fe4541f
BJ
119}
120
edb4a1e3
KB
121show(fp, offset, buf)
122 FILE *fp;
123 char *offset, *buf;
6fe4541f 124{
edb4a1e3
KB
125 do {
126 (void)printf("%s%s", offset, buf);
127 } while (fgets(buf, MAXLINELEN, fp));
6fe4541f
BJ
128}
129
edb4a1e3
KB
130FILE *
131file(name)
132 char *name;
6fe4541f 133{
edb4a1e3 134 FILE *fp;
6fe4541f 135
edb4a1e3
KB
136 if (!strcmp(name, "-"))
137 return(stdin);
138 if (!(fp = fopen(name, "r"))) {
139 (void)fprintf(stderr, "comm: can't read %s.\n", name);
140 exit(1);
141 }
142 return(fp);
6fe4541f
BJ
143}
144
edb4a1e3 145usage()
6fe4541f 146{
edb4a1e3
KB
147 (void)fprintf(stderr, "usage: comm [-123] [ - ] file1 file2\n");
148 exit(1);
6fe4541f 149}