/* vi: set sw=4 ts=4: */
/*
 * Mini diff implementation for busybox, adapted from OpenBSD diff.
 *
 * Copyright (C) 2006 by Robert Sullivan <cogito.ergo.cogito@hotmail.com>
 * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
 *
 * Sponsored in part by the Defense Advanced Research Projects
 * Agency (DARPA) and Air Force Research Laboratory, Air Force
 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include "libbb.h"

#define dbg_error_msg(...) ((void)0)
//#define dbg_error_msg(...) bb_error_msg(__VA_ARGS__)

// #define FSIZE_MAX 32768

/* NOINLINEs added to prevent gcc from merging too much into diffreg()
 * (it bites more than it can (efficiently) chew). */

/*
 * Output flags
 */
enum {
	/* Print a header/footer between files */
	/* D_HEADER = 1, - unused */
	/* Treat file as empty (/dev/null) */
	D_EMPTY1 = 2 * ENABLE_FEATURE_DIFF_DIR,
	D_EMPTY2 = 4 * ENABLE_FEATURE_DIFF_DIR,
};

/*
 * Status values for print_status() and diffreg() return values
 * Guide:
 * D_SAME - files are the same
 * D_DIFFER - files differ
 * D_BINARY - binary files differ
 * D_COMMON - subdirectory common to both dirs
 * D_ONLY - file only exists in one dir
 * D_ISDIR1 - path1 a dir, path2 a file
 * D_ISDIR2 - path1 a file, path2 a dir
 * D_ERROR - error occurred
 * D_SKIPPED1 - skipped path1 as it is a special file
 * D_SKIPPED2 - skipped path2 as it is a special file
 */
#define D_SAME          0
#define D_DIFFER        (1 << 0)
#define D_BINARY        (1 << 1)
#define D_COMMON        (1 << 2)
/*#define D_ONLY        (1 << 3) - unused */
#define D_ISDIR1        (1 << 4)
#define D_ISDIR2        (1 << 5)
#define D_ERROR         (1 << 6)
#define D_SKIPPED1      (1 << 7)
#define D_SKIPPED2      (1 << 8)

/* Command line options */
#define FLAG_a  (1 << 0)
#define FLAG_b  (1 << 1)
#define FLAG_d  (1 << 2)
#define FLAG_i  (1 << 3)
#define FLAG_L  (1 << 4)
#define FLAG_N  (1 << 5)
#define FLAG_q  (1 << 6)
#define FLAG_r  (1 << 7)
#define FLAG_s  (1 << 8)
#define FLAG_S  (1 << 9)
#define FLAG_t  (1 << 10)
#define FLAG_T  (1 << 11)
#define FLAG_U  (1 << 12)
#define FLAG_w  (1 << 13)


struct cand {
	int x;
	int y;
	int pred;
};

struct line {
	int serial;
	int value;
};

/*
 * The following struct is used to record change information
 * doing a "context" or "unified" diff.  (see routine "change" to
 * understand the highly mnemonic field names)
 */
struct context_vec {
	int a;          /* start line in old file */
	int b;          /* end line in old file */
	int c;          /* start line in new file */
	int d;          /* end line in new file */
};


#define g_read_buf bb_common_bufsiz1

struct globals {
	bool anychange;
	smallint exit_status;
	int opt_U_context;
	int context_idx;
	IF_FEATURE_DIFF_DIR(int dl_count;)
	IF_FEATURE_DIFF_DIR(char **dl;)
	char *opt_S_start;
	const char *label1;
	const char *label2;
	int *J;                 /* will be overlaid on class */
	int clen;
	int pref, suff;         /* length of prefix and suffix */
	int nlen[2];
	int slen[2];
	int clistlen;           /* the length of clist */
	struct cand *clist;     /* merely a free storage pot for candidates */
	long *ixnew;            /* will be overlaid on nfile[1] */
	long *ixold;            /* will be overlaid on klist */
	struct line *nfile[2];
	struct line *sfile[2];  /* shortened by pruning common prefix/suffix */
	struct context_vec *context_vector;
	char *tempname1, *tempname2;
	struct stat stb1, stb2;
};
#define G (*ptr_to_globals)
#define anychange          (G.anychange         )
#define exit_status        (G.exit_status       )
#define opt_U_context      (G.opt_U_context     )
#define context_idx        (G.context_idx       )
#define dl_count           (G.dl_count          )
#define dl                 (G.dl                )
#define opt_S_start        (G.opt_S_start       )
#define label1             (G.label1            )
#define label2             (G.label2            )
#define J                  (G.J                 )
#define clen               (G.clen              )
#define pref               (G.pref              )
#define suff               (G.suff              )
#define nlen               (G.nlen              )
#define slen               (G.slen              )
#define clistlen           (G.clistlen          )
#define clist              (G.clist             )
#define ixnew              (G.ixnew             )
#define ixold              (G.ixold             )
#define nfile              (G.nfile             )
#define sfile              (G.sfile             )
#define context_vector     (G.context_vector    )
#define stb1               (G.stb1              )
#define stb2               (G.stb2              )
#define tempname1          (G.tempname1         )
#define tempname2          (G.tempname2         )
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
	opt_U_context = 3; \
	context_vector = xrealloc_vector(context_vector, 6, 0); \
} while (0)


