aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/diff.c142
-rw-r--r--libbb/last_char_is.c12
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 */
53static 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] */
72int context, status; 70int context, status;
73char *start, *label[2]; 71char *start, *label[2];
74struct stat stb1, stb2; 72struct stat stb1, stb2;
75char **dl; 73char **dl;
76static int dl_count = 0; 74static int dl_count;
77 75
78struct cand { 76struct cand {
79 int x; 77 int x;
@@ -116,6 +114,7 @@ static struct context_vec *context_vec_start;
116static struct context_vec *context_vec_end; 114static struct context_vec *context_vec_end;
117static struct context_vec *context_vec_ptr; 115static struct context_vec *context_vec_ptr;
118 116
117
119static void print_only(const char *path, size_t dirlen, const char *entry) 118static 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
126static void print_status(int val, char *path1, char *path2, char *entry) 126static 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 */
242static int files_differ(FILE * f1, FILE * f2, int flags) 242static 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
265static void prepare(int i, FILE * fd, off_t filesize) 266static 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
289static void prune(void) 291static 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
306static void equiv(struct line *a, int n, struct line *b, int m, int *c) 309static 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
333static int isqrt(int n) 337static 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
350static int newcand(int x, int y, int pred) 355static 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
436static void unravel(int p) 442static 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
460static int skipline(FILE * f) 467static 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 */
569static void sort(struct line *a, int n) 577static 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
610static int fetch(long *f, int a, int b, FILE * lb, int ch) 619static 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
643static int asciifile(FILE * f) 653static 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 */
666static void dump_unified_vec(FILE * f1, FILE * f2) 677static 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
793static void output(char *file1, FILE * f1, char *file2, FILE * f2) 801static 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
887static int diffreg(char *ofile1, char *ofile2, int flags) 893static 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
986static void do_diff(char *dir1, char *path1, char *dir2, char *path2) 988static 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
1027static int dir_strcmp(const void *p1, const void *p2) 1029static 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. */
1034static int add_to_dirlist(const char *filename, 1036static 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. */
1051static char **get_dir(char *path) 1054static 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
1098static void diffdir(char *p1, char *p2) 1101static 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
1165int diff_main(int argc, char **argv) 1166int 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 */
16char* last_char_is(const char *s, int c) 15char* 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;