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