#if ENABLE_FEATURE_DIFF_DIR
static void print_only(const char *path, const char *entry)
{
	printf("Only in %s: %s\n", path, entry);
}
#endif


static void print_status(int val, char *_path1, char *_path2)
{
	/*const char *const _entry = entry ? entry : "";*/
	/*char *const _path1 = entry ? concat_path_file(path1, _entry) : path1;*/
	/*char *const _path2 = entry ? concat_path_file(path2, _entry) : path2;*/

	switch (val) {
/*	case D_ONLY:
		print_only(path1, entry);
		break;
*/
	case D_COMMON:
		printf("Common subdirectories: %s and %s\n", _path1, _path2);
		break;
	case D_BINARY:
		printf("Binary files %s and %s differ\n", _path1, _path2);
		break;
	case D_DIFFER:
		if (option_mask32 & FLAG_q)
			printf("Files %s and %s differ\n", _path1, _path2);
		break;
	case D_SAME:
		if (option_mask32 & FLAG_s)
			printf("Files %s and %s are identical\n", _path1, _path2);
		break;
	case D_ISDIR1:
		printf("File %s is a %s while file %s is a %s\n",
			   _path1, "directory", _path2, "regular file");
		break;
	case D_ISDIR2:
		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",
			   _path1);
		break;
	case D_SKIPPED2:
		printf("File %s is not a regular file or directory and was skipped\n",
			   _path2);
		break;
	}
/*
	if (entry) {
		free(_path1);
		free(_path2);
	}
*/
}


/* Read line, return its nonzero hash. Return 0 if EOF.
 *
 * Hash function taken from Robert Sedgewick, Algorithms in C, 3d ed., p 578.
 */
static ALWAYS_INLINE int fiddle_sum(int sum, int t)
{
	return sum * 127 + t;
}
static int readhash(FILE *fp)
{
	int i, t;
	int sum;

	sum = 1;
	i = 0;
	if (!(option_mask32 & (FLAG_b | FLAG_w))) {
		while ((t = getc(fp)) != '\n') {
			if (t == EOF) {
				if (i == 0)
					return 0;
				break;
			}
			sum = fiddle_sum(sum, t);
			i = 1;
		}
	} else {
		int space = 0;

		while (1) {
			t = getc(fp);
			switch (t) {
			case '\t':
			case '\r':
			case '\v':
			case '\f':
			case ' ':
				space = 1;
				continue;
			default:
				if (space && !(option_mask32 & FLAG_w)) {
					i = 1;
					space = 0;
				}
				sum = fiddle_sum(sum, t);
				i = 1;
				continue;
			case EOF:
				if (i == 0)
					return 0;
				/* FALLTHROUGH */
			case '\n':
				break;
			}
			break;
		}
	}
	/*
	 * There is a remote possibility that we end up with a zero sum.
	 * Zero is used as an EOF marker, so return 1 instead.
	 */
	return (sum == 0 ? 1 : sum);
}


/* Our diff implementation is using seek.
 * When we meet non-seekable file, we must make a temp copy.
 */
static char *make_temp(FILE *f, struct stat *sb)
{
	char *name;
	int fd;

	if (S_ISREG(sb->st_mode) || S_ISBLK(sb->st_mode))
		return NULL;
	name = xstrdup("/tmp/difXXXXXX");
	fd = mkstemp(name);
	if (fd < 0)
		bb_perror_msg_and_die("mkstemp");
	if (bb_copyfd_eof(fileno(f), fd) < 0) {
 clean_up:
		unlink(name);
		xfunc_die(); /* error message is printed by bb_copyfd_eof */
	}
	fstat(fd, sb);
	close(fd);
	if (freopen(name, "r+", f) == NULL) {
		bb_perror_msg("freopen");
		goto clean_up;
	}
	return name;
}


/*
 * Check to see if the given files differ.
 * Returns 0 if they are the same, 1 if different, and -1 on error.
 */
static NOINLINE int files_differ(FILE *f1, FILE *f2)
{
	size_t i, j;

	/* Prevent making copies for "/dev/null" (too common) */
	/* Deal with input from pipes etc */
	tempname1 = make_temp(f1, &stb1);
	tempname2 = make_temp(f2, &stb2);
	if (stb1.st_size != stb2.st_size) {
		return 1;
	}
	while (1) {
		i = fread(g_read_buf,                    1, COMMON_BUFSIZE/2, f1);
		j = fread(g_read_buf + COMMON_BUFSIZE/2, 1, COMMON_BUFSIZE/2, f2);
		if (i != j)
			return 1;
		if (i == 0)
			return (ferror(f1) || ferror(f2)) ? -1 : 0;
		if (memcmp(g_read_buf,
		           g_read_buf + COMMON_BUFSIZE/2, i) != 0)
			return 1;
	}
}


static void prepare(int i, FILE *fp /*, off_t filesize*/)
{
	struct line *p;
	int h;
	size_t j, sz;

	rewind(fp);

	/*sz = (filesize <= FSIZE_MAX ? filesize : FSIZE_MAX) / 25;*/
	/*if (sz < 100)*/
	sz = 100;

	p = xmalloc((sz + 3) * sizeof(p[0]));
	j = 0;
	while ((h = readhash(fp)) != 0) { /* while not EOF */
		if (j == sz) {
			sz = sz * 3 / 2;
			p = xrealloc(p, (sz + 3) * sizeof(p[0]));
		}
		p[++j].value = h;
	}
	nlen[i] = j;
	nfile[i] = p;
}


static void prune(void)
{
	int i, j;

	for (pref = 0; pref < nlen[0] && pref < nlen[1] &&
		nfile[0][pref + 1].value == nfile[1][pref + 1].value; pref++)
		continue;
	for (suff = 0; suff < nlen[0] - pref && suff < nlen[1] - pref &&
		nfile[0][nlen[0] - suff].value == nfile[1][nlen[1] - suff].value;
		suff++)
		continue;
	for (j = 0; j < 2; j++) {
		sfile[j] = nfile[j] + pref;
		slen[j] = nlen[j] - pref - suff;
		for (i = 0; i <= slen[j]; i++)
			sfile[j][i].serial = i;
	}
}


static void equiv(struct line *a, int n, struct line *b, int m, int *c)
{
	int i, j;

	i = j = 1;
	while (i <= n && j <= m) {
		if (a[i].value < b[j].value)
			a[i++].value = 0;
		else if (a[i].value == b[j].value)
			a[i++].value = j;
		else
			j++;
	}
	while (i <= n)
		a[i++].value = 0;
	b[m + 1].value = 0;
	j = 0;
	while (++j <= m) {
		c[j] = -b[j].serial;
		while (b[j + 1].value == b[j].value) {
			j++;
			c[j] = b[j].serial;
		}
	}
	c[j] = -1;
}


static int isqrt(int n)
{
	int y, x;

	if (n == 0)
		return 0;
	x = 1;
	do {
		y = x;
		x = n / x;
		x += y;
		x /= 2;
	} while ((x - y) > 1 || (x - y) < -1);

	return x;
}


static int newcand(int x, int y, int pred)
{
	struct cand *q;

	if (clen == clistlen) {
		clistlen = clistlen * 11 / 10;
		clist = xrealloc(clist, clistlen * sizeof(struct cand));
	}
	q = clist + clen;
	q->x = x;
	q->y = y;
	q->pred = pred;
	return clen++;
}


static int search(int *c, int k, int y)
{
	int i, j, l, t;

	if (clist[c[k]].y < y)	/* quick look for typical case */
		return k + 1;
	i = 0;
	j = k + 1;
	while (1) {
		l = i + j;
		if ((l >>= 1) <= i)
			break;
		t = clist[c[l]].y;
		if (t > y)
			j = l;
		else if (t < y)
			i = l;
		else
			return l;
	}
	return l + 1;
}


static int stone(int *a, int n, int *b, int *c)
{
	int i, k, y, j, l;
	int oldc, tc, oldl;
	unsigned numtries;
	int isq = isqrt(n);
#if ENABLE_FEATURE_DIFF_MINIMAL
	const unsigned bound =
		(option_mask32 & FLAG_d) ? UINT_MAX : MAX(256, isq);
#else
	const unsigned bound = MAX(256, isq);
#endif

	k = 0;
	c[0] = newcand(0, 0, 0);
	for (i = 1; i <= n; i++) {
		j = a[i];
		if (j == 0)
			continue;
		y = -b[j];
		oldl = 0;
		oldc = c[0];
		numtries = 0;
		do {
			if (y <= clist[oldc].y)
				continue;
			l = search(c, k, y);
			if (l != oldl + 1)
				oldc = c[l - 1];
			if (l <= k) {
				if (clist[c[l]].y <= y)
					continue;
				tc = c[l];
				c[l] = newcand(i, y, oldc);
				oldc = tc;
				oldl = l;
				numtries++;
			} else {
				c[l] = newcand(i, y, oldc);
				k++;
				break;
			}
		} while ((y = b[++j]) > 0 && numtries < bound);
	}
	return k;
}


static void unravel(int p)
{
	struct cand *q;
	int i;

	for (i = 0; i <= nlen[0]; i++)
		J[i] = i <= pref ? i : i > nlen[0] - suff ? i + nlen[1] - nlen[0] : 0;
	for (q = clist + p; q->y != 0; q = clist + q->pred)
		J[q->x + pref] = q->y + pref;
}


static void unsort(struct line *f, int l, int *b)
{
	int *a, i;

	a = xmalloc((l + 1) * sizeof(int));
	for (i = 1; i <= l; i++)
		a[f[i].serial] = f[i].value;
	for (i = 1; i <= l; i++)
		b[i] = a[i];
	free(a);
}


static int skipline(FILE *f)
{
	int i, c;

	for (i = 1; (c = getc(f)) != '\n' && c != EOF; i++)
		continue;
	return i;
}


/*
 * Check does double duty:
 *  1.  ferret out any fortuitous correspondences due
 *      to confounding by hashing (which result in "jackpot")
 *  2.  collect random access indexes to the two files
 */
static NOINLINE void check(FILE *f1, FILE *f2)
{
	int i, j, jackpot, c, d;
	long ctold, ctnew;

	rewind(f1);
	rewind(f2);
	j = 1;
	ixold[0] = ixnew[0] = 0;
	jackpot = 0;
	ctold = ctnew = 0;
	for (i = 1; i <= nlen[0]; i++) {
		if (J[i] == 0) {
			ixold[i] = ctold += skipline(f1);
			continue;
		}
		while (j < J[i]) {
			ixnew[j] = ctnew += skipline(f2);
			j++;
		}
		if (option_mask32 & (FLAG_b | FLAG_w | FLAG_i)) {
			while (1) {
				c = getc(f1);
				d = getc(f2);
				/*
				 * GNU diff ignores a missing newline
				 * in one file if bflag || wflag.
				 */
				if ((option_mask32 & (FLAG_b | FLAG_w))
				 && ((c == EOF && d == '\n') || (c == '\n' && d == EOF))
				) {
					break;
				}
				ctold++;
				ctnew++;
				if ((option_mask32 & FLAG_b) && isspace(c) && isspace(d)) {
					do {
						if (c == '\n')
							break;
						ctold++;
						c = getc(f1);
					} while (isspace(c));
					do {
						if (d == '\n')
							break;
						ctnew++;
						d = getc(f2);
					} while (isspace(d));
				} else if (option_mask32 & FLAG_w) {
					while (isspace(c) && c != '\n') {
						c = getc(f1);
						ctold++;
					}
					while (isspace(d) && d != '\n') {
						d = getc(f2);
						ctnew++;
					}
				}
				if (c != d) {
					jackpot++;
					J[i] = 0;
					if (c != '\n' && c != EOF)
						ctold += skipline(f1);
					if (d != '\n' && c != EOF)
						ctnew += skipline(f2);
					break;
				}
				if (c == '\n' || c == EOF)
					break;
			}
		} else {
			while (1) {
				ctold++;
				ctnew++;
				c = getc(f1);
				d = getc(f2);
				if (c != d) {
					J[i] = 0;
					if (c != '\n' && c != EOF)
						ctold += skipline(f1);
/* was buggy? "if (d != '\n' && c != EOF)" */
					if (d != '\n' && d != EOF)
						ctnew += skipline(f2);
					break;
				}
				if (c == '\n' || c == EOF)
					break;
			}
		}
		ixold[i] = ctold;
		ixnew[j] = ctnew;
		j++;
	}
	for (; j <= nlen[1]; j++)
		ixnew[j] = ctnew += skipline(f2);
}


/* shellsort CACM #201 */
static void sort(struct line *a, int n)
{
	struct line *ai, *aim, w;
	int j, m = 0, k;

	if (n == 0)
		return;
	for (j = 1; j <= n; j *= 2)
		m = 2 * j - 1;
	for (m /= 2; m != 0; m /= 2) {
		k = n - m;
		for (j = 1; j <= k; j++) {
			for (ai = &a[j]; ai > a; ai -= m) {
				aim = &ai[m];
				if (aim < ai)
					break;	/* wraparound */
				if (aim->value > ai[0].value
				 || (aim->value == ai[0].value && aim->serial > ai[0].serial)
				) {
					break;
				}
				w.value = ai[0].value;
				ai[0].value = aim->value;
				aim->value = w.value;
				w.serial = ai[0].serial;
				ai[0].serial = aim->serial;
				aim->serial = w.serial;
			}
		}
	}
}


static void uni_range(int a, int b)
{
	if (a < b)
		printf("%d,%d", a, b - a + 1);
	else if (a == b)
		printf("%d", b);
	else
		printf("%d,0", b);
}


static void fetch(long *f, int a, int b, FILE *lb, int ch)
{
	int i, j, c, lastc, col, nc;

	if (a > b)
		return;
	for (i = a; i <= b; i++) {
		fseek(lb, f[i - 1], SEEK_SET);
		nc = f[i] - f[i - 1];
		if (ch != '\0') {
			putchar(ch);
			if (option_mask32 & FLAG_T)
				putchar('\t');
		}
		col = 0;
		for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) {
			c = getc(lb);
			if (c == EOF) {
				printf("\n\\ No newline at end of file\n");
				return;
			}
			if (c == '\t' && (option_mask32 & FLAG_t)) {
				do {
					putchar(' ');
				} while (++col & 7);
			} else {
				putchar(c);
				col++;
			}
		}
	}
}


#if ENABLE_FEATURE_DIFF_BINARY
static int asciifile(FILE *f)
{
	int i, cnt;

	if (option_mask32 & FLAG_a)
		return 1;
	rewind(f);
	cnt = fread(g_read_buf, 1, COMMON_BUFSIZE, f);
	for (i = 0; i < cnt; i++) {
		if (!isprint_asciionly(g_read_buf[i])
		 && !isspace(g_read_buf[i])
		) {
			return 0;
		}
	}
	return 1;
}
#else
#define asciifile(f) 1
#endif


/* dump accumulated "unified" diff changes */
static void dump_unified_vec(FILE *f1, FILE *f2)
{
	struct context_vec *cvp = context_vector;
	int lowa, upb, lowc, upd;
	int a, b, c, d;
	char ch;

	if (context_idx < 0)
		return;

	dbg_error_msg("dumping %d context_vecs", context_idx+1);

	b = d = 0;			/* gcc */
	lowa = MAX(1, cvp->a - opt_U_context);
	upb = MIN(nlen[0], context_vector[context_idx].b + opt_U_context);
	lowc = MAX(1, cvp->c - opt_U_context);
	upd = MIN(nlen[1], context_vector[context_idx].d + opt_U_context);

	printf("@@ -");
	uni_range(lowa, upb);
	printf(" +");
	uni_range(lowc, upd);
	printf(" @@\n");

	/*
	 * Output changes in "unified" diff format--the old and new lines
	 * are printed together.
	 */
	for (; cvp <= &context_vector[context_idx]; cvp++) {
		a = cvp->a;
		b = cvp->b;
		c = cvp->c;
		d = cvp->d;

		/*
		 * c: both new and old changes
		 * d: only changes in the old file
		 * a: only changes in the new file
		 */
		if (a <= b && c <= d)
			ch = 'c';
		else
			ch = (a <= b) ? 'd' : 'a';
#if 0
		switch (ch) {
		case 'c':
// fetch() seeks!
			fetch(ixold, lowa, a - 1, f1, ' ');
			fetch(ixold, a, b, f1, '-');
			fetch(ixnew, c, d, f2, '+');
			break;
		case 'd':
			fetch(ixold, lowa, a - 1, f1, ' ');
			fetch(ixold, a, b, f1, '-');
			break;
		case 'a':
			fetch(ixnew, lowc, c - 1, f2, ' ');
			fetch(ixnew, c, d, f2, '+');
			break;
		}
#else
		if (ch == 'c' || ch == 'd') {
			fetch(ixold, lowa, a - 1, f1, ' ');
			fetch(ixold, a, b, f1, '-');
		}
		if (ch == 'a')
			fetch(ixnew, lowc, c - 1, f2, ' ');
		if (ch == 'c' || ch == 'a')
			fetch(ixnew, c, d, f2, '+');
#endif
		lowa = b + 1;
		lowc = d + 1;
	}
	fetch(ixnew, d + 1, upd, f2, ' ');

	context_idx = -1;
}


static void print_header(const char *file1, const char *file2)
{
	if (label1)
		printf("--- %s\n", label1);
	else
		printf("--- %s\t%s", file1, ctime(&stb1.st_mtime));
	if (label2)
		printf("+++ %s\n", label2);
	else
		printf("+++ %s\t%s", file2, ctime(&stb2.st_mtime));
}


/*
 * 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 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 void change(const char *file1, FILE *f1, const char *file2, FILE *f2,
			int a, int b, int c, int d)
{
	if ((a > b && c > d) || (option_mask32 & FLAG_q)) {
//compat BUG: "diff -ub F1 F2" will output nothing, but will exit 1
//if F1 and F2 differ only in whitespace. "standard" diff exits 0.
//This is the place where this erroneous exitcode is set:
		dbg_error_msg("%d: abcd:%d,%d,%d,%d, anychange=1", __LINE__, a,b,c,d);
		anychange = 1;
		return;
	}

	if (anychange == 0) {
		/*
		 * Print the context/unidiff header first time through.
		 */
		print_header(file1, file2);
	} else if (a > context_vector[context_idx].b + (2 * opt_U_context) + 1
	        && c > context_vector[context_idx].d + (2 * opt_U_context) + 1
	) {
		/*
		 * If this change is more than 'context' lines from the
		 * previous change, dump the record and reset it.
		 */
// dump_unified_vec() seeks!
		dump_unified_vec(f1, f2);
	}
	context_idx++;
	context_vector = xrealloc_vector(context_vector, 6, context_idx);
	context_vector[context_idx].a = a;
	context_vector[context_idx].b = b;
	context_vector[context_idx].c = c;
	context_vector[context_idx].d = d;
	dbg_error_msg("new context_vec[%d]:%d,%d,%d,%d", context_idx, a,b,c,d);
	anychange = 1;
}


