int
diff_2_files (struct comparison *cmp)
{
- lin diags;
int f;
struct change *e, *p;
struct change *script;
}
else
{
+ struct context ctxt;
+ lin diags;
+ OFFSET too_expensive;
+
/* Allocate vectors for the results of comparison:
a flag for each line of each file, saying whether that line
is an insertion or deletion.
/* Now do the main comparison algorithm, considering just the
undiscarded lines. */
- xvec = cmp->file[0].undiscarded;
- yvec = cmp->file[1].undiscarded;
+ ctxt.xvec = cmp->file[0].undiscarded;
+ ctxt.yvec = cmp->file[1].undiscarded;
diags = (cmp->file[0].nondiscarded_lines
+ cmp->file[1].nondiscarded_lines + 3);
- fdiag = xmalloc (diags * (2 * sizeof *fdiag));
- bdiag = fdiag + diags;
- fdiag += cmp->file[1].nondiscarded_lines + 1;
- bdiag += cmp->file[1].nondiscarded_lines + 1;
+ ctxt.fdiag = xmalloc (diags * (2 * sizeof *fdiag));
+ ctxt.bdiag = fdiag + diags;
+ ctxt.fdiag += cmp->file[1].nondiscarded_lines + 1;
+ ctxt.bdiag += cmp->file[1].nondiscarded_lines + 1;
- heuristic = speed_large_files;
+ ctxt.heuristic = speed_large_files;
/* Set TOO_EXPENSIVE to be approximate square root of input size,
bounded below by 256. */
too_expensive = 1;
for (; diags != 0; diags >>= 2)
too_expensive <<= 1;
- too_expensive = MAX (256, too_expensive);
+ ctxt.too_expensive = MAX (256, too_expensive);
files[0] = cmp->file[0];
files[1] = cmp->file[1];
compareseq (0, cmp->file[0].nondiscarded_lines,
- 0, cmp->file[1].nondiscarded_lines, minimal);
+ 0, cmp->file[1].nondiscarded_lines, minimal, &ctxt);
- free (fdiag - (cmp->file[1].nondiscarded_lines + 1));
+ free (ctxt.fdiag - (cmp->file[1].nondiscarded_lines + 1));
/* Modify the results slightly to make them prettier
in cases where that can validly be done. */
#define OFFSET_MAX \
((((OFFSET)1 << (sizeof (OFFSET_MAX) * CHAR_BIT - 2)) - 1) * 2 + 1)
-/* Vectors being compared. */
-static const ELEMENT *xvec, *yvec;
-
-/* Vector, indexed by diagonal, containing 1 + the X coordinate of the point
- furthest along the given diagonal in the forward search of the edit
- matrix. */
-static OFFSET *fdiag;
-
-/* Vector, indexed by diagonal, containing the X coordinate of the point
- furthest along the given diagonal in the backward search of the edit
- matrix. */
-static OFFSET *bdiag;
-
-#ifdef USE_HEURISTIC
-/* This corresponds to the diff -H flag. With this heuristic, for
- vectors with a constant small density of changes, the algorithm is
- linear in the vectors size. This is unlikely in typical uses of
- fstrcmp, and so is usually compiled out. Besides, there is no
- interface to set it true. */
-int heuristic;
-#endif
-
-/* Edit scripts longer than this are too expensive to compute. */
-static OFFSET too_expensive;
-
-/* Snakes bigger than this are considered `big'. */
-#define SNAKE_LIMIT 20
+/*
+ * Context of comparison operation.
+ */
+struct context
+{
+ /* Vectors being compared. */
+ const ELEMENT *xvec;
+ const ELEMENT *yvec;
+
+ /* Vector, indexed by diagonal, containing 1 + the X coordinate of the point
+ furthest along the given diagonal in the forward search of the edit
+ matrix. */
+ OFFSET *fdiag;
+
+ /* Vector, indexed by diagonal, containing the X coordinate of the point
+ furthest along the given diagonal in the backward search of the edit
+ matrix. */
+ OFFSET *bdiag;
+
+ #ifdef USE_HEURISTIC
+ /* This corresponds to the diff -H flag. With this heuristic, for
+ vectors with a constant small density of changes, the algorithm is
+ linear in the vectors size. */
+ int heuristic;
+ #endif
+
+ /* Edit scripts longer than this are too expensive to compute. */
+ OFFSET too_expensive;
+
+ /* Snakes bigger than this are considered `big'. */
+ #define SNAKE_LIMIT 20
+};
struct partition
{
static void
diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
- struct partition *part)
+ struct partition *part, struct context *ctxt)
{
- OFFSET *const fd = fdiag; /* Give the compiler a chance. */
- OFFSET *const bd = bdiag; /* Additional help for the compiler. */
- const ELEMENT *const xv = xvec; /* Still more help for the compiler. */
- const ELEMENT *const yv = yvec; /* And more and more . . . */
+ OFFSET *const fd = ctxt->fdiag; /* Give the compiler a chance. */
+ OFFSET *const bd = ctxt->bdiag; /* Additional help for the compiler. */
+ const ELEMENT *const xv = ctxt->xvec; /* Still more help for the compiler. */
+ const ELEMENT *const yv = ctxt->yvec; /* And more and more . . . */
const OFFSET dmin = xoff - ylim; /* Minimum valid diagonal. */
const OFFSET dmax = xlim - yoff; /* Maximum valid diagonal. */
const OFFSET fmid = xoff - yoff; /* Center diagonal of top-down search. */
With this heuristic, for vectors with a constant small density
of changes, the algorithm is linear in the vector size. */
- if (c > 200 && big_snake && heuristic)
+ if (c > 200 && big_snake && ctxt->heuristic)
{
OFFSET best = 0;
/* Heuristic: if we've gone well beyond the call of duty,
give up and report halfway between our best results so far. */
- if (c >= too_expensive)
+ if (c >= ctxt->too_expensive)
{
OFFSET fxybest;
OFFSET bxybest;
expensive it is. */
static void
-compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal)
+compareseq (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
+ bool find_minimal, struct context *ctxt)
{
- const ELEMENT *xv = xvec; /* Help the compiler. */
- const ELEMENT *yv = yvec;
+ const ELEMENT *xv = ctxt->xvec; /* Help the compiler. */
+ const ELEMENT *yv = ctxt->yvec;
/* Slide down the bottom initial diagonal. */
while (xoff < xlim && yoff < ylim && xv[xoff] == yv[yoff])
struct partition part IF_LINT (= {0});
/* Find a point of correspondence in the middle of the vectors. */
- diag (xoff, xlim, yoff, ylim, find_minimal, &part);
+ diag (xoff, xlim, yoff, ylim, find_minimal, &part, ctxt);
/* Use the partitions to split this problem into subproblems. */
- compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal);
- compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal);
+ compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal, ctxt);
+ compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal, ctxt);
}
}