mirror of
https://github.com/sheumann/hush.git
synced 2024-12-26 10:32:02 +00:00
diff: fix -q exit code
last_char_is: sacrifice 9 bytes but avoid double-scan
This commit is contained in:
parent
79e77cdbed
commit
6a1d661036
142
coreutils/diff.c
142
coreutils/diff.c
@ -50,8 +50,6 @@
|
|||||||
#define D_SKIPPED2 (1<<8)
|
#define D_SKIPPED2 (1<<8)
|
||||||
|
|
||||||
/* Command line options */
|
/* Command line options */
|
||||||
static unsigned long cmd_flags;
|
|
||||||
|
|
||||||
#define FLAG_a (1<<0)
|
#define FLAG_a (1<<0)
|
||||||
#define FLAG_b (1<<1)
|
#define FLAG_b (1<<1)
|
||||||
#define FLAG_d (1<<2)
|
#define FLAG_d (1<<2)
|
||||||
@ -68,12 +66,12 @@ static unsigned long cmd_flags;
|
|||||||
#define FLAG_w (1<<13)
|
#define FLAG_w (1<<13)
|
||||||
|
|
||||||
/* XXX: FIXME: the following variables should be static, but gcc currently
|
/* XXX: FIXME: the following variables should be static, but gcc currently
|
||||||
* creates a much bigger object if we do this. */
|
* creates a much bigger object if we do this. [which version of gcc? --vda] */
|
||||||
int context, status;
|
int context, status;
|
||||||
char *start, *label[2];
|
char *start, *label[2];
|
||||||
struct stat stb1, stb2;
|
struct stat stb1, stb2;
|
||||||
char **dl;
|
char **dl;
|
||||||
static int dl_count = 0;
|
static int dl_count;
|
||||||
|
|
||||||
struct cand {
|
struct cand {
|
||||||
int x;
|
int x;
|
||||||
@ -116,6 +114,7 @@ static struct context_vec *context_vec_start;
|
|||||||
static struct context_vec *context_vec_end;
|
static struct context_vec *context_vec_end;
|
||||||
static struct context_vec *context_vec_ptr;
|
static struct context_vec *context_vec_ptr;
|
||||||
|
|
||||||
|
|
||||||
static void print_only(const char *path, size_t dirlen, const char *entry)
|
static void print_only(const char *path, size_t dirlen, const char *entry)
|
||||||
{
|
{
|
||||||
if (dirlen > 1)
|
if (dirlen > 1)
|
||||||
@ -123,6 +122,7 @@ static void print_only(const char *path, size_t dirlen, const char *entry)
|
|||||||
printf("Only in %.*s: %s\n", (int) dirlen, path, entry);
|
printf("Only in %.*s: %s\n", (int) dirlen, path, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_status(int val, char *path1, char *path2, char *entry)
|
static void print_status(int val, char *path1, char *path2, char *entry)
|
||||||
{
|
{
|
||||||
const char *const _entry = entry ? entry : "";
|
const char *const _entry = entry ? entry : "";
|
||||||
@ -140,20 +140,20 @@ static void print_status(int val, char *path1, char *path2, char *entry)
|
|||||||
printf("Binary files %s and %s differ\n", _path1, _path2);
|
printf("Binary files %s and %s differ\n", _path1, _path2);
|
||||||
break;
|
break;
|
||||||
case D_DIFFER:
|
case D_DIFFER:
|
||||||
if (cmd_flags & FLAG_q)
|
if (option_mask32 & FLAG_q)
|
||||||
printf("Files %s and %s differ\n", _path1, _path2);
|
printf("Files %s and %s differ\n", _path1, _path2);
|
||||||
break;
|
break;
|
||||||
case D_SAME:
|
case D_SAME:
|
||||||
if (cmd_flags & FLAG_s)
|
if (option_mask32 & FLAG_s)
|
||||||
printf("Files %s and %s are identical\n", _path1, _path2);
|
printf("Files %s and %s are identical\n", _path1, _path2);
|
||||||
break;
|
break;
|
||||||
case D_MISMATCH1:
|
case D_MISMATCH1:
|
||||||
printf("File %s is a directory while file %s is a regular file\n",
|
printf("File %s is a %s while file %s is a %s\n",
|
||||||
_path1, _path2);
|
_path1, "directory", _path2, "regular file");
|
||||||
break;
|
break;
|
||||||
case D_MISMATCH2:
|
case D_MISMATCH2:
|
||||||
printf("File %s is a regular file while file %s is a directory\n",
|
printf("File %s is a %s while file %s is a %s\n",
|
||||||
_path1, _path2);
|
_path1, "regular file", _path2, "directory");
|
||||||
break;
|
break;
|
||||||
case D_SKIPPED1:
|
case D_SKIPPED1:
|
||||||
printf("File %s is not a regular file or directory and was skipped\n",
|
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
|
* Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
|
||||||
*/
|
*/
|
||||||
@ -180,7 +181,7 @@ static int readhash(FILE * f)
|
|||||||
|
|
||||||
sum = 1;
|
sum = 1;
|
||||||
space = 0;
|
space = 0;
|
||||||
if (!(cmd_flags & FLAG_b) && !(cmd_flags & FLAG_w)) {
|
if (!(option_mask32 & FLAG_b) && !(option_mask32 & FLAG_w)) {
|
||||||
if (FLAG_i)
|
if (FLAG_i)
|
||||||
for (i = 0; (t = getc(f)) != '\n'; i++) {
|
for (i = 0; (t = getc(f)) != '\n'; i++) {
|
||||||
if (t == EOF) {
|
if (t == EOF) {
|
||||||
@ -209,7 +210,7 @@ static int readhash(FILE * f)
|
|||||||
space++;
|
space++;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
if (space && !(cmd_flags & FLAG_w)) {
|
if (space && !(option_mask32 & FLAG_w)) {
|
||||||
i++;
|
i++;
|
||||||
space = 0;
|
space = 0;
|
||||||
}
|
}
|
||||||
@ -234,22 +235,20 @@ static int readhash(FILE * f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if the given files differ.
|
* Check to see if the given files differ.
|
||||||
* Returns 0 if they are the same, 1 if different, and -1 on error.
|
* Returns 0 if they are the same, 1 if different, and -1 on error.
|
||||||
*/
|
*/
|
||||||
static int files_differ(FILE * f1, FILE * f2, int flags)
|
static int files_differ(FILE * f1, FILE * f2, int flags)
|
||||||
{
|
{
|
||||||
char buf1[BUFSIZ], buf2[BUFSIZ];
|
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
|
||||||
if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size ||
|
if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size ||
|
||||||
(stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
|
(stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
|
||||||
return 1;
|
return 1;
|
||||||
while (1) {
|
while (1) {
|
||||||
i = fread(buf1, 1, sizeof(buf1), f1);
|
i = fread(bb_common_bufsiz1, 1, BUFSIZ/2, f1);
|
||||||
j = fread(buf2, 1, sizeof(buf2), f2);
|
j = fread(bb_common_bufsiz1 + BUFSIZ/2, 1, BUFSIZ/2, f2);
|
||||||
if (i != j)
|
if (i != j)
|
||||||
return 1;
|
return 1;
|
||||||
if (i == 0 && j == 0) {
|
if (i == 0 && j == 0) {
|
||||||
@ -257,11 +256,13 @@ static int files_differ(FILE * f1, FILE * f2, int flags)
|
|||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (memcmp(buf1, buf2, i) != 0)
|
if (memcmp(bb_common_bufsiz1,
|
||||||
|
bb_common_bufsiz1 + BUFSIZ/2, i) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void prepare(int i, FILE * fd, off_t filesize)
|
static void prepare(int i, FILE * fd, off_t filesize)
|
||||||
{
|
{
|
||||||
struct line *p;
|
struct line *p;
|
||||||
@ -286,6 +287,7 @@ static void prepare(int i, FILE * fd, off_t filesize)
|
|||||||
file[i] = p;
|
file[i] = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void prune(void)
|
static void prune(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -303,6 +305,7 @@ static void prune(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void equiv(struct line *a, int n, struct line *b, int m, int *c)
|
static void equiv(struct line *a, int n, struct line *b, int m, int *c)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -330,6 +333,7 @@ static void equiv(struct line *a, int n, struct line *b, int m, int *c)
|
|||||||
c[j] = -1;
|
c[j] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int isqrt(int n)
|
static int isqrt(int n)
|
||||||
{
|
{
|
||||||
int y, x = 1;
|
int y, x = 1;
|
||||||
@ -347,6 +351,7 @@ static int isqrt(int n)
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int newcand(int x, int y, int pred)
|
static int newcand(int x, int y, int pred)
|
||||||
{
|
{
|
||||||
struct cand *q;
|
struct cand *q;
|
||||||
@ -395,7 +400,7 @@ static int stone(int *a, int n, int *b, int *c)
|
|||||||
|
|
||||||
#if ENABLE_FEATURE_DIFF_MINIMAL
|
#if ENABLE_FEATURE_DIFF_MINIMAL
|
||||||
const unsigned int bound =
|
const unsigned int bound =
|
||||||
(cmd_flags & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n));
|
(option_mask32 & FLAG_d) ? UINT_MAX : MAX(256, isqrt(n));
|
||||||
#else
|
#else
|
||||||
const unsigned int bound = MAX(256, isqrt(n));
|
const unsigned int bound = MAX(256, isqrt(n));
|
||||||
#endif
|
#endif
|
||||||
@ -433,6 +438,7 @@ static int stone(int *a, int n, int *b, int *c)
|
|||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void unravel(int p)
|
static void unravel(int p)
|
||||||
{
|
{
|
||||||
struct cand *q;
|
struct cand *q;
|
||||||
@ -457,6 +463,7 @@ static void unsort(struct line *f, int l, int *b)
|
|||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int skipline(FILE * f)
|
static int skipline(FILE * f)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i, c;
|
||||||
@ -493,8 +500,8 @@ static void check(FILE * f1, FILE * f2)
|
|||||||
ixnew[j] = ctnew += skipline(f2);
|
ixnew[j] = ctnew += skipline(f2);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
if ((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)
|
if ((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)
|
||||||
|| (cmd_flags & FLAG_i)) {
|
|| (option_mask32 & FLAG_i)) {
|
||||||
while (1) {
|
while (1) {
|
||||||
c = getc(f1);
|
c = getc(f1);
|
||||||
d = getc(f2);
|
d = getc(f2);
|
||||||
@ -502,13 +509,13 @@ static void check(FILE * f1, FILE * f2)
|
|||||||
* GNU diff ignores a missing newline
|
* GNU diff ignores a missing newline
|
||||||
* in one file if bflag || wflag.
|
* in one file if bflag || wflag.
|
||||||
*/
|
*/
|
||||||
if (((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)) &&
|
if (((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)) &&
|
||||||
((c == EOF && d == '\n') || (c == '\n' && d == EOF))) {
|
((c == EOF && d == '\n') || (c == '\n' && d == EOF))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ctold++;
|
ctold++;
|
||||||
ctnew++;
|
ctnew++;
|
||||||
if ((cmd_flags & FLAG_b) && isspace(c) && isspace(d)) {
|
if ((option_mask32 & FLAG_b) && isspace(c) && isspace(d)) {
|
||||||
do {
|
do {
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
break;
|
break;
|
||||||
@ -519,7 +526,7 @@ static void check(FILE * f1, FILE * f2)
|
|||||||
break;
|
break;
|
||||||
ctnew++;
|
ctnew++;
|
||||||
} while (isspace(d = getc(f2)));
|
} while (isspace(d = getc(f2)));
|
||||||
} else if (cmd_flags & FLAG_w) {
|
} else if (option_mask32 & FLAG_w) {
|
||||||
while (isspace(c) && c != '\n') {
|
while (isspace(c) && c != '\n') {
|
||||||
c = getc(f1);
|
c = getc(f1);
|
||||||
ctold++;
|
ctold++;
|
||||||
@ -565,6 +572,7 @@ static void check(FILE * f1, FILE * f2)
|
|||||||
ixnew[j] = ctnew += skipline(f2);
|
ixnew[j] = ctnew += skipline(f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* shellsort CACM #201 */
|
/* shellsort CACM #201 */
|
||||||
static void sort(struct line *a, int n)
|
static void sort(struct line *a, int n)
|
||||||
{
|
{
|
||||||
@ -607,6 +615,7 @@ static void uni_range(int a, int b)
|
|||||||
printf("%d,0", b);
|
printf("%d,0", b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int fetch(long *f, int a, int b, FILE * lb, int ch)
|
static int fetch(long *f, int a, int b, FILE * lb, int ch)
|
||||||
{
|
{
|
||||||
int i, j, c, lastc, col, nc;
|
int i, j, c, lastc, col, nc;
|
||||||
@ -618,7 +627,7 @@ static int fetch(long *f, int a, int b, FILE * lb, int ch)
|
|||||||
nc = f[i] - f[i - 1];
|
nc = f[i] - f[i - 1];
|
||||||
if (ch != '\0') {
|
if (ch != '\0') {
|
||||||
putchar(ch);
|
putchar(ch);
|
||||||
if (cmd_flags & FLAG_T)
|
if (option_mask32 & FLAG_T)
|
||||||
putchar('\t');
|
putchar('\t');
|
||||||
}
|
}
|
||||||
col = 0;
|
col = 0;
|
||||||
@ -627,7 +636,7 @@ static int fetch(long *f, int a, int b, FILE * lb, int ch)
|
|||||||
puts("\n\\ No newline at end of file");
|
puts("\n\\ No newline at end of file");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (c == '\t' && (cmd_flags & FLAG_t)) {
|
if (c == '\t' && (option_mask32 & FLAG_t)) {
|
||||||
do {
|
do {
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
} while (++col & 7);
|
} while (++col & 7);
|
||||||
@ -640,21 +649,22 @@ static int fetch(long *f, int a, int b, FILE * lb, int ch)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int asciifile(FILE * f)
|
static int asciifile(FILE * f)
|
||||||
{
|
{
|
||||||
#if ENABLE_FEATURE_DIFF_BINARY
|
#if ENABLE_FEATURE_DIFF_BINARY
|
||||||
unsigned char buf[BUFSIZ];
|
|
||||||
int i, cnt;
|
int i, cnt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((cmd_flags & FLAG_a) || f == NULL)
|
if ((option_mask32 & FLAG_a) || f == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_DIFF_BINARY
|
#if ENABLE_FEATURE_DIFF_BINARY
|
||||||
rewind(f);
|
rewind(f);
|
||||||
cnt = fread(buf, 1, sizeof(buf), f);
|
cnt = fread(bb_common_bufsiz1, 1, BUFSIZ, f);
|
||||||
for (i = 0; i < cnt; i++) {
|
for (i = 0; i < cnt; i++) {
|
||||||
if (!isprint(buf[i]) && !isspace(buf[i])) {
|
if (!isprint(bb_common_bufsiz1[i])
|
||||||
|
&& !isspace(bb_common_bufsiz1[i])) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -662,6 +672,7 @@ static int asciifile(FILE * f)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* dump accumulated "unified" diff changes */
|
/* dump accumulated "unified" diff changes */
|
||||||
static void dump_unified_vec(FILE * f1, FILE * f2)
|
static void dump_unified_vec(FILE * f1, FILE * f2)
|
||||||
{
|
{
|
||||||
@ -735,10 +746,9 @@ static void print_header(const char *file1, const char *file2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Indicate that there is a difference between lines a and b of the from file
|
* Indicate that there is a difference between lines a and b of the from file
|
||||||
* to get to lines c to d of the to file. If a is greater then b then there
|
* to get to lines c to d of the to file. If a is greater than b then there
|
||||||
* are no lines in the from file involved and this means that there were
|
* are no lines in the from file involved and this means that there were
|
||||||
* lines appended (beginning at b). If c is greater than d then there are
|
* lines appended (beginning at b). If c is greater than d then there are
|
||||||
* lines missing from the to file.
|
* lines missing from the to file.
|
||||||
@ -748,10 +758,10 @@ static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a,
|
|||||||
{
|
{
|
||||||
static size_t max_context = 64;
|
static size_t max_context = 64;
|
||||||
|
|
||||||
if (a > b && c > d)
|
if ((a > b && c > d) || (option_mask32 & FLAG_q)) {
|
||||||
return;
|
anychange = 1;
|
||||||
if (cmd_flags & FLAG_q)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate change records as needed.
|
* Allocate change records as needed.
|
||||||
@ -771,7 +781,6 @@ static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a,
|
|||||||
* Print the context/unidiff header first time through.
|
* Print the context/unidiff header first time through.
|
||||||
*/
|
*/
|
||||||
print_header(file1, file2);
|
print_header(file1, file2);
|
||||||
anychange = 1;
|
|
||||||
} else if (a > context_vec_ptr->b + (2 * context) + 1 &&
|
} else if (a > context_vec_ptr->b + (2 * context) + 1 &&
|
||||||
c > context_vec_ptr->d + (2 * context) + 1) {
|
c > context_vec_ptr->d + (2 * context) + 1) {
|
||||||
/*
|
/*
|
||||||
@ -785,14 +794,12 @@ static void change(char *file1, FILE * f1, char *file2, FILE * f2, int a,
|
|||||||
context_vec_ptr->b = b;
|
context_vec_ptr->b = b;
|
||||||
context_vec_ptr->c = c;
|
context_vec_ptr->c = c;
|
||||||
context_vec_ptr->d = d;
|
context_vec_ptr->d = d;
|
||||||
return;
|
anychange = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void output(char *file1, FILE * f1, char *file2, FILE * f2)
|
static void output(char *file1, FILE * f1, char *file2, FILE * f2)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Note that j0 and j1 can't be used as they are defined in math.h.
|
/* Note that j0 and j1 can't be used as they are defined in math.h.
|
||||||
* This also allows the rather amusing variable 'j00'... */
|
* This also allows the rather amusing variable 'j00'... */
|
||||||
int m, i0, i1, j00, j01;
|
int m, i0, i1, j00, j01;
|
||||||
@ -816,7 +823,7 @@ static void output(char *file1, FILE * f1, char *file2, FILE * f2)
|
|||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
change(file1, f1, file2, f2, 1, 0, 1, len[1]);
|
change(file1, f1, file2, f2, 1, 0, 1, len[1]);
|
||||||
}
|
}
|
||||||
if (anychange != 0) {
|
if (anychange != 0 && !(option_mask32 & FLAG_q)) {
|
||||||
dump_unified_vec(f1, f2);
|
dump_unified_vec(f1, f2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -883,7 +890,6 @@ static void output(char *file1, FILE * f1, char *file2, FILE * f2)
|
|||||||
* 3*(number of k-candidates installed), typically about
|
* 3*(number of k-candidates installed), typically about
|
||||||
* 6n words for files of length n.
|
* 6n words for files of length n.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int diffreg(char *ofile1, char *ofile2, int flags)
|
static int diffreg(char *ofile1, char *ofile2, int flags)
|
||||||
{
|
{
|
||||||
char *file1 = ofile1;
|
char *file1 = ofile1;
|
||||||
@ -901,25 +907,20 @@ static int diffreg(char *ofile1, char *ofile2, int flags)
|
|||||||
if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
|
if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
|
||||||
goto closem;
|
goto closem;
|
||||||
|
|
||||||
|
f1 = stdin;
|
||||||
if (flags & D_EMPTY1)
|
if (flags & D_EMPTY1)
|
||||||
f1 = xfopen(bb_dev_null, "r");
|
f1 = xfopen(bb_dev_null, "r");
|
||||||
else {
|
else if (file1[0] != '-' || file1[1]) /* not "-" */
|
||||||
if (strcmp(file1, "-") == 0)
|
f1 = xfopen(file1, "r");
|
||||||
f1 = stdin;
|
|
||||||
else
|
|
||||||
f1 = xfopen(file1, "r");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
f2 = stdin;
|
||||||
if (flags & D_EMPTY2)
|
if (flags & D_EMPTY2)
|
||||||
f2 = xfopen(bb_dev_null, "r");
|
f2 = xfopen(bb_dev_null, "r");
|
||||||
else {
|
else if (file2[0] != '-' || file2[1]) /* not "-" */
|
||||||
if (strcmp(file2, "-") == 0)
|
f2 = xfopen(file2, "r");
|
||||||
f2 = stdin;
|
|
||||||
else
|
|
||||||
f2 = xfopen(file2, "r");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((i = files_differ(f1, f2, flags)) == 0)
|
i = files_differ(f1, f2, flags);
|
||||||
|
if (i == 0)
|
||||||
goto closem;
|
goto closem;
|
||||||
else if (i != 1) { /* 1 == ok */
|
else if (i != 1) { /* 1 == ok */
|
||||||
/* error */
|
/* error */
|
||||||
@ -965,7 +966,7 @@ static int diffreg(char *ofile1, char *ofile2, int flags)
|
|||||||
check(f1, f2);
|
check(f1, f2);
|
||||||
output(file1, f1, file2, f2);
|
output(file1, f1, file2, f2);
|
||||||
|
|
||||||
closem:
|
closem:
|
||||||
if (anychange) {
|
if (anychange) {
|
||||||
status |= 1;
|
status |= 1;
|
||||||
if (rval == D_SAME)
|
if (rval == D_SAME)
|
||||||
@ -982,10 +983,10 @@ static int diffreg(char *ofile1, char *ofile2, int flags)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_DIFF_DIR
|
#if ENABLE_FEATURE_DIFF_DIR
|
||||||
static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
|
static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
|
||||||
{
|
{
|
||||||
|
|
||||||
int flags = D_HEADER;
|
int flags = D_HEADER;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
@ -1023,14 +1024,15 @@ static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_DIFF_DIR
|
#if ENABLE_FEATURE_DIFF_DIR
|
||||||
static int dir_strcmp(const void *p1, const void *p2)
|
static int dir_strcmp(const void *p1, const void *p2)
|
||||||
{
|
{
|
||||||
return strcmp(*(char *const *) p1, *(char *const *) p2);
|
return strcmp(*(char *const *) p1, *(char *const *) p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function adds a filename to dl, the directory listing. */
|
|
||||||
|
|
||||||
|
/* This function adds a filename to dl, the directory listing. */
|
||||||
static int add_to_dirlist(const char *filename,
|
static int add_to_dirlist(const char *filename,
|
||||||
struct stat ATTRIBUTE_UNUSED * sb, void *userdata,
|
struct stat ATTRIBUTE_UNUSED * sb, void *userdata,
|
||||||
int depth ATTRIBUTE_UNUSED)
|
int depth ATTRIBUTE_UNUSED)
|
||||||
@ -1038,7 +1040,7 @@ static int add_to_dirlist(const char *filename,
|
|||||||
dl_count++;
|
dl_count++;
|
||||||
dl = xrealloc(dl, dl_count * sizeof(char *));
|
dl = xrealloc(dl, dl_count * sizeof(char *));
|
||||||
dl[dl_count - 1] = xstrdup(filename);
|
dl[dl_count - 1] = xstrdup(filename);
|
||||||
if (cmd_flags & FLAG_r) {
|
if (option_mask32 & FLAG_r) {
|
||||||
int *pp = (int *) userdata;
|
int *pp = (int *) userdata;
|
||||||
int path_len = *pp + 1;
|
int path_len = *pp + 1;
|
||||||
|
|
||||||
@ -1047,10 +1049,10 @@ static int add_to_dirlist(const char *filename,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This returns a sorted directory listing. */
|
/* This returns a sorted directory listing. */
|
||||||
static char **get_dir(char *path)
|
static char **get_dir(char *path)
|
||||||
{
|
{
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
char **retval;
|
char **retval;
|
||||||
|
|
||||||
@ -1068,7 +1070,7 @@ static char **get_dir(char *path)
|
|||||||
dl_count = 0;
|
dl_count = 0;
|
||||||
|
|
||||||
/* Now fill dl with a listing. */
|
/* Now fill dl with a listing. */
|
||||||
if (cmd_flags & FLAG_r)
|
if (option_mask32 & FLAG_r)
|
||||||
recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL,
|
recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL,
|
||||||
userdata, 0);
|
userdata, 0);
|
||||||
else {
|
else {
|
||||||
@ -1095,9 +1097,9 @@ static char **get_dir(char *path)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void diffdir(char *p1, char *p2)
|
static void diffdir(char *p1, char *p2)
|
||||||
{
|
{
|
||||||
|
|
||||||
char **dirlist1, **dirlist2;
|
char **dirlist1, **dirlist2;
|
||||||
char *dp1, *dp2;
|
char *dp1, *dp2;
|
||||||
int dirlist1_count, dirlist2_count;
|
int dirlist1_count, dirlist2_count;
|
||||||
@ -1144,13 +1146,13 @@ static void diffdir(char *p1, char *p2)
|
|||||||
dirlist1++;
|
dirlist1++;
|
||||||
dirlist2++;
|
dirlist2++;
|
||||||
} else if (pos < 0) {
|
} else if (pos < 0) {
|
||||||
if (cmd_flags & FLAG_N)
|
if (option_mask32 & FLAG_N)
|
||||||
do_diff(p1, dp1, p2, NULL);
|
do_diff(p1, dp1, p2, NULL);
|
||||||
else
|
else
|
||||||
print_only(p1, strlen(p1) + 1, dp1);
|
print_only(p1, strlen(p1) + 1, dp1);
|
||||||
dirlist1++;
|
dirlist1++;
|
||||||
} else {
|
} else {
|
||||||
if (cmd_flags & FLAG_N)
|
if (option_mask32 & FLAG_N)
|
||||||
do_diff(p1, NULL, p2, dp2);
|
do_diff(p1, NULL, p2, dp2);
|
||||||
else
|
else
|
||||||
print_only(p2, strlen(p2) + 1, dp2);
|
print_only(p2, strlen(p2) + 1, dp2);
|
||||||
@ -1161,7 +1163,6 @@ static void diffdir(char *p1, char *p2)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int diff_main(int argc, char **argv)
|
int diff_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int gotstdin = 0;
|
int gotstdin = 0;
|
||||||
@ -1170,10 +1171,11 @@ int diff_main(int argc, char **argv)
|
|||||||
llist_t *L_arg = NULL;
|
llist_t *L_arg = NULL;
|
||||||
|
|
||||||
opt_complementary = "L::";
|
opt_complementary = "L::";
|
||||||
cmd_flags = getopt32(argc, argv, "abdiL:NqrsS:tTU:wu",
|
getopt32(argc, argv, "abdiL:NqrsS:tTU:wu"
|
||||||
|
"p" /* ignored (for compatibility) */,
|
||||||
&L_arg, &start, &U_opt);
|
&L_arg, &start, &U_opt);
|
||||||
|
|
||||||
if (cmd_flags & FLAG_L) {
|
if (option_mask32 & FLAG_L) {
|
||||||
while (L_arg) {
|
while (L_arg) {
|
||||||
if (label[0] == NULL)
|
if (label[0] == NULL)
|
||||||
label[0] = L_arg->data;
|
label[0] = L_arg->data;
|
||||||
@ -1196,8 +1198,8 @@ int diff_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
context = 3; /* This is the default number of lines of context. */
|
context = 3; /* This is the default number of lines of context. */
|
||||||
if (cmd_flags & FLAG_U) {
|
if (option_mask32 & FLAG_U) {
|
||||||
context = xatoul_range(U_opt, 1, INT_MAX);
|
context = xatou_range(U_opt, 1, INT_MAX);
|
||||||
}
|
}
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
@ -1210,12 +1212,12 @@ int diff_main(int argc, char **argv)
|
|||||||
bb_error_msg("missing filename");
|
bb_error_msg("missing filename");
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
if (strcmp(argv[0], "-") == 0) {
|
if (argv[0][0] == '-' && !argv[0][1]) { /* "-" */
|
||||||
fstat(STDIN_FILENO, &stb1);
|
fstat(STDIN_FILENO, &stb1);
|
||||||
gotstdin = 1;
|
gotstdin = 1;
|
||||||
} else
|
} else
|
||||||
xstat(argv[0], &stb1);
|
xstat(argv[0], &stb1);
|
||||||
if (strcmp(argv[1], "-") == 0) {
|
if (argv[1][0] == '-' && !argv[1][1]) { /* "-" */
|
||||||
fstat(STDIN_FILENO, &stb2);
|
fstat(STDIN_FILENO, &stb2);
|
||||||
gotstdin = 1;
|
gotstdin = 1;
|
||||||
} else
|
} else
|
||||||
@ -1239,5 +1241,5 @@ int diff_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL);
|
print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL);
|
||||||
}
|
}
|
||||||
exit(status);
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,15 @@
|
|||||||
|
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
/* Find out if the last character of a string matches the one given Don't
|
/* Find out if the last character of a string matches the one given.
|
||||||
* underrun the buffer if the string length is 0. Also avoids a possible
|
* Don't underrun the buffer if the string length is 0.
|
||||||
* space-hogging inline of strlen() per usage.
|
|
||||||
*/
|
*/
|
||||||
char* last_char_is(const char *s, int c)
|
char* last_char_is(const char *s, int c)
|
||||||
{
|
{
|
||||||
if (s) {
|
if (s && *s) {
|
||||||
s = strrchr(s, c);
|
size_t sz = strlen(s) - 1;
|
||||||
if (s && !s[1])
|
s += sz;
|
||||||
|
if ( (unsigned char)*s == c)
|
||||||
return (char*)s;
|
return (char*)s;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user