static void output(const char *file1, FILE *f1, const 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;

	rewind(f1);
	rewind(f2);
	m = nlen[0];
	J[0] = 0;
	J[m + 1] = nlen[1] + 1;
	for (i0 = 1; i0 <= m; i0 = i1 + 1) {
		while (i0 <= m && J[i0] == J[i0 - 1] + 1)
			i0++;
		j00 = J[i0 - 1] + 1;
		i1 = i0 - 1;
		while (i1 < m && J[i1 + 1] == 0)
			i1++;
		j01 = J[i1 + 1] - 1;
		J[i1] = j01;
// change() seeks!
		change(file1, f1, file2, f2, i0, i1, j00, j01);
	}
	if (m == 0) {
// change() seeks!
		change(file1, f1, file2, f2, 1, 0, 1, nlen[1]);
	}
	if (anychange != 0 && !(option_mask32 & FLAG_q)) {
// dump_unified_vec() seeks!
		dump_unified_vec(f1, f2);
	}
}

/*
 * The following code uses an algorithm due to Harold Stone,
 * which finds a pair of longest identical subsequences in
 * the two files.
 *
 * The major goal is to generate the match vector J.
 * J[i] is the index of the line in file1 corresponding
 * to line i in file0. J[i] = 0 if there is no
 * such line in file1.
 *
 * Lines are hashed so as to work in core. All potential
 * matches are located by sorting the lines of each file
 * on the hash (called "value"). In particular, this
 * collects the equivalence classes in file1 together.
 * Subroutine equiv replaces the value of each line in
 * file0 by the index of the first element of its
 * matching equivalence in (the reordered) file1.
 * To save space equiv squeezes file1 into a single
 * array member in which the equivalence classes
 * are simply concatenated, except that their first
 * members are flagged by changing sign.
 *
 * Next the indices that point into member are unsorted into
 * array class according to the original order of file0.
 *
 * The cleverness lies in routine stone. This marches
 * through the lines of file0, developing a vector klist
 * of "k-candidates". At step i a k-candidate is a matched
 * pair of lines x,y (x in file0, y in file1) such that
 * there is a common subsequence of length k
 * between the first i lines of file0 and the first y
 * lines of file1, but there is no such subsequence for
 * any smaller y. x is the earliest possible mate to y
 * that occurs in such a subsequence.
 *
 * Whenever any of the members of the equivalence class of
 * lines in file1 matable to a line in file0 has serial number
 * less than the y of some k-candidate, that k-candidate
 * with the smallest such y is replaced. The new
 * k-candidate is chained (via pred) to the current
 * k-1 candidate so that the actual subsequence can
 * be recovered. When a member has serial number greater
 * that the y of all k-candidates, the klist is extended.
 * At the end, the longest subsequence is pulled out
 * and placed in the array J by unravel
 *
 * With J in hand, the matches there recorded are
 * checked against reality to assure that no spurious
 * matches have crept in due to hashing. If they have,
 * they are broken, and "jackpot" is recorded--a harmless
 * matter except that a true match for a spuriously
 * mated line may now be unnecessarily reported as a change.
 *
 * Much of the complexity of the program comes simply
 * from trying to minimize core utilization and
 * maximize the range of doable problems by dynamically
 * allocating what is needed and reusing what is not.
 * The core requirements for problems larger than somewhat
 * are (in words) 2*length(file0) + length(file1) +
 * 3*(number of k-candidates installed), typically about
 * 6n words for files of length n.
 */
/* NB: files can be not REGular. The only sure thing that they
 * are not both DIRectories. */
