Commit 027630dd by Edward Thomson

xdiff: update to xdiff from git 2.40.1

parent a821455e
...@@ -27,11 +27,14 @@ ...@@ -27,11 +27,14 @@
# endif # endif
#endif #endif
#define XDL_UNUSED GIT_UNUSED_ARG
#define xdl_malloc(x) git__malloc(x) #define xdl_malloc(x) git__malloc(x)
#define xdl_calloc(n, sz) git__calloc(n, sz)
#define xdl_free(ptr) git__free(ptr) #define xdl_free(ptr) git__free(ptr)
#define xdl_realloc(ptr, x) git__realloc(ptr, x) #define xdl_realloc(ptr, x) git__realloc(ptr, x)
#define XDL_BUG(msg) GIT_ASSERT(msg) #define XDL_BUG(msg) GIT_ASSERT(!msg)
#define xdl_regex_t git_regexp #define xdl_regex_t git_regexp
#define xdl_regmatch_t git_regmatch #define xdl_regmatch_t git_regmatch
......
...@@ -315,16 +315,19 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, ...@@ -315,16 +315,19 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
long *kvd, *kvdf, *kvdb; long *kvd, *kvdf, *kvdb;
xdalgoenv_t xenv; xdalgoenv_t xenv;
diffdata_t dd1, dd2; diffdata_t dd1, dd2;
int res;
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF) if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0)
return xdl_do_patience_diff(mf1, mf2, xpp, xe); return -1;
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) { if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF) {
res = xdl_do_patience_diff(xpp, xe);
goto out;
}
return -1; if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF) {
res = xdl_do_histogram_diff(xpp, xe);
goto out;
} }
/* /*
...@@ -334,7 +337,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, ...@@ -334,7 +337,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
* One is to store the forward path and one to store the backward path. * One is to store the forward path and one to store the backward path.
*/ */
ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3; ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) { if (!XDL_ALLOC_ARRAY(kvd, 2 * ndiags + 2)) {
xdl_free_env(xe); xdl_free_env(xe);
return -1; return -1;
...@@ -359,17 +362,15 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, ...@@ -359,17 +362,15 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
dd2.rchg = xe->xdf2.rchg; dd2.rchg = xe->xdf2.rchg;
dd2.rindex = xe->xdf2.rindex; dd2.rindex = xe->xdf2.rindex;
if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec, res = xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) { kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0,
&xenv);
xdl_free(kvd); xdl_free(kvd);
out:
if (res < 0)
xdl_free_env(xe); xdl_free_env(xe);
return -1;
}
xdl_free(kvd); return res;
return 0;
} }
...@@ -972,7 +973,7 @@ void xdl_free_script(xdchange_t *xscr) { ...@@ -972,7 +973,7 @@ void xdl_free_script(xdchange_t *xscr) {
} }
} }
static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, static int xdl_call_hunk_func(xdfenv_t *xe XDL_UNUSED, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg) xdemitconf_t const *xecfg)
{ {
xdchange_t *xch, *xche; xdchange_t *xch, *xche;
......
...@@ -56,9 +56,7 @@ int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr); ...@@ -56,9 +56,7 @@ int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
void xdl_free_script(xdchange_t *xscr); void xdl_free_script(xdchange_t *xscr);
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg); xdemitconf_t const *xecfg);
int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env);
xdfenv_t *env); int xdl_do_histogram_diff(xpparam_t const *xpp, xdfenv_t *env);
int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
xdfenv_t *env);
#endif /* #if !defined(XDIFFI_H) */ #endif /* #if !defined(XDIFFI_H) */
...@@ -65,7 +65,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) ...@@ -65,7 +65,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
*xscr = xch; *xscr = xch;
} }
if (*xscr == NULL) if (!*xscr)
return NULL; return NULL;
lxch = *xscr; lxch = *xscr;
...@@ -95,7 +95,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) ...@@ -95,7 +95,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
} }
static long def_ff(const char *rec, long len, char *buf, long sz, void *priv) static long def_ff(const char *rec, long len, char *buf, long sz)
{ {
if (len > 0 && if (len > 0 &&
(isalpha((unsigned char)*rec) || /* identifier? */ (isalpha((unsigned char)*rec) || /* identifier? */
...@@ -117,7 +117,7 @@ static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri, ...@@ -117,7 +117,7 @@ static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri,
const char *rec; const char *rec;
long len = xdl_get_rec(xdf, ri, &rec); long len = xdl_get_rec(xdf, ri, &rec);
if (!xecfg->find_func) if (!xecfg->find_func)
return def_ff(rec, len, buf, sz, xecfg->find_func_priv); return def_ff(rec, len, buf, sz);
return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv); return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv);
} }
......
...@@ -251,7 +251,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env, ...@@ -251,7 +251,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
int line1, int count1, int line2, int count2) int line1, int count1, int line2, int count2)
{ {
int b_ptr; int b_ptr;
int sz, ret = -1; int ret = -1;
struct histindex index; struct histindex index;
memset(&index, 0, sizeof(index)); memset(&index, 0, sizeof(index));
...@@ -265,23 +265,16 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env, ...@@ -265,23 +265,16 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
index.rcha.head = NULL; index.rcha.head = NULL;
index.table_bits = xdl_hashbits(count1); index.table_bits = xdl_hashbits(count1);
sz = index.records_size = 1 << index.table_bits; index.records_size = 1 << index.table_bits;
sz *= sizeof(struct record *); if (!XDL_CALLOC_ARRAY(index.records, index.records_size))
if (!(index.records = (struct record **) xdl_malloc(sz)))
goto cleanup; goto cleanup;
memset(index.records, 0, sz);
sz = index.line_map_size = count1; index.line_map_size = count1;
sz *= sizeof(struct record *); if (!XDL_CALLOC_ARRAY(index.line_map, index.line_map_size))
if (!(index.line_map = (struct record **) xdl_malloc(sz)))
goto cleanup; goto cleanup;
memset(index.line_map, 0, sz);
sz = index.line_map_size; if (!XDL_CALLOC_ARRAY(index.next_ptrs, index.line_map_size))
sz *= sizeof(unsigned int);
if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
goto cleanup; goto cleanup;
memset(index.next_ptrs, 0, sz);
/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */ /* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0) if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
...@@ -369,12 +362,8 @@ out: ...@@ -369,12 +362,8 @@ out:
return result; return result;
} }
int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2, int xdl_do_histogram_diff(xpparam_t const *xpp, xdfenv_t *env)
xpparam_t const *xpp, xdfenv_t *env)
{ {
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
return -1;
return histogram_diff(xpp, env, return histogram_diff(xpp, env,
env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1, env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1); env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b))) #define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
#define XDL_MASKBITS(b) ((1UL << (b)) - 1) #define XDL_MASKBITS(b) ((1UL << (b)) - 1)
#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b)) #define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
#define XDL_LE32_PUT(p, v) \ #define XDL_LE32_PUT(p, v) \
do { \ do { \
unsigned char *__p = (unsigned char *) (p); \ unsigned char *__p = (unsigned char *) (p); \
...@@ -50,5 +49,23 @@ do { \ ...@@ -50,5 +49,23 @@ do { \
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \ ((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
} while (0) } while (0)
/* Allocate an array of nr elements, returns NULL on failure */
#define XDL_ALLOC_ARRAY(p, nr) \
((p) = SIZE_MAX / sizeof(*(p)) >= (size_t)(nr) \
? xdl_malloc((nr) * sizeof(*(p))) \
: NULL)
/* Allocate an array of nr zeroed out elements, returns NULL on failure */
#define XDL_CALLOC_ARRAY(p, nr) ((p) = xdl_calloc(nr, sizeof(*(p))))
/*
* Ensure array p can accommodate at least nr elements, growing the
* array and updating alloc (which is the number of allocated
* elements) as necessary. Frees p and returns -1 on failure, returns
* 0 on success
*/
#define XDL_ALLOC_GROW(p, nr, alloc) \
(-!((nr) <= (alloc) || \
((p) = xdl_alloc_grow_helper((p), (nr), &(alloc), sizeof(*(p))))))
#endif /* #if !defined(XMACROS_H) */ #endif /* #if !defined(XMACROS_H) */
...@@ -88,7 +88,7 @@ static int xdl_cleanup_merge(xdmerge_t *c) ...@@ -88,7 +88,7 @@ static int xdl_cleanup_merge(xdmerge_t *c)
if (c->mode == 0) if (c->mode == 0)
count++; count++;
next_c = c->next; next_c = c->next;
xdl_free(c); free(c);
} }
return count; return count;
} }
...@@ -456,7 +456,7 @@ static void xdl_merge_two_conflicts(xdmerge_t *m) ...@@ -456,7 +456,7 @@ static void xdl_merge_two_conflicts(xdmerge_t *m)
m->chg1 = next_m->i1 + next_m->chg1 - m->i1; m->chg1 = next_m->i1 + next_m->chg1 - m->i1;
m->chg2 = next_m->i2 + next_m->chg2 - m->i2; m->chg2 = next_m->i2 + next_m->chg2 - m->i2;
m->next = next_m->next; m->next = next_m->next;
xdl_free(next_m); free(next_m);
} }
/* /*
...@@ -684,42 +684,42 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, ...@@ -684,42 +684,42 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2, int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
xmparam_t const *xmp, mmbuffer_t *result) xmparam_t const *xmp, mmbuffer_t *result)
{ {
xdchange_t *xscr1, *xscr2; xdchange_t *xscr1 = NULL, *xscr2 = NULL;
xdfenv_t xe1, xe2; xdfenv_t xe1, xe2;
int status; int status = -1;
xpparam_t const *xpp = &xmp->xpp; xpparam_t const *xpp = &xmp->xpp;
result->ptr = NULL; result->ptr = NULL;
result->size = 0; result->size = 0;
if (xdl_do_diff(orig, mf1, xpp, &xe1) < 0) { if (xdl_do_diff(orig, mf1, xpp, &xe1) < 0)
return -1; return -1;
}
if (xdl_do_diff(orig, mf2, xpp, &xe2) < 0) { if (xdl_do_diff(orig, mf2, xpp, &xe2) < 0)
xdl_free_env(&xe1); goto free_xe1; /* avoid double free of xe2 */
return -1;
}
if (xdl_change_compact(&xe1.xdf1, &xe1.xdf2, xpp->flags) < 0 || if (xdl_change_compact(&xe1.xdf1, &xe1.xdf2, xpp->flags) < 0 ||
xdl_change_compact(&xe1.xdf2, &xe1.xdf1, xpp->flags) < 0 || xdl_change_compact(&xe1.xdf2, &xe1.xdf1, xpp->flags) < 0 ||
xdl_build_script(&xe1, &xscr1) < 0) { xdl_build_script(&xe1, &xscr1) < 0)
xdl_free_env(&xe1); goto out;
return -1;
}
if (xdl_change_compact(&xe2.xdf1, &xe2.xdf2, xpp->flags) < 0 || if (xdl_change_compact(&xe2.xdf1, &xe2.xdf2, xpp->flags) < 0 ||
xdl_change_compact(&xe2.xdf2, &xe2.xdf1, xpp->flags) < 0 || xdl_change_compact(&xe2.xdf2, &xe2.xdf1, xpp->flags) < 0 ||
xdl_build_script(&xe2, &xscr2) < 0) { xdl_build_script(&xe2, &xscr2) < 0)
xdl_free_script(xscr1); goto out;
xdl_free_env(&xe1);
xdl_free_env(&xe2);
return -1;
}
status = 0;
if (!xscr1) { if (!xscr1) {
result->ptr = xdl_malloc(mf2->size); result->ptr = xdl_malloc(mf2->size);
if (!result->ptr)
goto out;
status = 0;
memcpy(result->ptr, mf2->ptr, mf2->size); memcpy(result->ptr, mf2->ptr, mf2->size);
result->size = mf2->size; result->size = mf2->size;
} else if (!xscr2) { } else if (!xscr2) {
result->ptr = xdl_malloc(mf1->size); result->ptr = xdl_malloc(mf1->size);
if (!result->ptr)
goto out;
status = 0;
memcpy(result->ptr, mf1->ptr, mf1->size); memcpy(result->ptr, mf1->ptr, mf1->size);
result->size = mf1->size; result->size = mf1->size;
} else { } else {
...@@ -727,11 +727,13 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2, ...@@ -727,11 +727,13 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
&xe2, xscr2, &xe2, xscr2,
xmp, result); xmp, result);
} }
out:
xdl_free_script(xscr1); xdl_free_script(xscr1);
xdl_free_script(xscr2); xdl_free_script(xscr2);
xdl_free_env(&xe1);
xdl_free_env(&xe2); xdl_free_env(&xe2);
free_xe1:
xdl_free_env(&xe1);
return status; return status;
} }
...@@ -69,7 +69,6 @@ struct hashmap { ...@@ -69,7 +69,6 @@ struct hashmap {
} *entries, *first, *last; } *entries, *first, *last;
/* were common records found? */ /* were common records found? */
unsigned long has_matches; unsigned long has_matches;
mmfile_t *file1, *file2;
xdfenv_t *env; xdfenv_t *env;
xpparam_t const *xpp; xpparam_t const *xpp;
}; };
...@@ -139,23 +138,17 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map, ...@@ -139,23 +138,17 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
* *
* It is assumed that env has been prepared using xdl_prepare(). * It is assumed that env has been prepared using xdl_prepare().
*/ */
static int fill_hashmap(mmfile_t *file1, mmfile_t *file2, static int fill_hashmap(xpparam_t const *xpp, xdfenv_t *env,
xpparam_t const *xpp, xdfenv_t *env,
struct hashmap *result, struct hashmap *result,
int line1, int count1, int line2, int count2) int line1, int count1, int line2, int count2)
{ {
result->file1 = file1;
result->file2 = file2;
result->xpp = xpp; result->xpp = xpp;
result->env = env; result->env = env;
/* We know exactly how large we want the hash map */ /* We know exactly how large we want the hash map */
result->alloc = count1 * 2; result->alloc = count1 * 2;
result->entries = (struct entry *) if (!XDL_CALLOC_ARRAY(result->entries, result->alloc))
xdl_malloc(result->alloc * sizeof(struct entry));
if (!result->entries)
return -1; return -1;
memset(result->entries, 0, result->alloc * sizeof(struct entry));
/* First, fill with entries from the first file */ /* First, fill with entries from the first file */
while (count1--) while (count1--)
...@@ -198,9 +191,9 @@ static int binary_search(struct entry **sequence, int longest, ...@@ -198,9 +191,9 @@ static int binary_search(struct entry **sequence, int longest,
* item per sequence length: the sequence with the smallest last * item per sequence length: the sequence with the smallest last
* element (in terms of line2). * element (in terms of line2).
*/ */
static struct entry *find_longest_common_sequence(struct hashmap *map) static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
{ {
struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *)); struct entry **sequence;
int longest = 0, i; int longest = 0, i;
struct entry *entry; struct entry *entry;
...@@ -211,6 +204,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map) ...@@ -211,6 +204,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
*/ */
int anchor_i = -1; int anchor_i = -1;
if (!XDL_ALLOC_ARRAY(sequence, map->nr))
return -1;
for (entry = map->first; entry; entry = entry->next) { for (entry = map->first; entry; entry = entry->next) {
if (!entry->line2 || entry->line2 == NON_UNIQUE) if (!entry->line2 || entry->line2 == NON_UNIQUE)
continue; continue;
...@@ -230,8 +226,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map) ...@@ -230,8 +226,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
/* No common unique lines were found */ /* No common unique lines were found */
if (!longest) { if (!longest) {
*res = NULL;
xdl_free(sequence); xdl_free(sequence);
return NULL; return 0;
} }
/* Iterate starting at the last element, adjusting the "next" members */ /* Iterate starting at the last element, adjusting the "next" members */
...@@ -241,8 +238,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map) ...@@ -241,8 +238,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
entry->previous->next = entry; entry->previous->next = entry;
entry = entry->previous; entry = entry->previous;
} }
*res = entry;
xdl_free(sequence); xdl_free(sequence);
return entry; return 0;
} }
static int match(struct hashmap *map, int line1, int line2) static int match(struct hashmap *map, int line1, int line2)
...@@ -252,8 +250,7 @@ static int match(struct hashmap *map, int line1, int line2) ...@@ -252,8 +250,7 @@ static int match(struct hashmap *map, int line1, int line2)
return record1->ha == record2->ha; return record1->ha == record2->ha;
} }
static int patience_diff(mmfile_t *file1, mmfile_t *file2, static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
xpparam_t const *xpp, xdfenv_t *env,
int line1, int count1, int line2, int count2); int line1, int count1, int line2, int count2);
static int walk_common_sequence(struct hashmap *map, struct entry *first, static int walk_common_sequence(struct hashmap *map, struct entry *first,
...@@ -284,8 +281,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first, ...@@ -284,8 +281,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
/* Recurse */ /* Recurse */
if (next1 > line1 || next2 > line2) { if (next1 > line1 || next2 > line2) {
if (patience_diff(map->file1, map->file2, if (patience_diff(map->xpp, map->env,
map->xpp, map->env,
line1, next1 - line1, line1, next1 - line1,
line2, next2 - line2)) line2, next2 - line2))
return -1; return -1;
...@@ -324,8 +320,7 @@ static int fall_back_to_classic_diff(struct hashmap *map, ...@@ -324,8 +320,7 @@ static int fall_back_to_classic_diff(struct hashmap *map,
* *
* This function assumes that env was prepared with xdl_prepare_env(). * This function assumes that env was prepared with xdl_prepare_env().
*/ */
static int patience_diff(mmfile_t *file1, mmfile_t *file2, static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
xpparam_t const *xpp, xdfenv_t *env,
int line1, int count1, int line2, int count2) int line1, int count1, int line2, int count2)
{ {
struct hashmap map; struct hashmap map;
...@@ -344,7 +339,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2, ...@@ -344,7 +339,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
} }
memset(&map, 0, sizeof(map)); memset(&map, 0, sizeof(map));
if (fill_hashmap(file1, file2, xpp, env, &map, if (fill_hashmap(xpp, env, &map,
line1, count1, line2, count2)) line1, count1, line2, count2))
return -1; return -1;
...@@ -358,25 +353,21 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2, ...@@ -358,25 +353,21 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
return 0; return 0;
} }
first = find_longest_common_sequence(&map); result = find_longest_common_sequence(&map, &first);
if (result)
goto out;
if (first) if (first)
result = walk_common_sequence(&map, first, result = walk_common_sequence(&map, first,
line1, count1, line2, count2); line1, count1, line2, count2);
else else
result = fall_back_to_classic_diff(&map, result = fall_back_to_classic_diff(&map,
line1, count1, line2, count2); line1, count1, line2, count2);
out:
xdl_free(map.entries); xdl_free(map.entries);
return result; return result;
} }
int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2, int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env)
xpparam_t const *xpp, xdfenv_t *env)
{ {
if (xdl_prepare_env(file1, file2, xpp, env) < 0) return patience_diff(xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec);
return -1;
/* environment is cleaned up in xdl_diff() */
return patience_diff(file1, file2, xpp, env,
1, env->xdf1.nrec, 1, env->xdf2.nrec);
} }
...@@ -78,15 +78,14 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) { ...@@ -78,15 +78,14 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
return -1; return -1;
} }
if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) { if (!XDL_CALLOC_ARRAY(cf->rchash, cf->hsize)) {
xdl_cha_free(&cf->ncha); xdl_cha_free(&cf->ncha);
return -1; return -1;
} }
memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
cf->alloc = size; cf->alloc = size;
if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) { if (!XDL_ALLOC_ARRAY(cf->rcrecs, cf->alloc)) {
xdl_free(cf->rchash); xdl_free(cf->rchash);
xdl_cha_free(&cf->ncha); xdl_cha_free(&cf->ncha);
...@@ -112,7 +111,6 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t ...@@ -112,7 +111,6 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
long hi; long hi;
char const *line; char const *line;
xdlclass_t *rcrec; xdlclass_t *rcrec;
xdlclass_t **rcrecs;
line = rec->ptr; line = rec->ptr;
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits); hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
...@@ -128,14 +126,8 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t ...@@ -128,14 +126,8 @@ static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t
return -1; return -1;
} }
rcrec->idx = cf->count++; rcrec->idx = cf->count++;
if (cf->count > cf->alloc) { if (XDL_ALLOC_GROW(cf->rcrecs, cf->count, cf->alloc))
cf->alloc *= 2;
if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
return -1; return -1;
}
cf->rcrecs = rcrecs;
}
cf->rcrecs[rcrec->idx] = rcrec; cf->rcrecs[rcrec->idx] = rcrec;
rcrec->line = line; rcrec->line = line;
rcrec->size = rec->size; rcrec->size = rec->size;
...@@ -164,7 +156,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_ ...@@ -164,7 +156,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
unsigned long hav; unsigned long hav;
char const *blk, *cur, *top, *prev; char const *blk, *cur, *top, *prev;
xrecord_t *crec; xrecord_t *crec;
xrecord_t **recs, **rrecs; xrecord_t **recs;
xrecord_t **rhash; xrecord_t **rhash;
unsigned long *ha; unsigned long *ha;
char *rchg; char *rchg;
...@@ -178,26 +170,21 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_ ...@@ -178,26 +170,21 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0) if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
goto abort; goto abort;
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *)))) if (!XDL_ALLOC_ARRAY(recs, narec))
goto abort; goto abort;
hbits = xdl_hashbits((unsigned int) narec); hbits = xdl_hashbits((unsigned int) narec);
hsize = 1 << hbits; hsize = 1 << hbits;
if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) if (!XDL_CALLOC_ARRAY(rhash, hsize))
goto abort; goto abort;
memset(rhash, 0, hsize * sizeof(xrecord_t *));
nrec = 0; nrec = 0;
if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) { if ((cur = blk = xdl_mmfile_first(mf, &bsize))) {
for (top = blk + bsize; cur < top; ) { for (top = blk + bsize; cur < top; ) {
prev = cur; prev = cur;
hav = xdl_hash_record(&cur, top, xpp->flags); hav = xdl_hash_record(&cur, top, xpp->flags);
if (nrec >= narec) { if (XDL_ALLOC_GROW(recs, nrec + 1, narec))
narec *= 2;
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
goto abort; goto abort;
recs = rrecs;
}
if (!(crec = xdl_cha_alloc(&xdf->rcha))) if (!(crec = xdl_cha_alloc(&xdf->rcha)))
goto abort; goto abort;
crec->ptr = prev; crec->ptr = prev;
...@@ -209,15 +196,14 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_ ...@@ -209,15 +196,14 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
} }
} }
if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char)))) if (!XDL_CALLOC_ARRAY(rchg, nrec + 2))
goto abort; goto abort;
memset(rchg, 0, (nrec + 2) * sizeof(char));
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) && if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) { (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)) {
if (!(rindex = xdl_malloc((nrec + 1) * sizeof(*rindex)))) if (!XDL_ALLOC_ARRAY(rindex, nrec + 1))
goto abort; goto abort;
if (!(ha = xdl_malloc((nrec + 1) * sizeof(*ha)))) if (!XDL_ALLOC_ARRAY(ha, nrec + 1))
goto abort; goto abort;
} }
...@@ -383,11 +369,8 @@ static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xd ...@@ -383,11 +369,8 @@ static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xd
xdlclass_t *rcrec; xdlclass_t *rcrec;
char *dis, *dis1, *dis2; char *dis, *dis1, *dis2;
if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) { if (!XDL_CALLOC_ARRAY(dis, xdf1->nrec + xdf2->nrec + 2))
return -1; return -1;
}
memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
dis1 = dis; dis1 = dis;
dis2 = dis1 + xdf1->nrec + 1; dis2 = dis1 + xdf1->nrec + 1;
......
...@@ -122,7 +122,7 @@ long xdl_guess_lines(mmfile_t *mf, long sample) { ...@@ -122,7 +122,7 @@ long xdl_guess_lines(mmfile_t *mf, long sample) {
long nl = 0, size, tsize = 0; long nl = 0, size, tsize = 0;
char const *data, *cur, *top; char const *data, *cur, *top;
if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) { if ((cur = data = xdl_mmfile_first(mf, &size))) {
for (top = data + size; nl < sample && cur < top; ) { for (top = data + size; nl < sample && cur < top; ) {
nl++; nl++;
if (!(cur = memchr(cur, '\n', top - cur))) if (!(cur = memchr(cur, '\n', top - cur)))
...@@ -432,3 +432,20 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp, ...@@ -432,3 +432,20 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
return 0; return 0;
} }
void* xdl_alloc_grow_helper(void *p, long nr, long *alloc, size_t size)
{
void *tmp = NULL;
size_t n = ((LONG_MAX - 16) / 2 >= *alloc) ? 2 * *alloc + 16 : LONG_MAX;
if (nr > n)
n = nr;
if (SIZE_MAX / size >= n)
tmp = xdl_realloc(p, n * size);
if (tmp) {
*alloc = n;
} else {
xdl_free(p);
*alloc = 0;
}
return tmp;
}
...@@ -42,6 +42,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, ...@@ -42,6 +42,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp, int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
int line1, int count1, int line2, int count2); int line1, int count1, int line2, int count2);
/* Do not call this function, use XDL_ALLOC_GROW instead */
void* xdl_alloc_grow_helper(void* p, long nr, long* alloc, size_t size);
#endif /* #if !defined(XUTILS_H) */ #endif /* #if !defined(XUTILS_H) */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment