summaryrefslogtreecommitdiff
path: root/xdiff/xdiffi.c
diff options
context:
space:
mode:
Diffstat (limited to 'xdiff/xdiffi.c')
-rw-r--r--xdiff/xdiffi.c102
1 files changed, 45 insertions, 57 deletions
diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c
index 5a96e36dfb..6f3998ee54 100644
--- a/xdiff/xdiffi.c
+++ b/xdiff/xdiffi.c
@@ -22,6 +22,11 @@
#include "xinclude.h"
+static unsigned long get_hash(xdfile_t *xdf, long index)
+{
+ return xdf->recs[xdf->rindex[index]].ha;
+}
+
#define XDL_MAX_COST_MIN 256
#define XDL_HEUR_MIN_COST 256
#define XDL_LINE_MAX (long)((1UL << (CHAR_BIT * sizeof(long) - 1)) - 1)
@@ -42,8 +47,8 @@ typedef struct s_xdpsplit {
* using this algorithm, so a little bit of heuristic is needed to cut the
* search and to return a suboptimal point.
*/
-static long xdl_split(unsigned long const *ha1, long off1, long lim1,
- unsigned long const *ha2, long off2, long lim2,
+static long xdl_split(xdfile_t *xdf1, long off1, long lim1,
+ xdfile_t *xdf2, long off2, long lim2,
long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
xdalgoenv_t *xenv) {
long dmin = off1 - lim2, dmax = lim1 - off2;
@@ -87,7 +92,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
i1 = kvdf[d + 1];
prev1 = i1;
i2 = i1 - d;
- for (; i1 < lim1 && i2 < lim2 && ha1[i1] == ha2[i2]; i1++, i2++);
+ for (; i1 < lim1 && i2 < lim2 && get_hash(xdf1, i1) == get_hash(xdf2, i2); i1++, i2++);
if (i1 - prev1 > xenv->snake_cnt)
got_snake = 1;
kvdf[d] = i1;
@@ -124,7 +129,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
i1 = kvdb[d + 1] - 1;
prev1 = i1;
i2 = i1 - d;
- for (; i1 > off1 && i2 > off2 && ha1[i1 - 1] == ha2[i2 - 1]; i1--, i2--);
+ for (; i1 > off1 && i2 > off2 && get_hash(xdf1, i1 - 1) == get_hash(xdf2, i2 - 1); i1--, i2--);
if (prev1 - i1 > xenv->snake_cnt)
got_snake = 1;
kvdb[d] = i1;
@@ -159,7 +164,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
if (v > XDL_K_HEUR * ec && v > best &&
off1 + xenv->snake_cnt <= i1 && i1 < lim1 &&
off2 + xenv->snake_cnt <= i2 && i2 < lim2) {
- for (k = 1; ha1[i1 - k] == ha2[i2 - k]; k++)
+ for (k = 1; get_hash(xdf1, i1 - k) == get_hash(xdf2, i2 - k); k++)
if (k == xenv->snake_cnt) {
best = v;
spl->i1 = i1;
@@ -183,7 +188,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
if (v > XDL_K_HEUR * ec && v > best &&
off1 < i1 && i1 <= lim1 - xenv->snake_cnt &&
off2 < i2 && i2 <= lim2 - xenv->snake_cnt) {
- for (k = 0; ha1[i1 + k] == ha2[i2 + k]; k++)
+ for (k = 0; get_hash(xdf1, i1 + k) == get_hash(xdf2, i2 + k); k++)
if (k == xenv->snake_cnt - 1) {
best = v;
spl->i1 = i1;
@@ -257,33 +262,26 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
* sub-boxes by calling the box splitting function. Note that the real job
* (marking changed lines) is done in the two boundary reaching checks.
*/
-int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
- diffdata_t *dd2, long off2, long lim2,
+int xdl_recs_cmp(xdfile_t *xdf1, long off1, long lim1,
+ xdfile_t *xdf2, long off2, long lim2,
long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv) {
- unsigned long const *ha1 = dd1->ha, *ha2 = dd2->ha;
/*
* Shrink the box by walking through each diagonal snake (SW and NE).
*/
- for (; off1 < lim1 && off2 < lim2 && ha1[off1] == ha2[off2]; off1++, off2++);
- for (; off1 < lim1 && off2 < lim2 && ha1[lim1 - 1] == ha2[lim2 - 1]; lim1--, lim2--);
+ for (; off1 < lim1 && off2 < lim2 && get_hash(xdf1, off1) == get_hash(xdf2, off2); off1++, off2++);
+ for (; off1 < lim1 && off2 < lim2 && get_hash(xdf1, lim1 - 1) == get_hash(xdf2, lim2 - 1); lim1--, lim2--);
/*
* If one dimension is empty, then all records on the other one must
* be obviously changed.
*/
if (off1 == lim1) {
- char *rchg2 = dd2->rchg;
- long *rindex2 = dd2->rindex;
-
for (; off2 < lim2; off2++)
- rchg2[rindex2[off2]] = 1;
+ xdf2->changed[xdf2->rindex[off2]] = true;
} else if (off2 == lim2) {
- char *rchg1 = dd1->rchg;
- long *rindex1 = dd1->rindex;
-
for (; off1 < lim1; off1++)
- rchg1[rindex1[off1]] = 1;
+ xdf1->changed[xdf1->rindex[off1]] = true;
} else {
xdpsplit_t spl;
spl.i1 = spl.i2 = 0;
@@ -291,7 +289,7 @@ int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
/*
* Divide ...
*/
- if (xdl_split(ha1, off1, lim1, ha2, off2, lim2, kvdf, kvdb,
+ if (xdl_split(xdf1, off1, lim1, xdf2, off2, lim2, kvdf, kvdb,
need_min, &spl, xenv) < 0) {
return -1;
@@ -300,9 +298,9 @@ int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
/*
* ... et Impera.
*/
- if (xdl_recs_cmp(dd1, off1, spl.i1, dd2, off2, spl.i2,
+ if (xdl_recs_cmp(xdf1, off1, spl.i1, xdf2, off2, spl.i2,
kvdf, kvdb, spl.min_lo, xenv) < 0 ||
- xdl_recs_cmp(dd1, spl.i1, lim1, dd2, spl.i2, lim2,
+ xdl_recs_cmp(xdf1, spl.i1, lim1, xdf2, spl.i2, lim2,
kvdf, kvdb, spl.min_hi, xenv) < 0) {
return -1;
@@ -318,7 +316,6 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
long ndiags;
long *kvd, *kvdf, *kvdb;
xdalgoenv_t xenv;
- diffdata_t dd1, dd2;
int res;
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0)
@@ -357,16 +354,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xenv.snake_cnt = XDL_SNAKE_CNT;
xenv.heur_min = XDL_HEUR_MIN_COST;
- dd1.nrec = xe->xdf1.nreff;
- dd1.ha = xe->xdf1.ha;
- dd1.rchg = xe->xdf1.rchg;
- dd1.rindex = xe->xdf1.rindex;
- dd2.nrec = xe->xdf2.nreff;
- dd2.ha = xe->xdf2.ha;
- dd2.rchg = xe->xdf2.rchg;
- dd2.rindex = xe->xdf2.rindex;
-
- res = xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
+ res = xdl_recs_cmp(&xe->xdf1, 0, xe->xdf1.nreff, &xe->xdf2, 0, xe->xdf2.nreff,
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0,
&xenv);
xdl_free(kvd);
@@ -501,13 +489,13 @@ static void measure_split(const xdfile_t *xdf, long split,
m->indent = -1;
} else {
m->end_of_file = 0;
- m->indent = get_indent(xdf->recs[split]);
+ m->indent = get_indent(&xdf->recs[split]);
}
m->pre_blank = 0;
m->pre_indent = -1;
for (i = split - 1; i >= 0; i--) {
- m->pre_indent = get_indent(xdf->recs[i]);
+ m->pre_indent = get_indent(&xdf->recs[i]);
if (m->pre_indent != -1)
break;
m->pre_blank += 1;
@@ -520,7 +508,7 @@ static void measure_split(const xdfile_t *xdf, long split,
m->post_blank = 0;
m->post_indent = -1;
for (i = split + 1; i < xdf->nrec; i++) {
- m->post_indent = get_indent(xdf->recs[i]);
+ m->post_indent = get_indent(&xdf->recs[i]);
if (m->post_indent != -1)
break;
m->post_blank += 1;
@@ -720,7 +708,7 @@ struct xdlgroup {
static void group_init(xdfile_t *xdf, struct xdlgroup *g)
{
g->start = g->end = 0;
- while (xdf->rchg[g->end])
+ while (xdf->changed[g->end])
g->end++;
}
@@ -734,7 +722,7 @@ static inline int group_next(xdfile_t *xdf, struct xdlgroup *g)
return -1;
g->start = g->end + 1;
- for (g->end = g->start; xdf->rchg[g->end]; g->end++)
+ for (g->end = g->start; xdf->changed[g->end]; g->end++)
;
return 0;
@@ -750,7 +738,7 @@ static inline int group_previous(xdfile_t *xdf, struct xdlgroup *g)
return -1;
g->end = g->start - 1;
- for (g->start = g->end; xdf->rchg[g->start - 1]; g->start--)
+ for (g->start = g->end; xdf->changed[g->start - 1]; g->start--)
;
return 0;
@@ -764,11 +752,11 @@ static inline int group_previous(xdfile_t *xdf, struct xdlgroup *g)
static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g)
{
if (g->end < xdf->nrec &&
- recs_match(xdf->recs[g->start], xdf->recs[g->end])) {
- xdf->rchg[g->start++] = 0;
- xdf->rchg[g->end++] = 1;
+ recs_match(&xdf->recs[g->start], &xdf->recs[g->end])) {
+ xdf->changed[g->start++] = false;
+ xdf->changed[g->end++] = true;
- while (xdf->rchg[g->end])
+ while (xdf->changed[g->end])
g->end++;
return 0;
@@ -785,11 +773,11 @@ static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g)
static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g)
{
if (g->start > 0 &&
- recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1])) {
- xdf->rchg[--g->start] = 1;
- xdf->rchg[--g->end] = 0;
+ recs_match(&xdf->recs[g->start - 1], &xdf->recs[g->end - 1])) {
+ xdf->changed[--g->start] = true;
+ xdf->changed[--g->end] = false;
- while (xdf->rchg[g->start - 1])
+ while (xdf->changed[g->start - 1])
g->start--;
return 0;
@@ -944,16 +932,16 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr) {
xdchange_t *cscr = NULL, *xch;
- char *rchg1 = xe->xdf1.rchg, *rchg2 = xe->xdf2.rchg;
+ bool *changed1 = xe->xdf1.changed, *changed2 = xe->xdf2.changed;
long i1, i2, l1, l2;
/*
* Trivial. Collects "groups" of changes and creates an edit script.
*/
for (i1 = xe->xdf1.nrec, i2 = xe->xdf2.nrec; i1 >= 0 || i2 >= 0; i1--, i2--)
- if (rchg1[i1 - 1] || rchg2[i2 - 1]) {
- for (l1 = i1; rchg1[i1 - 1]; i1--);
- for (l2 = i2; rchg2[i2 - 1]; i2--);
+ if (changed1[i1 - 1] || changed2[i2 - 1]) {
+ for (l1 = i1; changed1[i1 - 1]; i1--);
+ for (l2 = i2; changed2[i2 - 1]; i2--);
if (!(xch = xdl_add_change(cscr, i1, i2, l1 - i1, l2 - i2))) {
xdl_free_script(cscr);
@@ -1000,16 +988,16 @@ static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags)
for (xch = xscr; xch; xch = xch->next) {
int ignore = 1;
- xrecord_t **rec;
+ xrecord_t *rec;
long i;
rec = &xe->xdf1.recs[xch->i1];
for (i = 0; i < xch->chg1 && ignore; i++)
- ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
+ ignore = xdl_blankline(rec[i].ptr, rec[i].size, flags);
rec = &xe->xdf2.recs[xch->i2];
for (i = 0; i < xch->chg2 && ignore; i++)
- ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
+ ignore = xdl_blankline(rec[i].ptr, rec[i].size, flags);
xch->ignore = ignore;
}
@@ -1033,7 +1021,7 @@ static void xdl_mark_ignorable_regex(xdchange_t *xscr, const xdfenv_t *xe,
xdchange_t *xch;
for (xch = xscr; xch; xch = xch->next) {
- xrecord_t **rec;
+ xrecord_t *rec;
int ignore = 1;
long i;
@@ -1045,11 +1033,11 @@ static void xdl_mark_ignorable_regex(xdchange_t *xscr, const xdfenv_t *xe,
rec = &xe->xdf1.recs[xch->i1];
for (i = 0; i < xch->chg1 && ignore; i++)
- ignore = record_matches_regex(rec[i], xpp);
+ ignore = record_matches_regex(&rec[i], xpp);
rec = &xe->xdf2.recs[xch->i2];
for (i = 0; i < xch->chg2 && ignore; i++)
- ignore = record_matches_regex(rec[i], xpp);
+ ignore = record_matches_regex(&rec[i], xpp);
xch->ignore = ignore;
}