diff options
Diffstat (limited to 'xdiff/xdiffi.c')
| -rw-r--r-- | xdiff/xdiffi.c | 102 |
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; } |
