diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-03-31 11:53:37 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-03-31 11:53:37 +0000 |
commit | 0b5bf45d3252227dc44396efd196b6b97813cecf (patch) | |
tree | e827f36a92e08ab6a501965a9e8aac39a5d57f68 | |
parent | 46390ed829dd770e4dea4630b9ce80bbe4659737 (diff) | |
download | busybox-w32-0b5bf45d3252227dc44396efd196b6b97813cecf.tar.gz busybox-w32-0b5bf45d3252227dc44396efd196b6b97813cecf.tar.bz2 busybox-w32-0b5bf45d3252227dc44396efd196b6b97813cecf.zip |
Patch from Hideki IWAMOTO adding support for 'cmp -n'
-rw-r--r-- | patches/cmp_n.diff | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/patches/cmp_n.diff b/patches/cmp_n.diff new file mode 100644 index 000000000..fc4661cf5 --- /dev/null +++ b/patches/cmp_n.diff | |||
@@ -0,0 +1,377 @@ | |||
1 | Index: coreutils/Config.in | ||
2 | =================================================================== | ||
3 | RCS file: /var/cvs/busybox/coreutils/Config.in,v | ||
4 | retrieving revision 1.24 | ||
5 | diff -u -r1.24 Config.in | ||
6 | --- a/coreutils/Config.in 15 Mar 2004 08:28:19 -0000 1.24 | ||
7 | +++ b/coreutils/Config.in 31 Mar 2004 11:51:17 -0000 | ||
8 | @@ -59,6 +59,21 @@ | ||
9 | cmp is used to compare two files and returns the result | ||
10 | to standard output. | ||
11 | |||
12 | +config CONFIG_FEATURE_CMP_SKIP | ||
13 | + bool " Enable optional arguments SKIP1 and SKIP2" | ||
14 | + default n | ||
15 | + depends on CONFIG_CMP | ||
16 | + help | ||
17 | + SKIP1 and SKIP2 specify how many bytes to ignore | ||
18 | + at the start of each file. | ||
19 | + | ||
20 | +config CONFIG_FEATURE_CMP_LIMIT | ||
21 | + bool " Enable limit of inputs" | ||
22 | + default n | ||
23 | + depends on CONFIG_CMP | ||
24 | + help | ||
25 | + Enable cmp option (-n). | ||
26 | + | ||
27 | config CONFIG_CP | ||
28 | bool "cp" | ||
29 | default n | ||
30 | Index: coreutils/cmp.c | ||
31 | =================================================================== | ||
32 | RCS file: /var/cvs/busybox/coreutils/cmp.c,v | ||
33 | retrieving revision 1.9 | ||
34 | diff -u -r1.9 cmp.c | ||
35 | --- a/coreutils/cmp.c 19 Mar 2003 09:11:32 -0000 1.9 | ||
36 | +++ b/coreutils/cmp.c 31 Mar 2004 11:51:17 -0000 | ||
37 | @@ -39,6 +39,12 @@ | ||
38 | #include <unistd.h> | ||
39 | #include "busybox.h" | ||
40 | |||
41 | +#ifdef CONFIG_FEATURE_CMP_SKIP | ||
42 | +#define MAX_OPTIONAL_ARGS 3 | ||
43 | +#else | ||
44 | +#define MAX_OPTIONAL_ARGS 1 | ||
45 | +#endif | ||
46 | + | ||
47 | static FILE *cmp_xfopen_input(const char *filename) | ||
48 | { | ||
49 | FILE *fp; | ||
50 | @@ -58,12 +64,57 @@ | ||
51 | static const char fmt_l_opt[] = "%.0s%.0s%d %3o %3o\n"; /* nicer gnu format */ | ||
52 | #endif | ||
53 | |||
54 | -static const char opt_chars[] = "sl"; | ||
55 | +#ifdef CONFIG_FEATURE_CMP_LIMIT | ||
56 | +#define OPTCHR_LIMIT "n:" | ||
57 | +#define OPTARG_LIMIT ,&limit_str | ||
58 | +#else | ||
59 | +#define OPTCHR_LIMIT | ||
60 | +#define OPTARG_LIMIT | ||
61 | +#endif | ||
62 | + | ||
63 | +static const char opt_chars[] = "sl" OPTCHR_LIMIT; | ||
64 | |||
65 | enum { | ||
66 | OPT_s = 1, | ||
67 | - OPT_l = 2 | ||
68 | + OPT_l = 2, | ||
69 | + OPT_n = 4 | ||
70 | +}; | ||
71 | + | ||
72 | +#ifdef CONFIG_LFS | ||
73 | +#define SUFFIX_STRUCT suffix_mult64 | ||
74 | +#define PARSE_FUNC bb_xgetllarg10_sfx | ||
75 | +#else | ||
76 | +#define SUFFIX_STRUCT suffix_mult | ||
77 | +#define PARSE_FUNC bb_xgetlarg10_sfx | ||
78 | +#endif | ||
79 | + | ||
80 | +#if defined(CONFIG_FEATURE_CMP_SKIP) || defined(CONFIG_FEATURE_CMP_LIMIT) | ||
81 | +static const struct SUFFIX_STRUCT suffixes[] = { | ||
82 | + { "k", 1UL << 10 }, | ||
83 | + { "M", 1UL << 20 }, | ||
84 | + { "G", 1UL << 30 }, | ||
85 | +#ifdef CONFIG_LFS | ||
86 | + { "T", 1ULL << 40 }, | ||
87 | + { "P", 1ULL << 50 }, | ||
88 | + { "E", 1ULL << 60 }, | ||
89 | +#endif | ||
90 | + { NULL, 0 } | ||
91 | }; | ||
92 | +#endif | ||
93 | + | ||
94 | +#ifdef CONFIG_FEATURE_CMP_SKIP | ||
95 | +static void skip_input(FILE *fp, off_t skip, const char *filename) | ||
96 | +{ | ||
97 | + if (skip > 0 && fseeko(fp, skip, SEEK_CUR) != 0) { | ||
98 | + while (skip-- > 0) { | ||
99 | + if (getc(fp) == EOF) { | ||
100 | + bb_xferror(fp, filename); | ||
101 | + break; | ||
102 | + } | ||
103 | + } | ||
104 | + } | ||
105 | +} | ||
106 | +#endif | ||
107 | |||
108 | int cmp_main(int argc, char **argv) | ||
109 | { | ||
110 | @@ -73,12 +124,26 @@ | ||
111 | int c1, c2, char_pos, line_pos; | ||
112 | int opt_flags; | ||
113 | int exit_val = 0; | ||
114 | +#ifdef CONFIG_FEATURE_CMP_SKIP | ||
115 | + off_t skip1 = 0, skip2 = 0; | ||
116 | +#endif | ||
117 | +#ifdef CONFIG_FEATURE_CMP_LIMIT | ||
118 | + off_t limit = -1; | ||
119 | + char *limit_str; | ||
120 | +#endif | ||
121 | |||
122 | bb_default_error_retval = 2; /* 1 is returned if files are different. */ | ||
123 | |||
124 | - opt_flags = bb_getopt_ulflags(argc, argv, opt_chars); | ||
125 | + opt_flags = bb_getopt_ulflags(argc, argv, opt_chars OPTARG_LIMIT); | ||
126 | |||
127 | - if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > 1)) { | ||
128 | +#ifdef CONFIG_FEATURE_CMP_LIMIT | ||
129 | + if (opt_flags & OPT_n) { | ||
130 | + limit = PARSE_FUNC(limit_str, suffixes); | ||
131 | + opt_flags &= 3; | ||
132 | + } | ||
133 | +#endif | ||
134 | + | ||
135 | + if ((opt_flags == 3) || (((unsigned int)(--argc - optind)) > MAX_OPTIONAL_ARGS)) { | ||
136 | bb_show_usage(); | ||
137 | } | ||
138 | |||
139 | @@ -87,6 +152,13 @@ | ||
140 | filename2 = "-"; | ||
141 | if (*++argv) { | ||
142 | filename2 = *argv; | ||
143 | +#ifdef CONFIG_FEATURE_CMP_SKIP | ||
144 | + if (*++argv) { | ||
145 | + skip1 = PARSE_FUNC(*argv, suffixes); | ||
146 | + if (*++argv) | ||
147 | + skip2 = PARSE_FUNC(*argv, suffixes); | ||
148 | + } | ||
149 | +#endif | ||
150 | } | ||
151 | fp2 = cmp_xfopen_input(filename2); | ||
152 | |||
153 | @@ -98,6 +170,11 @@ | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | +#ifdef CONFIG_FEATURE_CMP_SKIP | ||
158 | + skip_input(fp1, skip1, filename1); | ||
159 | + skip_input(fp2, skip2, filename2); | ||
160 | +#endif | ||
161 | + | ||
162 | fmt = fmt_differ; | ||
163 | if (opt_flags == OPT_l) { | ||
164 | fmt = fmt_l_opt; | ||
165 | @@ -106,6 +183,10 @@ | ||
166 | char_pos = 0; | ||
167 | line_pos = 1; | ||
168 | do { | ||
169 | +#ifdef CONFIG_FEATURE_CMP_LIMIT | ||
170 | + if (limit-- == 0) | ||
171 | + break; | ||
172 | +#endif | ||
173 | c1 = getc(fp1); | ||
174 | c2 = getc(fp2); | ||
175 | ++char_pos; | ||
176 | Index: include/usage.h | ||
177 | =================================================================== | ||
178 | RCS file: /var/cvs/busybox/include/usage.h,v | ||
179 | retrieving revision 1.198 | ||
180 | diff -u -r1.198 usage.h | ||
181 | --- a/include/usage.h 29 Mar 2004 08:20:08 -0000 1.198 | ||
182 | +++ b/include/usage.h 31 Mar 2004 11:51:17 -0000 | ||
183 | @@ -186,14 +186,29 @@ | ||
184 | #define clear_full_usage \ | ||
185 | "Clear screen." | ||
186 | |||
187 | +#ifdef CONFIG_FEATURE_CMP_SKIP | ||
188 | +#define USAGE_CMP_SKIP(a) a | ||
189 | +#else | ||
190 | +#define USAGE_CMP_SKIP(a) | ||
191 | +#endif | ||
192 | + | ||
193 | +#ifdef CONFIG_FEATURE_CMP_LIMIT | ||
194 | +#define USAGE_CMP_LIMIT(a) a | ||
195 | +#else | ||
196 | +#define USAGE_CMP_LIMIT(a) | ||
197 | +#endif | ||
198 | + | ||
199 | #define cmp_trivial_usage \ | ||
200 | - "[OPTION]... FILE1 [FILE2]" | ||
201 | + "[OPTION]... FILE1 [FILE2" USAGE_CMP_SKIP(" [SKIP1 [SKIP2]]") "]" | ||
202 | #define cmp_full_usage \ | ||
203 | - "Compare files.\n\n" \ | ||
204 | + "Compare files.\n" \ | ||
205 | + USAGE_CMP_SKIP("SKIP1 and SKIP2 are the number of bytes to skip in each file.\n") \ | ||
206 | + "\n" \ | ||
207 | "Options:\n" \ | ||
208 | - "\t-l\tWrite the byte numbers (decimal) and values (octal)\n" \ | ||
209 | - "\t\t for all differing bytes.\n" \ | ||
210 | - "\t-s\tquiet mode - do not print" | ||
211 | + "\t-l\t\tWrite the byte numbers (decimal) and values (octal)\n" \ | ||
212 | + "\t\t\t for all differing bytes.\n" \ | ||
213 | + USAGE_CMP_LIMIT("\t-n LIMIT\tCompare at most LIMIT bytes.\n") \ | ||
214 | + "\t-s\t\tquiet mode - do not print" | ||
215 | |||
216 | #define cp_trivial_usage \ | ||
217 | "[OPTION]... SOURCE DEST" | ||
218 | Index: include/libbb.h | ||
219 | =================================================================== | ||
220 | RCS file: /var/cvs/busybox/include/libbb.h,v | ||
221 | retrieving revision 1.129 | ||
222 | diff -u -r1.129 libbb.h | ||
223 | --- a/include/libbb.h 15 Mar 2004 08:28:38 -0000 1.129 | ||
224 | +++ b/include/libbb.h 31 Mar 2004 11:51:17 -0000 | ||
225 | @@ -217,6 +217,21 @@ | ||
226 | const struct suffix_mult *suffixes); | ||
227 | extern long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes); | ||
228 | |||
229 | +struct suffix_mult64 { | ||
230 | + const char *suffix; | ||
231 | + unsigned long long mult; | ||
232 | +}; | ||
233 | + | ||
234 | +extern unsigned long long bb_xgetullarg_bnd_sfx(const char *arg, int base, | ||
235 | + unsigned long long lower, | ||
236 | + unsigned long long upper, | ||
237 | + const struct suffix_mult64 *suffixes); | ||
238 | + | ||
239 | +extern long long bb_xgetllarg_bnd_sfx(const char *arg, int base, | ||
240 | + long long lower, | ||
241 | + long long upper, | ||
242 | + const struct suffix_mult64 *suffixes); | ||
243 | +extern long long bb_xgetllarg10_sfx(const char *arg, const struct suffix_mult64 *suffixes); | ||
244 | |||
245 | //#warning pitchable now? | ||
246 | extern unsigned long bb_xparse_number(const char *numstr, | ||
247 | Index: libbb/Makefile.in | ||
248 | =================================================================== | ||
249 | RCS file: /var/cvs/busybox/libbb/Makefile.in,v | ||
250 | retrieving revision 1.34 | ||
251 | diff -u -r1.34 Makefile.in | ||
252 | --- a/libbb/Makefile.in 6 Mar 2004 22:11:45 -0000 1.34 | ||
253 | +++ b/libbb/Makefile.in 31 Mar 2004 11:51:17 -0000 | ||
254 | @@ -70,7 +70,8 @@ | ||
255 | |||
256 | LIBBB_MSRC3:=$(LIBBB_DIR)xgetularg.c | ||
257 | LIBBB_MOBJ3:=xgetularg_bnd_sfx.o xgetlarg_bnd_sfx.o getlarg10_sfx.o \ | ||
258 | - xgetularg_bnd.o xgetularg10_bnd.o xgetularg10.o | ||
259 | + xgetularg_bnd.o xgetularg10_bnd.o xgetularg10.o \ | ||
260 | + xgetullarg_bnd_sfx.o xgetllarg_bnd_sfx.o xgetllarg10_sfx.o | ||
261 | |||
262 | LIBBB_MSRC4:=$(LIBBB_DIR)/safe_strtol.c | ||
263 | LIBBB_MOBJ4:=safe_strtoi.o safe_strtod.o safe_strtol.o safe_strtoul.o | ||
264 | Index: libbb/xgetularg.c | ||
265 | =================================================================== | ||
266 | RCS file: /var/cvs/busybox/libbb/xgetularg.c,v | ||
267 | retrieving revision 1.2 | ||
268 | diff -u -r1.2 xgetularg.c | ||
269 | --- a/libbb/xgetularg.c 15 Mar 2004 08:28:44 -0000 1.2 | ||
270 | +++ b/libbb/xgetularg.c 31 Mar 2004 11:51:17 -0000 | ||
271 | @@ -158,3 +158,106 @@ | ||
272 | return bb_xgetularg10_bnd(arg, 0, ULONG_MAX); | ||
273 | } | ||
274 | #endif | ||
275 | + | ||
276 | +#ifdef L_xgetullarg_bnd_sfx | ||
277 | +extern | ||
278 | +unsigned long long bb_xgetullarg_bnd_sfx(const char *arg, int base, | ||
279 | + unsigned long long lower, | ||
280 | + unsigned long long upper, | ||
281 | + const struct suffix_mult64 *suffixes) | ||
282 | +{ | ||
283 | + unsigned long long r; | ||
284 | + int old_errno; | ||
285 | + char *e; | ||
286 | + | ||
287 | + assert(arg); | ||
288 | + | ||
289 | + /* Disallow '-' and any leading whitespace. Speed isn't critical here | ||
290 | + * since we're parsing commandline args. So make sure we get the | ||
291 | + * actual isspace function rather than a larger macro implementaion. */ | ||
292 | + if ((*arg == '-') || (isspace)(*arg)) { | ||
293 | + bb_show_usage(); | ||
294 | + } | ||
295 | + | ||
296 | + /* Since this is a lib function, we're not allowed to reset errno to 0. | ||
297 | + * Doing so could break an app that is deferring checking of errno. | ||
298 | + * So, save the old value so that we can restore it if successful. */ | ||
299 | + old_errno = errno; | ||
300 | + errno = 0; | ||
301 | + r = strtoull(arg, &e, base); | ||
302 | + /* Do the initial validity check. Note: The standards do not | ||
303 | + * guarantee that errno is set if no digits were found. So we | ||
304 | + * must test for this explicitly. */ | ||
305 | + if (errno || (arg == e)) { /* error or no digits */ | ||
306 | + bb_show_usage(); | ||
307 | + } | ||
308 | + errno = old_errno; /* Ok. So restore errno. */ | ||
309 | + | ||
310 | + /* Do optional suffix parsing. Allow 'empty' suffix tables. | ||
311 | + * Note that we also all nul suffixes with associated multipliers, | ||
312 | + * to allow for scaling of the arg by some default multiplier. */ | ||
313 | + | ||
314 | + if (suffixes) { | ||
315 | + while (suffixes->suffix) { | ||
316 | + if (strcmp(suffixes->suffix, e) == 0) { | ||
317 | + if (ULONG_LONG_MAX / suffixes->mult < r) { /* Overflow! */ | ||
318 | + bb_show_usage(); | ||
319 | + } | ||
320 | + ++e; | ||
321 | + r *= suffixes->mult; | ||
322 | + break; | ||
323 | + } | ||
324 | + ++suffixes; | ||
325 | + } | ||
326 | + } | ||
327 | + | ||
328 | + /* Finally, check for illegal trailing chars and range limits. */ | ||
329 | + /* Note: although we allow leading space (via stroul), trailing space | ||
330 | + * is an error. It would be easy enough to allow though if desired. */ | ||
331 | + if (*e || (r < lower) || (r > upper)) { | ||
332 | + bb_show_usage(); | ||
333 | + } | ||
334 | + | ||
335 | + return r; | ||
336 | +} | ||
337 | +#endif | ||
338 | + | ||
339 | +#ifdef L_xgetllarg_bnd_sfx | ||
340 | +extern | ||
341 | +long long bb_xgetllarg_bnd_sfx(const char *arg, int base, | ||
342 | + long long lower, | ||
343 | + long long upper, | ||
344 | + const struct suffix_mult64 *suffixes) | ||
345 | +{ | ||
346 | + unsigned long long u = LONG_LONG_MAX; | ||
347 | + long long r; | ||
348 | + const char *p = arg; | ||
349 | + | ||
350 | + if ((*p == '-') && (p[1] != '+')) { | ||
351 | + ++p; | ||
352 | +#if LONG_LONG_MAX == (-(LONG_LONG_MIN + 1)) | ||
353 | + ++u; /* two's complement */ | ||
354 | +#endif | ||
355 | + } | ||
356 | + | ||
357 | + r = bb_xgetullarg_bnd_sfx(p, base, 0, u, suffixes); | ||
358 | + | ||
359 | + if (*arg == '-') { | ||
360 | + r = -r; | ||
361 | + } | ||
362 | + | ||
363 | + if ((r < lower) || (r > upper)) { | ||
364 | + bb_show_usage(); | ||
365 | + } | ||
366 | + | ||
367 | + return r; | ||
368 | +} | ||
369 | +#endif | ||
370 | + | ||
371 | +#ifdef L_xgetllarg10_sfx | ||
372 | +extern | ||
373 | +long long bb_xgetllarg10_sfx(const char *arg, const struct suffix_mult64 *suffixes) | ||
374 | +{ | ||
375 | + return bb_xgetllarg_bnd_sfx(arg, 10, LONG_LONG_MIN, LONG_LONG_MAX, suffixes); | ||
376 | +} | ||
377 | +#endif | ||