diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-12-16 22:18:44 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-12-16 22:18:44 +0000 |
commit | 64dec33725690adf8cbe9dc931b8a0517e09bf1c (patch) | |
tree | 5d78605c22fa0cc8a36e774929c7b3e7dfbad0f4 | |
parent | 1a3fc4a74b65f20a7d8ae92fc68463406f4cb1f6 (diff) | |
download | busybox-w32-64dec33725690adf8cbe9dc931b8a0517e09bf1c.tar.gz busybox-w32-64dec33725690adf8cbe9dc931b8a0517e09bf1c.tar.bz2 busybox-w32-64dec33725690adf8cbe9dc931b8a0517e09bf1c.zip |
diff: fix -q exit code
last_char_is: sacrifice 9 bytes but avoid double-scan
git-svn-id: svn://busybox.net/trunk/busybox@16974 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | coreutils/diff.c | 142 | ||||
-rw-r--r-- | libbb/last_char_is.c | 12 |
2 files changed, 78 insertions, 76 deletions
diff --git a/coreutils/diff.c b/coreutils/diff.c index 2ed26babe..0df9989b7 100644 --- a/coreutils/diff.c +++ b/coreutils/diff.c | |||
@@ -50,8 +50,6 @@ | |||
50 | #define D_SKIPPED2 (1<<8) | 50 | #define D_SKIPPED2 (1<<8) |
51 | 51 | ||
52 | /* Command line options */ | 52 | /* Command line options */ |
53 | static unsigned long cmd_flags; | ||
54 | |||
55 | #define FLAG_a (1<<0) | 53 | #define FLAG_a (1<<0) |
56 | #define FLAG_b (1<<1) | 54 | #define FLAG_b (1<<1) |
57 | #define FLAG_d (1<<2) | 55 | #define FLAG_d (1<<2) |
@@ -68,12 +66,12 @@ static unsigned long cmd_flags; | |||
68 | #define FLAG_w (1<<13) | 66 | #define FLAG_w (1<<13) |
69 | 67 | ||
70 | /* XXX: FIXME: the following variables should be static, but gcc currently | 68 | /* XXX: FIXME: the following variables should be static, but gcc currently |
71 | * creates a much bigger object if we do this. */ | 69 | * creates a much bigger object if we do this. [which version of gcc? --vda] */ |
72 | int context, status; | 70 | int context, status; |
73 | char *start, *label[2]; | 71 | char *start, *label[2]; |
74 | struct stat stb1, stb2; | 72 | struct stat stb1, stb2; |
75 | char **dl; | 73 | char **dl; |
76 | static int dl_count = 0; | 74 | static int dl_count; |
77 | 75 | ||
78 | struct cand { | 76 | struct cand { |
79 | int x; | 77 | int x; |
@@ -116,6 +114,7 @@ static struct context_vec *context_vec_start; | |||
116 | static struct context_vec *context_vec_end; | 114 | static struct context_vec *context_vec_end; |
117 | static struct context_vec *context_vec_ptr; | 115 | static struct context_vec *context_vec_ptr; |
118 | 116 | ||
117 | |||
119 | static void print_only(const char *path, size_t dirlen, const char *entry) | 118 | static void print_only(const char *path, size_t dirlen, const char *entry) |
120 | { | 119 | { |
121 | if (dirlen > 1) | 120 | if (dirlen > 1) |
@@ -123,6 +122,7 @@ static void print_only(const char *path, size_t dirlen, const char *entry) | |||
123 | printf("Only in %.*s: %s\n", (int) dirlen, path, entry); | 122 | printf("Only in %.*s: %s\n", (int) dirlen, path, entry); |
124 | } | 123 | } |
125 | 124 | ||
125 | |||
126 | static void print_status(int val, char *path1, char *path2, char *entry) | 126 | static void print_status(int val, char *path1, char *path2, char *entry) |
127 | { | 127 | { |
128 | const char *const _entry = entry ? entry : ""; | 128 | const char *const _entry = entry ? entry : ""; |
@@ -140,20 +140,20 @@ static void print_status(int val, char *path1, char *path2, char *entry) | |||
140 | printf("Binary files %s and %s differ\n", _path1, _path2); | 140 | printf("Binary files %s and %s differ\n", _path1, _path2); |
141 | break; | 141 | break; |
142 | case D_DIFFER: | 142 | case D_DIFFER: |
143 | if (cmd_flags & FLAG_q) | 143 | if (option_mask32 & FLAG_q) |
144 | printf("Files %s and %s differ\n", _path1, _path2); | 144 | printf("Files %s and %s differ\n", _path1, _path2); |
145 | break; | 145 | break; |
146 | case D_SAME: | 146 | case D_SAME: |
147 | if (cmd_flags & FLAG_s) | 147 | if (option_mask32 & FLAG_s) |
148 | printf("Files %s and %s are identical\n", _path1, _path2); | 148 | printf("Files %s and %s are identical\n", _path1, _path2); |
149 | break; | 149 | break; |
150 | case D_MISMATCH1: | 150 | case D_MISMATCH1: |
151 | printf("File %s is a directory while file %s is a regular file\n", | 151 | printf("File %s is a %s while file %s is a %s\n", |
152 | _path1, _path2); | 152 | _path1, "directory", _path2, "regular file"); |
153 | break; | 153 | break; |
154 | case D_MISMATCH2: | 154 | case D_MISMATCH2: |
155 | printf("File %s is a regular file while file %s is a directory\n", | 155 | printf("File %s is a %s while file %s is a %s\n", |
156 | _path1, _path2); | 156 | _path1, "regular file", _path2, "directory"); |
157 | break; | 157 | break; |
158 | case D_SKIPPED1: | 158 | case D_SKIPPED1: |
159 | printf("File %s is not a regular file or directory and was skipped\n", | 159 | printf("File %s is not a regular file or directory and was skipped\n", |
@@ -170,6 +170,7 @@ static void print_status(int val, char *path1, char *path2, char *entry) | |||
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | ||
173 | |||
173 | /* | 174 | /* |
174 | * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578. | 175 | * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578. |
175 | */ | 176 | */ |
@@ -180,7 +181,7 @@ static int readhash(FILE * f) | |||
180 | 181 | ||
181 | sum = 1; | 182 | sum = 1; |
182 | space = 0; | 183 | space = 0; |
183 | if (!(cmd_flags & FLAG_b) && !(cmd_flags & FLAG_w)) { | 184 | if (!(option_mask32 & FLAG_b) && !(option_mask32 & FLAG_w)) { |
184 | if (FLAG_i) | 185 | if (FLAG_i) |
185 | for (i = 0; (t = getc(f)) != '\n'; i++) { | 186 | for (i = 0; (t = getc(f)) != '\n'; i++) { |
186 | if (t == EOF) { | 187 | if (t == EOF) { |
@@ -209,7 +210,7 @@ static int readhash(FILE * f) | |||
209 | space++; | 210 | space++; |
210 | continue; | 211 | continue; |
211 | default: | 212 | default: |
212 | if (space && !(cmd_flags & FLAG_w)) { | 213 | if (space && !(option_mask32 & FLAG_w)) { |
213 | i++; | 214 | i++; |
214 | space = 0; | 215 | space = 0; |
215 | } | 216 | } |
@@ -234,22 +235,20 @@ static int readhash(FILE * f) | |||
234 | } | 235 | } |
235 | 236 | ||
236 | 237 | ||
237 | |||
238 | /* | 238 | /* |
239 | * Check to see if the given files differ. | 239 | * Check to see if the given files differ. |
240 | * Returns 0 if they are the same, 1 if different, and -1 on error. | 240 | * Returns 0 if they are the same, 1 if different, and -1 on error. |
241 | */ | 241 | */ |
242 | static int files_differ(FILE * f1, FILE * f2, int flags) | 242 | static int files_differ(FILE * f1, FILE * f2, int flags) |
243 | { | 243 | { |
244 | char buf1[BUFSIZ], buf2[BUFSIZ]; | ||
245 | size_t i, j; | 244 | size_t i, j; |
246 | 245 | ||
247 | if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size || | 246 | if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size || |
248 | (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT)) | 247 | (stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT)) |
249 | return 1; | 248 | return 1; |
250 | while (1) { | 249 | while (1) { |
251 | i = fread(buf1, 1, sizeof(buf1), f1); | 250 | i = fread(bb_common_bufsiz1, 1, BUFSIZ/2, f1); |
252 | j = fread(buf2, 1, sizeof(buf2), f2); | 251 | j = fread(bb_common_bufsiz1 + BUFSIZ/2, 1, BUFSIZ/2, f2); |
253 | if (i != j) | 252 | if (i != j) |
254 | return 1; | 253 | return 1; |
255 | if (i == 0 && j == 0) { | 254 | if (i == 0 && j == 0) { |
@@ -257,11 +256,13 @@ static int files_differ(FILE * f1, FILE * f2, int flags) | |||
257 | return 1; | 256 | return 1; |
258 | return 0; | 257 | return 0; |
259 | } | 258 | } |
260 | if (memcmp(buf1, buf2, i) != 0) | 259 | if (memcmp(bb_common_bufsiz1, |
260 | bb_common_bufsiz1 + BUFSIZ/2, i) != 0) | ||
261 | return 1; | 261 | return 1; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | |||
265 | static void prepare(int i, FILE * fd, off_t filesize) | 266 | static void prepare(int i, FILE * fd, off_t filesize) |
266 | { | 267 | { |
267 | struct line *p; | 268 | struct line *p; |
@@ -286,6 +287,7 @@ static void prepare(int i, FILE * fd, off_t filesize) | |||
286 | file[i] = p; | 287 | file[i] = p; |
287 | } | 288 | } |
288 | 289 | ||
290 | |||
289 | static void prune(void) | 291 | static void prune(void) |
290 | { | 292 | { |
291 | int i, j; | 293 | int i, j; |
@@ -303,6 +305,7 @@ static void prune(void) | |||
303 | } | 305 | } |
304 | } | 306 | } |
305 | 307 | ||
308 | |||
306 | static void equiv(struct line *a, int n, struct line *b, int m, int *c) | 309 | static void equiv(struct line *a, int n, struct line *b, int m, int *c) |
307 | { | 310 | { |
308 | int i, j; | 311 | int i, j; |
@@ -330,6 +333,7 @@ static void equiv(struct line *a, int n, struct line *b, int m, int *c) | |||
330 | c[j] = -1; | 333 | c[j] = -1; |
331 | } | 334 | } |
332 | 335 | ||
336 | |||
333 | static int isqrt(int n) | 337 | static int isqrt(int n) |
334 | { | 338 | { |
335 | int y, x = 1; | 339 | int y, x = 1; |
@@ -347,6 +351,7 @@ static int isqrt(int n) | |||
347 | return x; | 351 | return x; |
348 | } | 352 | } |
349 | 353 | ||
354 | |||
350 | static int newcand(int x, int y, int pred) | 355 | static int newcand(int x, int y, int pred) |
351 | { | 356 | { |
352 | struct cand *q; | 357 | struct cand *q; |
@@ -395,7 +400,7 @@ static int stone(int *a, int n, int *b, int *c) | |||
395 | 400 | ||
396 | #if ENABLE_FEATURE_DIFF_MINIMAL | 401 | #if ENABLE_FEATURE_DIFF_MINIMAL |
397 | const unsigned int bound = | 402 | const unsigned int bound = |
398 | (cmd_flags & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n)); | 403 | (option_mask32 & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n)); |
399 | #else | 404 | #else |
400 | const unsigned int bound = MAX(256, isqrt(n)); | 405 | const unsigned int bound = MAX(256, isqrt(n)); |
401 | #endif | 406 | #endif |
@@ -433,6 +438,7 @@ static int stone(int *a, int n, int *b, int *c) | |||
433 | return k; | 438 | return k; |
434 | } | 439 | } |
435 | 440 | ||
441 | |||
436 | static void unravel(int p) | 442 | static void unravel(int p) |
437 | { | 443 | { |
438 | struct cand *q; | 444 | struct cand *q; |
@@ -457,6 +463,7 @@ static void unsort(struct line *f, int l, int *b) | |||
457 | free(a); | 463 | free(a); |
458 | } | 464 | } |
459 | 465 | ||
466 | |||
460 | static int skipline(FILE * f) | 467 | static int skipline(FILE * f) |
461 | { | 468 | { |
462 | int i, c; | 469 | int i, c; |
@@ -493,8 +500,8 @@ static void check(FILE * f1, FILE * f2) | |||
493 | ixnew[j] = ctnew += skipline(f2); | 500 | ixnew[j] = ctnew += skipline(f2); |
494 | j++; | 501 | j++; |
495 | } | 502 | } |
496 | if ((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w) | 503 | if ((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w) |
497 | || (cmd_flags & FLAG_i)) { | 504 | || (option_mask32 & FLAG_i)) { |
498 | while (1) { | 505 | while (1) { |
499 | c = getc(f1); | 506 | c = getc(f1); |
500 | d = getc(f2); | 507 | d = getc(f2); |
@@ -502,13 +509,13 @@ static void check(FILE * f1, FILE * f2) | |||
502 | * GNU diff ignores a missing newline | 509 | * GNU diff ignores a missing newline |
503 | * in one file if bflag || wflag. | 510 | * in one file if bflag || wflag. |
504 | */ | 511 | */ |
505 | if (((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)) && | 512 | if (((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)) && |
506 | ((c == EOF && d == '\n') || (c == '\n' && d == EOF))) { | 513 | ((c == EOF && d == '\n') || (c == '\n' && d == EOF))) { |
507 | break; | 514 | break; |
508 | } | 515 | } |
509 | ctold++; | 516 | ctold++; |
510 | ctnew++; | 517 | ctnew++; |
511 | if ((cmd_flags & FLAG_b) && isspace(c) && isspace(d)) { | 518 | if ((option_mask32 & FLAG_b) && isspace(c) && isspace(d)) { |
512 | do { | 519 | do { |
513 | if (c == '\n') | 520 | if (c == '\n') |
514 | break; | 521 | break; |
@@ -519,7 +526,7 @@ static void check(FILE * f1, FILE * f2) | |||
519 | break; | 526 | break; |
520 | ctnew++; | 527 | ctnew++; |
521 | } while (isspace(d = getc(f2))); | 528 | } while (isspace(d = getc(f2))); |
522 | } else if (cmd_flags & FLAG_w) { | 529 | } else if (option_mask32 & FLAG_w) { |
523 | while (isspace(c) && c != '\n') { | 530 | while (isspace(c) && c != '\n') { |
524 | c = getc(f1); | 531 | c = getc(f1); |
525 | ctold++; | 532 | ctold++; |
@@ -565,6 +572,7 @@ static void check(FILE * f1, FILE * f2) | |||
565 | ixnew[j] = ctnew += skipline(f2); | 572 | ixnew[j] = ctnew += skipline(f2); |
566 | } | 573 | } |
567 | 574 | ||
575 | |||
568 | /* shellsort CACM #201 */ | 576 | /* shellsort CACM #201 */ |
569 | static void sort(struct line *a, int n) | 577 | static void sort(struct line *a, int n) |
570 | { | 578 | { |
@@ -607,6 +615,7 @@ static void uni_range(int a, int b) | |||
607 | printf("%d,0", b); | 615 | printf("%d,0", b); |
608 | } | 616 | } |
609 | 617 | ||
618 | |||
610 | static int fetch(long *f, int a, int b, FILE * lb, int ch) | 619 | static int fetch(long *f, int a, int b, FILE * lb, int ch) |
611 | { | 620 | { |
612 | int i, j, c, lastc, col, nc; | 621 | int i, j, c, lastc, col, nc; |
@@ -618,7 +627,7 @@ static int fetch(long *f, int a, int b, FILE * lb, int ch) | |||
618 | nc = f[i] - f[i - 1]; | 627 | nc = f[i] - f[i - 1]; |
619 | if (ch != '\0') { | 628 | if (ch != '\0') { |
620 | putchar(ch); | 629 | putchar(ch); |
621 | if (cmd_flags & FLAG_T) | 630 | if (option_mask32 & FLAG_T) |
622 | putchar('\t'); | 631 | putchar('\t'); |
623 | } | 632 | } |
624 | col = 0; | 633 | col = 0; |
@@ -627,7 +636,7 @@ static int fetch(long *f, int a, int b, FILE * lb, int ch) | |||
627 | puts("\n\\ No newline at end of file"); | 636 | puts("\n\\ No newline at end of file"); |
628 | return 0; | 637 | return 0; |
629 | } | 638 | } |
630 | if (c == '\t' && (cmd_flags & FLAG_t)) { | 639 | if (c == '\t' && (option_mask32 & FLAG_t)) { |
631 | do { | 640 | do { |
632 | putchar(' '); | 641 | putchar(' '); |
633 | } while (++col & 7); | 642 | } while (++col & 7); |
@@ -640,21 +649,22 @@ static int fetch(long *f, int a, int b, FILE * lb, int ch) | |||
640 | return 0; | 649 | return 0; |
641 | } | 650 | } |
642 | 651 | ||
652 | |||
643 | static int asciifile(FILE * f) | 653 | static int asciifile(FILE * f) |
644 | { | 654 | { |
645 | #if ENABLE_FEATURE_DIFF_BINARY | 655 | #if ENABLE_FEATURE_DIFF_BINARY |
646 | unsigned char buf[BUFSIZ]; | ||
647 | int i, cnt; | 656 | int i, cnt; |
648 | #endif | 657 | #endif |
649 | 658 | ||
650 | if ((cmd_flags & FLAG_a) || f == NULL) | 659 | if ((option_mask32 & FLAG_a) || f == NULL) |
651 | return 1; | 660 | return 1; |
652 | 661 | ||
653 | #if ENABLE_FEATURE_DIFF_BINARY | 662 | #if ENABLE_FEATURE_DIFF_BINARY |
654 | rewind(f); | 663 | rewind(f); |
655 | cnt = fread(buf, 1, sizeof(buf), f); | 664 | cnt = fread(bb_common_bufsiz1, 1, BUFSIZ, f); |
656 | for (i = 0; i < cnt; i++) { | 665 | for (i = 0; i < cnt; i++) { |
657 | if (!isprint(buf[i]) && !isspace(buf[i])) { | 666 | if (!isprint(bb_common_bufsiz1[i]) |
667 | && !isspace(bb_common_bufsiz1[i])) { | ||
658 | return 0; | 668 | return 0; |
659 | } | 669 | } |
660 | } | 670 | } |
@@ -662,6 +672,7 @@ static int asciifile(FILE * f) | |||
662 | return 1; | 672 | return 1; |
663 | } | 673 | } |
664 | 674 | ||
675 | |||
665 | /* dump accumulated "unified" diff changes */ | 676 | /* dump accumulated "unified" diff changes */ |
666 | static void dump_unified_vec(FILE * f1, FILE * f2) | 677 | static void dump_unified_vec(FILE * f1, FILE * f2) |
667 | { | 678 | { |
@@ -735,10 +746,9 @@ static void print_header(const char *file1, const char *file2) | |||
735 | } | 746 | } |
736 | 747 | ||
737 | 748 | ||
738 | |||
739 | /* | 749 | /* |
740 | * Indicate that there is a difference between lines a and b of the from file | 750 | * Indicate that there is a difference between lines a and b of the from file |
741 | * to get to lines c to d of the to file. If a is greater then b then there | 751 | * to get to lines c to d of the to file. If a is greater than b then there |
742 | * are no lines in the from file involved and this means that there were | 752 | * are no lines in the from file involved and this means that there were |
743 | * lines appended (beginning at b). If c is greater than d then there are | 753 | * lines appended (beginning at b). If c is greater than d then there are |
744 | * lines missing from the to file. | 754 | * lines missing from the to file. |
@@ -748,10 +758,10 @@ static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a, | |||
748 | { | 758 | { |
749 | static size_t max_context = 64; | 759 | static size_t max_context = 64; |
750 | 760 | ||
751 | if (a > b && c > d) | 761 | if ((a > b && c > d) || (option_mask32 & FLAG_q)) { |
752 | return; | 762 | anychange = 1; |
753 | if (cmd_flags & FLAG_q) | ||
754 | return; | 763 | return; |
764 | } | ||
755 | 765 | ||
756 | /* | 766 | /* |
757 | * Allocate change records as needed. | 767 | * Allocate change records as needed. |
@@ -771,7 +781,6 @@ static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a, | |||
771 | * Print the context/unidiff header first time through. | 781 | * Print the context/unidiff header first time through. |
772 | */ | 782 | */ |
773 | print_header(file1, file2); | 783 | print_header(file1, file2); |
774 | anychange = 1; | ||
775 | } else if (a > context_vec_ptr->b + (2 * context) + 1 && | 784 | } else if (a > context_vec_ptr->b + (2 * context) + 1 && |
776 | c > context_vec_ptr->d + (2 * context) + 1) { | 785 | c > context_vec_ptr->d + (2 * context) + 1) { |
777 | /* | 786 | /* |
@@ -785,14 +794,12 @@ static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a, | |||
785 | context_vec_ptr->b = b; | 794 | context_vec_ptr->b = b; |
786 | context_vec_ptr->c = c; | 795 | context_vec_ptr->c = c; |
787 | context_vec_ptr->d = d; | 796 | context_vec_ptr->d = d; |
788 | return; | 797 | anychange = 1; |
789 | |||
790 | } | 798 | } |
791 | 799 | ||
792 | 800 | ||
793 | static void output(char *file1, FILE * f1, char *file2, FILE * f2) | 801 | static void output(char *file1, FILE * f1, char *file2, FILE * f2) |
794 | { | 802 | { |
795 | |||
796 | /* Note that j0 and j1 can't be used as they are defined in math.h. | 803 | /* Note that j0 and j1 can't be used as they are defined in math.h. |
797 | * This also allows the rather amusing variable 'j00'... */ | 804 | * This also allows the rather amusing variable 'j00'... */ |
798 | int m, i0, i1, j00, j01; | 805 | int m, i0, i1, j00, j01; |
@@ -816,7 +823,7 @@ static void output(char *file1, FILE * f1, char *file2, FILE * f2) | |||
816 | if (m == 0) { | 823 | if (m == 0) { |
817 | change(file1, f1, file2, f2, 1, 0, 1, len[1]); | 824 | change(file1, f1, file2, f2, 1, 0, 1, len[1]); |
818 | } | 825 | } |
819 | if (anychange != 0) { | 826 | if (anychange != 0 && !(option_mask32 & FLAG_q)) { |
820 | dump_unified_vec(f1, f2); | 827 | dump_unified_vec(f1, f2); |
821 | } | 828 | } |
822 | } | 829 | } |
@@ -883,7 +890,6 @@ static void output(char *file1, FILE * f1, char *file2, FILE * f2) | |||
883 | * 3*(number of k-candidates installed), typically about | 890 | * 3*(number of k-candidates installed), typically about |
884 | * 6n words for files of length n. | 891 | * 6n words for files of length n. |
885 | */ | 892 | */ |
886 | |||
887 | static int diffreg(char *ofile1, char *ofile2, int flags) | 893 | static int diffreg(char *ofile1, char *ofile2, int flags) |
888 | { | 894 | { |
889 | char *file1 = ofile1; | 895 | char *file1 = ofile1; |
@@ -901,25 +907,20 @@ static int diffreg(char *ofile1, char *ofile2, int flags) | |||
901 | if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0) | 907 | if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0) |
902 | goto closem; | 908 | goto closem; |
903 | 909 | ||
910 | f1 = stdin; | ||
904 | if (flags & D_EMPTY1) | 911 | if (flags & D_EMPTY1) |
905 | f1 = xfopen(bb_dev_null, "r"); | 912 | f1 = xfopen(bb_dev_null, "r"); |
906 | else { | 913 | else if (file1[0] != '-' || file1[1]) /* not "-" */ |
907 | if (strcmp(file1, "-") == 0) | 914 | f1 = xfopen(file1, "r"); |
908 | f1 = stdin; | ||
909 | else | ||
910 | f1 = xfopen(file1, "r"); | ||
911 | } | ||
912 | 915 | ||
916 | f2 = stdin; | ||
913 | if (flags & D_EMPTY2) | 917 | if (flags & D_EMPTY2) |
914 | f2 = xfopen(bb_dev_null, "r"); | 918 | f2 = xfopen(bb_dev_null, "r"); |
915 | else { | 919 | else if (file2[0] != '-' || file2[1]) /* not "-" */ |
916 | if (strcmp(file2, "-") == 0) | 920 | f2 = xfopen(file2, "r"); |
917 | f2 = stdin; | ||
918 | else | ||
919 | f2 = xfopen(file2, "r"); | ||
920 | } | ||
921 | 921 | ||
922 | if ((i = files_differ(f1, f2, flags)) == 0) | 922 | i = files_differ(f1, f2, flags); |
923 | if (i == 0) | ||
923 | goto closem; | 924 | goto closem; |
924 | else if (i != 1) { /* 1 == ok */ | 925 | else if (i != 1) { /* 1 == ok */ |
925 | /* error */ | 926 | /* error */ |
@@ -965,7 +966,7 @@ static int diffreg(char *ofile1, char *ofile2, int flags) | |||
965 | check(f1, f2); | 966 | check(f1, f2); |
966 | output(file1, f1, file2, f2); | 967 | output(file1, f1, file2, f2); |
967 | 968 | ||
968 | closem: | 969 | closem: |
969 | if (anychange) { | 970 | if (anychange) { |
970 | status |= 1; | 971 | status |= 1; |
971 | if (rval == D_SAME) | 972 | if (rval == D_SAME) |
@@ -982,10 +983,10 @@ static int diffreg(char *ofile1, char *ofile2, int flags) | |||
982 | return rval; | 983 | return rval; |
983 | } | 984 | } |
984 | 985 | ||
986 | |||
985 | #if ENABLE_FEATURE_DIFF_DIR | 987 | #if ENABLE_FEATURE_DIFF_DIR |
986 | static void do_diff(char *dir1, char *path1, char *dir2, char *path2) | 988 | static void do_diff(char *dir1, char *path1, char *dir2, char *path2) |
987 | { | 989 | { |
988 | |||
989 | int flags = D_HEADER; | 990 | int flags = D_HEADER; |
990 | int val; | 991 | int val; |
991 | 992 | ||
@@ -1023,14 +1024,15 @@ static void do_diff(char *dir1, char *path1, char *dir2, char *path2) | |||
1023 | } | 1024 | } |
1024 | #endif | 1025 | #endif |
1025 | 1026 | ||
1027 | |||
1026 | #if ENABLE_FEATURE_DIFF_DIR | 1028 | #if ENABLE_FEATURE_DIFF_DIR |
1027 | static int dir_strcmp(const void *p1, const void *p2) | 1029 | static int dir_strcmp(const void *p1, const void *p2) |
1028 | { | 1030 | { |
1029 | return strcmp(*(char *const *) p1, *(char *const *) p2); | 1031 | return strcmp(*(char *const *) p1, *(char *const *) p2); |
1030 | } | 1032 | } |
1031 | 1033 | ||
1032 | /* This function adds a filename to dl, the directory listing. */ | ||
1033 | 1034 | ||
1035 | /* This function adds a filename to dl, the directory listing. */ | ||
1034 | static int add_to_dirlist(const char *filename, | 1036 | static int add_to_dirlist(const char *filename, |
1035 | struct stat ATTRIBUTE_UNUSED * sb, void *userdata, | 1037 | struct stat ATTRIBUTE_UNUSED * sb, void *userdata, |
1036 | int depth ATTRIBUTE_UNUSED) | 1038 | int depth ATTRIBUTE_UNUSED) |
@@ -1038,7 +1040,7 @@ static int add_to_dirlist(const char *filename, | |||
1038 | dl_count++; | 1040 | dl_count++; |
1039 | dl = xrealloc(dl, dl_count * sizeof(char *)); | 1041 | dl = xrealloc(dl, dl_count * sizeof(char *)); |
1040 | dl[dl_count - 1] = xstrdup(filename); | 1042 | dl[dl_count - 1] = xstrdup(filename); |
1041 | if (cmd_flags & FLAG_r) { | 1043 | if (option_mask32 & FLAG_r) { |
1042 | int *pp = (int *) userdata; | 1044 | int *pp = (int *) userdata; |
1043 | int path_len = *pp + 1; | 1045 | int path_len = *pp + 1; |
1044 | 1046 | ||
@@ -1047,10 +1049,10 @@ static int add_to_dirlist(const char *filename, | |||
1047 | return TRUE; | 1049 | return TRUE; |
1048 | } | 1050 | } |
1049 | 1051 | ||
1052 | |||
1050 | /* This returns a sorted directory listing. */ | 1053 | /* This returns a sorted directory listing. */ |
1051 | static char **get_dir(char *path) | 1054 | static char **get_dir(char *path) |
1052 | { | 1055 | { |
1053 | |||
1054 | int i; | 1056 | int i; |
1055 | char **retval; | 1057 | char **retval; |
1056 | 1058 | ||
@@ -1068,7 +1070,7 @@ static char **get_dir(char *path) | |||
1068 | dl_count = 0; | 1070 | dl_count = 0; |
1069 | 1071 | ||
1070 | /* Now fill dl with a listing. */ | 1072 | /* Now fill dl with a listing. */ |
1071 | if (cmd_flags & FLAG_r) | 1073 | if (option_mask32 & FLAG_r) |
1072 | recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL, | 1074 | recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL, |
1073 | userdata, 0); | 1075 | userdata, 0); |
1074 | else { | 1076 | else { |
@@ -1095,9 +1097,9 @@ static char **get_dir(char *path) | |||
1095 | return retval; | 1097 | return retval; |
1096 | } | 1098 | } |
1097 | 1099 | ||
1100 | |||
1098 | static void diffdir(char *p1, char *p2) | 1101 | static void diffdir(char *p1, char *p2) |
1099 | { | 1102 | { |
1100 | |||
1101 | char **dirlist1, **dirlist2; | 1103 | char **dirlist1, **dirlist2; |
1102 | char *dp1, *dp2; | 1104 | char *dp1, *dp2; |
1103 | int dirlist1_count, dirlist2_count; | 1105 | int dirlist1_count, dirlist2_count; |
@@ -1144,13 +1146,13 @@ static void diffdir(char *p1, char *p2) | |||
1144 | dirlist1++; | 1146 | dirlist1++; |
1145 | dirlist2++; | 1147 | dirlist2++; |
1146 | } else if (pos < 0) { | 1148 | } else if (pos < 0) { |
1147 | if (cmd_flags & FLAG_N) | 1149 | if (option_mask32 & FLAG_N) |
1148 | do_diff(p1, dp1, p2, NULL); | 1150 | do_diff(p1, dp1, p2, NULL); |
1149 | else | 1151 | else |
1150 | print_only(p1, strlen(p1) + 1, dp1); | 1152 | print_only(p1, strlen(p1) + 1, dp1); |
1151 | dirlist1++; | 1153 | dirlist1++; |
1152 | } else { | 1154 | } else { |
1153 | if (cmd_flags & FLAG_N) | 1155 | if (option_mask32 & FLAG_N) |
1154 | do_diff(p1, NULL, p2, dp2); | 1156 | do_diff(p1, NULL, p2, dp2); |
1155 | else | 1157 | else |
1156 | print_only(p2, strlen(p2) + 1, dp2); | 1158 | print_only(p2, strlen(p2) + 1, dp2); |
@@ -1161,7 +1163,6 @@ static void diffdir(char *p1, char *p2) | |||
1161 | #endif | 1163 | #endif |
1162 | 1164 | ||
1163 | 1165 | ||
1164 | |||
1165 | int diff_main(int argc, char **argv) | 1166 | int diff_main(int argc, char **argv) |
1166 | { | 1167 | { |
1167 | int gotstdin = 0; | 1168 | int gotstdin = 0; |
@@ -1170,10 +1171,11 @@ int diff_main(int argc, char **argv) | |||
1170 | llist_t *L_arg = NULL; | 1171 | llist_t *L_arg = NULL; |
1171 | 1172 | ||
1172 | opt_complementary = "L::"; | 1173 | opt_complementary = "L::"; |
1173 | cmd_flags = getopt32(argc, argv, "abdiL:NqrsS:tTU:wu", | 1174 | getopt32(argc, argv, "abdiL:NqrsS:tTU:wu" |
1175 | "p" /* ignored (for compatibility) */, | ||
1174 | &L_arg, &start, &U_opt); | 1176 | &L_arg, &start, &U_opt); |
1175 | 1177 | ||
1176 | if (cmd_flags & FLAG_L) { | 1178 | if (option_mask32 & FLAG_L) { |
1177 | while (L_arg) { | 1179 | while (L_arg) { |
1178 | if (label[0] == NULL) | 1180 | if (label[0] == NULL) |
1179 | label[0] = L_arg->data; | 1181 | label[0] = L_arg->data; |
@@ -1196,8 +1198,8 @@ int diff_main(int argc, char **argv) | |||
1196 | } | 1198 | } |
1197 | 1199 | ||
1198 | context = 3; /* This is the default number of lines of context. */ | 1200 | context = 3; /* This is the default number of lines of context. */ |
1199 | if (cmd_flags & FLAG_U) { | 1201 | if (option_mask32 & FLAG_U) { |
1200 | context = xatoul_range(U_opt, 1, INT_MAX); | 1202 | context = xatou_range(U_opt, 1, INT_MAX); |
1201 | } | 1203 | } |
1202 | argc -= optind; | 1204 | argc -= optind; |
1203 | argv += optind; | 1205 | argv += optind; |
@@ -1210,12 +1212,12 @@ int diff_main(int argc, char **argv) | |||
1210 | bb_error_msg("missing filename"); | 1212 | bb_error_msg("missing filename"); |
1211 | bb_show_usage(); | 1213 | bb_show_usage(); |
1212 | } | 1214 | } |
1213 | if (strcmp(argv[0], "-") == 0) { | 1215 | if (argv[0][0] == '-' && !argv[0][1]) { /* "-" */ |
1214 | fstat(STDIN_FILENO, &stb1); | 1216 | fstat(STDIN_FILENO, &stb1); |
1215 | gotstdin = 1; | 1217 | gotstdin = 1; |
1216 | } else | 1218 | } else |
1217 | xstat(argv[0], &stb1); | 1219 | xstat(argv[0], &stb1); |
1218 | if (strcmp(argv[1], "-") == 0) { | 1220 | if (argv[1][0] == '-' && !argv[1][1]) { /* "-" */ |
1219 | fstat(STDIN_FILENO, &stb2); | 1221 | fstat(STDIN_FILENO, &stb2); |
1220 | gotstdin = 1; | 1222 | gotstdin = 1; |
1221 | } else | 1223 | } else |
@@ -1239,5 +1241,5 @@ int diff_main(int argc, char **argv) | |||
1239 | } | 1241 | } |
1240 | print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL); | 1242 | print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL); |
1241 | } | 1243 | } |
1242 | exit(status); | 1244 | return status; |
1243 | } | 1245 | } |
diff --git a/libbb/last_char_is.c b/libbb/last_char_is.c index 3616d5916..aaa85ddd9 100644 --- a/libbb/last_char_is.c +++ b/libbb/last_char_is.c | |||
@@ -9,15 +9,15 @@ | |||
9 | 9 | ||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | /* Find out if the last character of a string matches the one given Don't | 12 | /* Find out if the last character of a string matches the one given. |
13 | * underrun the buffer if the string length is 0. Also avoids a possible | 13 | * Don't underrun the buffer if the string length is 0. |
14 | * space-hogging inline of strlen() per usage. | ||
15 | */ | 14 | */ |
16 | char* last_char_is(const char *s, int c) | 15 | char* last_char_is(const char *s, int c) |
17 | { | 16 | { |
18 | if (s) { | 17 | if (s && *s) { |
19 | s = strrchr(s, c); | 18 | size_t sz = strlen(s) - 1; |
20 | if (s && !s[1]) | 19 | s += sz; |
20 | if ( (unsigned char)*s == c) | ||
21 | return (char*)s; | 21 | return (char*)s; |
22 | } | 22 | } |
23 | return NULL; | 23 | return NULL; |