2 * Copyright (c) 1989, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * @(#) Copyright (c) 1989, 1993, 1994 The Regents of the University of California. All rights reserved.
33 * @(#)comm.c 8.4 (Berkeley) 5/4/95
34 * $FreeBSD: head/usr.bin/comm/comm.c 227235 2011-11-06 18:49:10Z ed $
50 static const char *tabs
[] = { "", "\t", "\t\t" };
52 static FILE *file(const char *);
53 static wchar_t *convert(const char *);
54 static void show(FILE *, const char *, const char *, char **, size_t *);
55 static void usage(void);
58 main(int argc
, char *argv
[])
60 int comp
, read1
, read2
;
61 int ch
, flag1
, flag2
, flag3
;
63 const char *col1
, *col2
, *col3
;
64 size_t line1len
, line2len
;
67 wchar_t *tline1
, *tline2
;
70 (void) setlocale(LC_ALL
, "");
72 flag1
= flag2
= flag3
= 1;
74 while ((ch
= getopt(argc
, argv
, "123i")) != -1)
101 /* for each column printed, add another tab offset */
103 col1
= col2
= col3
= NULL
;
111 line1len
= line2len
= 0;
112 line1
= line2
= NULL
;
115 for (read1
= read2
= 1;;) {
116 /* read next line, check for EOF */
118 n1
= getline(&line1
, &line1len
, fp1
);
119 if (n1
< 0 && ferror(fp1
))
120 err(1, "%s", argv
[0]);
121 if (n1
> 0 && line1
[n1
- 1] == '\n')
122 line1
[n1
- 1] = '\0';
126 n2
= getline(&line2
, &line2len
, fp2
);
127 if (n2
< 0 && ferror(fp2
))
128 err(1, "%s", argv
[1]);
129 if (n2
> 0 && line2
[n2
- 1] == '\n')
130 line2
[n2
- 1] = '\0';
133 /* if one file done, display the rest of the other file */
135 if (n2
>= 0 && col2
!= NULL
)
136 show(fp2
, argv
[1], col2
, &line2
, &line2len
);
140 if (n1
>= 0 && col1
!= NULL
)
141 show(fp1
, argv
[0], col1
, &line1
, &line1len
);
146 if ((tline1
= convert(line1
)) != NULL
)
147 tline2
= convert(line2
);
148 if (tline1
== NULL
|| tline2
== NULL
)
149 comp
= strcmp(line1
, line2
);
151 comp
= wcscoll(tline1
, tline2
);
157 /* lines are the same */
161 (void)printf("%s%s\n", col3
, line1
);
165 /* lines are different */
170 (void)printf("%s%s\n", col1
, line1
);
175 (void)printf("%s%s\n", col2
, line2
);
182 convert(const char *str
)
187 if ((n
= mbstowcs(NULL
, str
, 0)) == (size_t)-1)
189 if (SIZE_MAX
/ sizeof(*buf
) < n
+ 1)
190 errx(1, "conversion buffer length overflow");
191 if ((buf
= malloc((n
+ 1) * sizeof(*buf
))) == NULL
)
193 if (mbstowcs(buf
, str
, n
+ 1) != n
)
194 errx(1, "internal mbstowcs() error");
197 for (p
= buf
; *p
!= L
'\0'; p
++)
205 show(FILE *fp
, const char *fn
, const char *offset
, char **bufp
, size_t *buflenp
)
210 (void)printf("%s%s\n", offset
, *bufp
);
211 if ((n
= getline(bufp
, buflenp
, fp
)) < 0)
213 if (n
> 0 && (*bufp
)[n
- 1] == '\n')
214 (*bufp
)[n
- 1] = '\0';
221 file(const char *name
)
225 if (!strcmp(name
, "-"))
227 if ((fp
= fopen(name
, "r")) == NULL
) {
236 (void)fprintf(stderr
, "usage: comm [-123i] file1 file2\n");