#define D_SKIPPED2 (1<<8)
/* Command line options */
-static unsigned long cmd_flags;
-
#define FLAG_a (1<<0)
#define FLAG_b (1<<1)
#define FLAG_d (1<<2)
#define FLAG_w (1<<13)
/* 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;
char *start, *label[2];
struct stat stb1, stb2;
char **dl;
-static int dl_count = 0;
+static int dl_count;
struct cand {
int x;
static struct context_vec *context_vec_end;
static struct context_vec *context_vec_ptr;
+
static void print_only(const char *path, size_t dirlen, const char *entry)
{
if (dirlen > 1)
printf("Only in %.*s: %s\n", (int) dirlen, path, entry);
}
+
static void print_status(int val, char *path1, char *path2, char *entry)
{
const char *const _entry = entry ? entry : "";
printf("Binary files %s and %s differ\n", _path1, _path2);
break;
case D_DIFFER:
- if (cmd_flags & FLAG_q)
+ if (option_mask32 & FLAG_q)
printf("Files %s and %s differ\n", _path1, _path2);
break;
case D_SAME:
- if (cmd_flags & FLAG_s)
+ if (option_mask32 & FLAG_s)
printf("Files %s and %s are identical\n", _path1, _path2);
break;
case D_MISMATCH1:
- printf("File %s is a directory while file %s is a regular file\n",
- _path1, _path2);
+ printf("File %s is a %s while file %s is a %s\n",
+ _path1, "directory", _path2, "regular file");
break;
case D_MISMATCH2:
- printf("File %s is a regular file while file %s is a directory\n",
- _path1, _path2);
+ printf("File %s is a %s while file %s is a %s\n",
+ _path1, "regular file", _path2, "directory");
break;
case D_SKIPPED1:
printf("File %s is not a regular file or directory and was skipped\n",
}
}
+
/*
* Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
*/
sum = 1;
space = 0;
- if (!(cmd_flags & FLAG_b) && !(cmd_flags & FLAG_w)) {
+ if (!(option_mask32 & FLAG_b) && !(option_mask32 & FLAG_w)) {
if (FLAG_i)
for (i = 0; (t = getc(f)) != '\n'; i++) {
if (t == EOF) {
space++;
continue;
default:
- if (space && !(cmd_flags & FLAG_w)) {
+ if (space && !(option_mask32 & FLAG_w)) {
i++;
space = 0;
}
}
-
/*
* Check to see if the given files differ.
* Returns 0 if they are the same, 1 if different, and -1 on error.
*/
static int files_differ(FILE * f1, FILE * f2, int flags)
{
- char buf1[BUFSIZ], buf2[BUFSIZ];
size_t i, j;
if ((flags & (D_EMPTY1 | D_EMPTY2)) || stb1.st_size != stb2.st_size ||
(stb1.st_mode & S_IFMT) != (stb2.st_mode & S_IFMT))
return 1;
while (1) {
- i = fread(buf1, 1, sizeof(buf1), f1);
- j = fread(buf2, 1, sizeof(buf2), f2);
+ i = fread(bb_common_bufsiz1, 1, BUFSIZ/2, f1);
+ j = fread(bb_common_bufsiz1 + BUFSIZ/2, 1, BUFSIZ/2, f2);
if (i != j)
return 1;
if (i == 0 && j == 0) {
return 1;
return 0;
}
- if (memcmp(buf1, buf2, i) != 0)
+ if (memcmp(bb_common_bufsiz1,
+ bb_common_bufsiz1 + BUFSIZ/2, i) != 0)
return 1;
}
}
+
static void prepare(int i, FILE * fd, off_t filesize)
{
struct line *p;
file[i] = p;
}
+
static void prune(void)
{
int i, j;
}
}
+
static void equiv(struct line *a, int n, struct line *b, int m, int *c)
{
int i, j;
c[j] = -1;
}
+
static int isqrt(int n)
{
int y, x = 1;
return x;
}
+
static int newcand(int x, int y, int pred)
{
struct cand *q;
#if ENABLE_FEATURE_DIFF_MINIMAL
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
const unsigned int bound = MAX(256, isqrt(n));
#endif
return k;
}
+
static void unravel(int p)
{
struct cand *q;
free(a);
}
+
static int skipline(FILE * f)
{
int i, c;
ixnew[j] = ctnew += skipline(f2);
j++;
}
- if ((cmd_flags & FLAG_b) || (cmd_flags & FLAG_w)
- || (cmd_flags & FLAG_i)) {
+ if ((option_mask32 & FLAG_b) || (option_mask32 & FLAG_w)
+ || (option_mask32 & FLAG_i)) {
while (1) {
c = getc(f1);
d = getc(f2);
* GNU diff ignores a missing newline
* 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))) {
break;
}
ctold++;
ctnew++;
- if ((cmd_flags & FLAG_b) && isspace(c) && isspace(d)) {
+ if ((option_mask32 & FLAG_b) && isspace(c) && isspace(d)) {
do {
if (c == '\n')
break;
break;
ctnew++;
} while (isspace(d = getc(f2)));
- } else if (cmd_flags & FLAG_w) {
+ } else if (option_mask32 & FLAG_w) {
while (isspace(c) && c != '\n') {
c = getc(f1);
ctold++;
ixnew[j] = ctnew += skipline(f2);
}
+
/* shellsort CACM #201 */
static void sort(struct line *a, int n)
{
printf("%d,0", b);
}
+
static int fetch(long *f, int a, int b, FILE * lb, int ch)
{
int i, j, c, lastc, col, nc;
nc = f[i] - f[i - 1];
if (ch != '\0') {
putchar(ch);
- if (cmd_flags & FLAG_T)
+ if (option_mask32 & FLAG_T)
putchar('\t');
}
col = 0;
puts("\n\\ No newline at end of file");
return 0;
}
- if (c == '\t' && (cmd_flags & FLAG_t)) {
+ if (c == '\t' && (option_mask32 & FLAG_t)) {
do {
putchar(' ');
} while (++col & 7);
return 0;
}
+
static int asciifile(FILE * f)
{
#if ENABLE_FEATURE_DIFF_BINARY
- unsigned char buf[BUFSIZ];
int i, cnt;
#endif
- if ((cmd_flags & FLAG_a) || f == NULL)
+ if ((option_mask32 & FLAG_a) || f == NULL)
return 1;
#if ENABLE_FEATURE_DIFF_BINARY
rewind(f);
- cnt = fread(buf, 1, sizeof(buf), f);
+ cnt = fread(bb_common_bufsiz1, 1, BUFSIZ, f);
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 1;
}
+
/* dump accumulated "unified" diff changes */
static void dump_unified_vec(FILE * f1, FILE * f2)
{
}
-
/*
* 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
* lines appended (beginning at b). If c is greater than d then there are
* lines missing from the to file.
{
static size_t max_context = 64;
- if (a > b && c > d)
- return;
- if (cmd_flags & FLAG_q)
+ if ((a > b && c > d) || (option_mask32 & FLAG_q)) {
+ anychange = 1;
return;
+ }
/*
* Allocate change records as needed.
* Print the context/unidiff header first time through.
*/
print_header(file1, file2);
- anychange = 1;
} else if (a > context_vec_ptr->b + (2 * context) + 1 &&
c > context_vec_ptr->d + (2 * context) + 1) {
/*
context_vec_ptr->b = b;
context_vec_ptr->c = c;
context_vec_ptr->d = d;
- return;
-
+ anychange = 1;
}
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.
* This also allows the rather amusing variable 'j00'... */
int m, i0, i1, j00, j01;
if (m == 0) {
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);
}
}
* 3*(number of k-candidates installed), typically about
* 6n words for files of length n.
*/
-
static int diffreg(char *ofile1, char *ofile2, int flags)
{
char *file1 = ofile1;
if (strcmp(file1, "-") == 0 && strcmp(file2, "-") == 0)
goto closem;
+ f1 = stdin;
if (flags & D_EMPTY1)
f1 = xfopen(bb_dev_null, "r");
- else {
- if (strcmp(file1, "-") == 0)
- f1 = stdin;
- else
- f1 = xfopen(file1, "r");
- }
+ else if (file1[0] != '-' || file1[1]) /* not "-" */
+ f1 = xfopen(file1, "r");
+ f2 = stdin;
if (flags & D_EMPTY2)
f2 = xfopen(bb_dev_null, "r");
- else {
- if (strcmp(file2, "-") == 0)
- f2 = stdin;
- else
- f2 = xfopen(file2, "r");
- }
+ else if (file2[0] != '-' || file2[1]) /* not "-" */
+ f2 = xfopen(file2, "r");
- if ((i = files_differ(f1, f2, flags)) == 0)
+ i = files_differ(f1, f2, flags);
+ if (i == 0)
goto closem;
else if (i != 1) { /* 1 == ok */
/* error */
check(f1, f2);
output(file1, f1, file2, f2);
- closem:
+ closem:
if (anychange) {
status |= 1;
if (rval == D_SAME)
return rval;
}
+
#if ENABLE_FEATURE_DIFF_DIR
static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
{
-
int flags = D_HEADER;
int val;
}
#endif
+
#if ENABLE_FEATURE_DIFF_DIR
static int dir_strcmp(const void *p1, const void *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,
struct stat ATTRIBUTE_UNUSED * sb, void *userdata,
int depth ATTRIBUTE_UNUSED)
dl_count++;
dl = xrealloc(dl, dl_count * sizeof(char *));
dl[dl_count - 1] = xstrdup(filename);
- if (cmd_flags & FLAG_r) {
+ if (option_mask32 & FLAG_r) {
int *pp = (int *) userdata;
int path_len = *pp + 1;
return TRUE;
}
+
/* This returns a sorted directory listing. */
static char **get_dir(char *path)
{
-
int i;
char **retval;
dl_count = 0;
/* 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,
userdata, 0);
else {
return retval;
}
+
static void diffdir(char *p1, char *p2)
{
-
char **dirlist1, **dirlist2;
char *dp1, *dp2;
int dirlist1_count, dirlist2_count;
dirlist1++;
dirlist2++;
} else if (pos < 0) {
- if (cmd_flags & FLAG_N)
+ if (option_mask32 & FLAG_N)
do_diff(p1, dp1, p2, NULL);
else
print_only(p1, strlen(p1) + 1, dp1);
dirlist1++;
} else {
- if (cmd_flags & FLAG_N)
+ if (option_mask32 & FLAG_N)
do_diff(p1, NULL, p2, dp2);
else
print_only(p2, strlen(p2) + 1, dp2);
#endif
-
int diff_main(int argc, char **argv)
{
int gotstdin = 0;
llist_t *L_arg = NULL;
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);
- if (cmd_flags & FLAG_L) {
+ if (option_mask32 & FLAG_L) {
while (L_arg) {
if (label[0] == NULL)
label[0] = L_arg->data;
}
context = 3; /* This is the default number of lines of context. */
- if (cmd_flags & FLAG_U) {
- context = xatoul_range(U_opt, 1, INT_MAX);
+ if (option_mask32 & FLAG_U) {
+ context = xatou_range(U_opt, 1, INT_MAX);
}
argc -= optind;
argv += optind;
bb_error_msg("missing filename");
bb_show_usage();
}
- if (strcmp(argv[0], "-") == 0) {
+ if (argv[0][0] == '-' && !argv[0][1]) { /* "-" */
fstat(STDIN_FILENO, &stb1);
gotstdin = 1;
} else
xstat(argv[0], &stb1);
- if (strcmp(argv[1], "-") == 0) {
+ if (argv[1][0] == '-' && !argv[1][1]) { /* "-" */
fstat(STDIN_FILENO, &stb2);
gotstdin = 1;
} else
}
print_status(diffreg(argv[0], argv[1], 0), argv[0], argv[1], NULL);
}
- exit(status);
+ return status;
}