1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include "libbb.h"
32
33static const char fmt_eof[] ALIGN1 = "cmp: EOF on %s\n";
34static const char fmt_differ[] ALIGN1 = "%s %s differ: char %"OFF_FMT"u, line %u\n";
35
36static const char fmt_l_opt[] ALIGN1 = "%.0s%.0s%"OFF_FMT"u %3o %3o\n";
37
38#define OPT_STR "sl"
39#define CMP_OPT_s (1<<0)
40#define CMP_OPT_l (1<<1)
41
42int cmp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
43int cmp_main(int argc UNUSED_PARAM, char **argv)
44{
45 FILE *fp1, *fp2, *outfile = stdout;
46 const char *filename1, *filename2 = "-";
47 off_t skip1 = 0, skip2 = 0, char_pos = 0;
48 int line_pos = 1;
49 const char *fmt;
50 int c1, c2;
51 unsigned opt;
52 int retval = 0;
53
54 opt = getopt32(argv, "^"
55 OPT_STR
56 "\0" "-1"
57 IF_DESKTOP(":?4")
58 IF_NOT_DESKTOP(":?2")
59 ":l--s:s--l"
60 );
61 argv += optind;
62
63 filename1 = *argv;
64 if (*++argv) {
65 filename2 = *argv;
66 if (ENABLE_DESKTOP && *++argv) {
67 skip1 = XATOOFF(*argv);
68 if (*++argv) {
69 skip2 = XATOOFF(*argv);
70 }
71 }
72 }
73
74 xfunc_error_retval = 2;
75 if (opt & CMP_OPT_s)
76 logmode = 0;
77 fp1 = xfopen_stdin(filename1);
78 fp2 = xfopen_stdin(filename2);
79 if (fp1 == fp2) {
80
81
82
83
84 return 0;
85 }
86 logmode = LOGMODE_STDIO;
87
88 if (opt & CMP_OPT_l)
89 fmt = fmt_l_opt;
90 else
91 fmt = fmt_differ;
92
93 if (ENABLE_DESKTOP) {
94 while (skip1) { getc(fp1); skip1--; }
95 while (skip2) { getc(fp2); skip2--; }
96 }
97 do {
98 c1 = getc(fp1);
99 c2 = getc(fp2);
100 ++char_pos;
101 if (c1 != c2) {
102 retval = 1;
103 if (c2 == EOF) {
104
105
106
107
108 fp1 = fp2;
109 filename1 = filename2;
110 c1 = c2;
111 }
112 if (c1 == EOF) {
113 die_if_ferror(fp1, filename1);
114 fmt = fmt_eof;
115 outfile = stderr;
116
117
118 fflush_all();
119 }
120 if (!(opt & CMP_OPT_s)) {
121 if (opt & CMP_OPT_l) {
122 line_pos = c1;
123 }
124 fprintf(outfile, fmt, filename1, filename2, char_pos, line_pos, c2);
125 if (opt) {
126
127
128 continue;
129 }
130 }
131 break;
132 }
133 if (c1 == '\n') {
134 ++line_pos;
135 }
136 } while (c1 != EOF);
137
138 die_if_ferror(fp1, filename1);
139 die_if_ferror(fp2, filename2);
140
141 fflush_stdout_and_exit(retval);
142}
143