static unsigned diffreg(const char *file1, const char *file2, int flags)
{
	int *member;     /* will be overlaid on nfile[1] */
	int *class;      /* will be overlaid on nfile[0] */
	int *klist;      /* will be overlaid on nfile[0] after class */
	FILE *f1;
	FILE *f2;
	unsigned rval;
	int i;

	anychange = 0;
	context_idx = -1;
	tempname1 = tempname2 = NULL;

	/* Is any of them a directory? Then it's simple */
	if (S_ISDIR(stb1.st_mode) != S_ISDIR(stb2.st_mode))
		return (S_ISDIR(stb1.st_mode) ? D_ISDIR1 : D_ISDIR2);

	/* None of them are directories */
	rval = D_SAME;

	if (flags & D_EMPTY1)
		/* can't be stdin, but xfopen_stdin() is smaller code */
		file1 = bb_dev_null;
	f1 = xfopen_stdin(file1);
	if (flags & D_EMPTY2)
		file2 = bb_dev_null;
	f2 = xfopen_stdin(file2);

	/* NB: if D_EMPTY1/2 is set, other file is always a regular file,
	 * not pipe/fifo/chardev/etc - D_EMPTY is used by "diff -r" only,
	 * and it never diffs non-ordinary files in subdirs. */
	if (!(flags & (D_EMPTY1 | D_EMPTY2))) {
		/* Quick check whether they are different */
		/* NB: copies non-REG files to tempfiles and fills tempname1/2 */
		i = files_differ(f1, f2);
		if (i != 1) { /* not different? */
			if (i != 0) /* error? */
				exit_status |= 2;
			goto closem;
		}
	}

	if (!asciifile(f1) || !asciifile(f2)) {
		rval = D_BINARY;
		exit_status |= 1;
		goto closem;
	}

// Rewind inside!
	prepare(0, f1 /*, stb1.st_size*/);
	prepare(1, f2 /*, stb2.st_size*/);
	prune();
	sort(sfile[0], slen[0]);
	sort(sfile[1], slen[1]);

	member = (int *) nfile[1];
	equiv(sfile[0], slen[0], sfile[1], slen[1], member);
//TODO: xrealloc_vector?
	member = xrealloc(member, (slen[1] + 2) * sizeof(int));

	class = (int *) nfile[0];
	unsort(sfile[0], slen[0], class);
	class = xrealloc(class, (slen[0] + 2) * sizeof(int));

	klist = xmalloc((slen[0] + 2) * sizeof(int));
	clen = 0;
	clistlen = 100;
	clist = xmalloc(clistlen * sizeof(struct cand));
	i = stone(class, slen[0], member, klist);
	free(member);
	free(class);

	J = xrealloc(J, (nlen[0] + 2) * sizeof(int));
	unravel(klist[i]);
	free(clist);
	free(klist);

	ixold = xrealloc(ixold, (nlen[0] + 2) * sizeof(long));
	ixnew = xrealloc(ixnew, (nlen[1] + 2) * sizeof(long));
// Rewind inside!
	check(f1, f2);
// Rewind inside!
	output(file1, f1, file2, f2);

 closem:
	if (anychange) {
		exit_status |= 1;
		dbg_error_msg("exit_status|=1 = %d", exit_status);
		if (rval == D_SAME)
			rval = D_DIFFER;
	}
	fclose_if_not_stdin(f1);
	fclose_if_not_stdin(f2);
	if (tempname1) {
		unlink(tempname1);
		free(tempname1);
	}
	if (tempname2) {
		unlink(tempname2);
		free(tempname2);
	}
	return rval;
}


#if ENABLE_FEATURE_DIFF_DIR
static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
{
	int flags = 0; /*D_HEADER;*/
	int val;
	char *fullpath1 = NULL; /* if -N */
	char *fullpath2 = NULL;

	if (path1)
		fullpath1 = concat_path_file(dir1, path1);
	if (path2)
		fullpath2 = concat_path_file(dir2, path2);

	if (!fullpath1 || stat(fullpath1, &stb1) != 0) {
		flags |= D_EMPTY1;
		memset(&stb1, 0, sizeof(stb1));
		if (path2) {
			free(fullpath1);
			fullpath1 = concat_path_file(dir1, path2);
		}
	}
	if (!fullpath2 || stat(fullpath2, &stb2) != 0) {
		flags |= D_EMPTY2;
		memset(&stb2, 0, sizeof(stb2));
		stb2.st_mode = stb1.st_mode;
		if (path1) {
			free(fullpath2);
			fullpath2 = concat_path_file(dir2, path1);
		}
	}

	if (stb1.st_mode == 0)
		stb1.st_mode = stb2.st_mode;

	if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
		printf("Common subdirectories: %s and %s\n", fullpath1, fullpath2);
		goto ret;
	}

	if (!S_ISREG(stb1.st_mode) && !S_ISDIR(stb1.st_mode))
		val = D_SKIPPED1;
	else if (!S_ISREG(stb2.st_mode) && !S_ISDIR(stb2.st_mode))
		val = D_SKIPPED2;
	else {
		/* Both files are either REGular or DIRectories */
		val = diffreg(fullpath1, fullpath2, flags);
	}

	print_status(val, fullpath1, fullpath2 /*, NULL*/);
 ret:
	free(fullpath1);
	free(fullpath2);
}
#endif


#if ENABLE_FEATURE_DIFF_DIR
/* This function adds a filename to dl, the directory listing. */
static int FAST_FUNC add_to_dirlist(const char *filename,
		struct stat *sb UNUSED_PARAM,
		void *userdata,
		int depth UNUSED_PARAM)
{
	dl = xrealloc_vector(dl, 5, dl_count);
	dl[dl_count] = xstrdup(filename + (int)(ptrdiff_t)userdata);
	dl_count++;
	return TRUE;
}


/* This returns a sorted directory listing. */
static char **get_recursive_dirlist(char *path)
{
	dl_count = 0;
	dl = xzalloc(sizeof(dl[0]));

	/* We need to trim root directory prefix.
	 * Using void *userdata to specify its length,
	 * add_to_dirlist will remove it. */
	if (option_mask32 & FLAG_r) {
		recursive_action(path, ACTION_RECURSE|ACTION_FOLLOWLINKS,
					add_to_dirlist, /* file_action */
					NULL, /* dir_action */
					(void*)(ptrdiff_t)(strlen(path) + 1),
					0);
	} else {
		DIR *dp;
		struct dirent *ep;

		dp = warn_opendir(path);
		while ((ep = readdir(dp))) {
			if (!strcmp(ep->d_name, "..") || LONE_CHAR(ep->d_name, '.'))
				continue;
			add_to_dirlist(ep->d_name, NULL, (void*)(int)0, 0);
		}
		closedir(dp);
	}

	/* Sort dl alphabetically. */
	qsort_string_vector(dl, dl_count);

	dl[dl_count] = NULL;
	return dl;
}


