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