static void diffdir(char *p1, char *p2)
{
	char **dirlist1, **dirlist2;
	char *dp1, *dp2;
	int pos;

	/* Check for trailing slashes. */
	dp1 = last_char_is(p1, '/');
	if (dp1 != NULL)
		*dp1 = '\0';
	dp2 = last_char_is(p2, '/');
	if (dp2 != NULL)
		*dp2 = '\0';

	/* Get directory listings for p1 and p2. */
	dirlist1 = get_recursive_dirlist(p1);
	dirlist2 = get_recursive_dirlist(p2);

	/* If -S was set, find the starting point. */
	if (opt_S_start) {
		while (*dirlist1 != NULL && strcmp(*dirlist1, opt_S_start) < 0)
			dirlist1++;
		while (*dirlist2 != NULL && strcmp(*dirlist2, opt_S_start) < 0)
			dirlist2++;
		if ((*dirlist1 == NULL) || (*dirlist2 == NULL))
			bb_error_msg(bb_msg_invalid_arg, "NULL", "-S");
	}

	/* Now that both dirlist1 and dirlist2 contain sorted directory
	 * listings, we can start to go through dirlist1. If both listings
	 * contain the same file, then do a normal diff. Otherwise, behaviour
	 * is determined by whether the -N flag is set. */
	while (*dirlist1 != NULL || *dirlist2 != NULL) {
		dp1 = *dirlist1;
		dp2 = *dirlist2;
		pos = dp1 == NULL ? 1 : (dp2 == NULL ? -1 : strcmp(dp1, dp2));
		if (pos == 0) {
			do_diff(p1, dp1, p2, dp2);
			dirlist1++;
			dirlist2++;
		} else if (pos < 0) {
			if (option_mask32 & FLAG_N)
				do_diff(p1, dp1, p2, NULL);
			else
				print_only(p1, dp1);
			dirlist1++;
		} else {
			if (option_mask32 & FLAG_N)
				do_diff(p1, NULL, p2, dp2);
			else
				print_only(p2, dp2);
			dirlist2++;
		}
	}
}
#endif


int diff_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int diff_main(int argc UNUSED_PARAM, char **argv)
{
	int gotstdin = 0;
	char *f1, *f2;
	llist_t *L_arg = NULL;

	INIT_G();

	/* exactly 2 params; collect multiple -L <label>; -U N */
	opt_complementary = "=2:L::U+";
	getopt32(argv, "abdiL:NqrsS:tTU:wu"
			"p" /* ignored (for compatibility) */,
			&L_arg, &opt_S_start, &opt_U_context);
	/*argc -= optind;*/
	argv += optind;
	while (L_arg) {
		if (label1 && label2)
			bb_show_usage();
		if (label1) /* then label2 is NULL */
			label2 = label1;
		label1 = llist_pop(&L_arg);
	}

	/*
	 * Do sanity checks, fill in stb1 and stb2 and call the appropriate
	 * driver routine.  Both drivers use the contents of stb1 and stb2.
	 */
	f1 = argv[0];
	f2 = argv[1];
	/* Compat: "diff file name_which_doesnt_exist" exits with 2 */
	xfunc_error_retval = 2;
	if (LONE_DASH(f1)) {
		fstat(STDIN_FILENO, &stb1);
		gotstdin++;
	} else
		xstat(f1, &stb1);
	if (LONE_DASH(f2)) {
		fstat(STDIN_FILENO, &stb2);
		gotstdin++;
	} else
		xstat(f2, &stb2);
	xfunc_error_retval = 1;

	if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
		bb_error_msg_and_die("can't compare stdin to a directory");

	if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
#if ENABLE_FEATURE_DIFF_DIR
		diffdir(f1, f2);
		return exit_status;
#else
		bb_error_msg_and_die("no support for directory comparison");
#endif
	}

	if (S_ISDIR(stb1.st_mode)) { /* "diff dir file" */
		/* NB: "diff dir      dir2/dir3/file" must become
		 *     "diff dir/file dir2/dir3/file" */
		char *slash = strrchr(f2, '/');
		f1 = concat_path_file(f1, slash ? slash + 1 : f2);
		xstat(f1, &stb1);
	}
	if (S_ISDIR(stb2.st_mode)) {
		char *slash = strrchr(f1, '/');
		f2 = concat_path_file(f2, slash ? slash + 1 : f1);
		xstat(f2, &stb2);
	}

	/* diffreg can get non-regular files here,
	 * they are not both DIRestories */
	print_status((gotstdin > 1 ? D_SAME : diffreg(f1, f2, 0)),
			f1, f2 /*, NULL*/);
	return exit_status;
}
