diff --git a/src/diff_tform.c b/src/diff_tform.c index ae0fd36d6..66a4702f2 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -170,21 +170,21 @@ int git_diff_merge( return error; } -#define FIND_SIMILAR_HASHSIG(NAME,OPT) \ - static int find_similar__hashsig_for_file ## NAME( \ - void **out, const git_diff_file *f, const char *path, void *p) { \ - GIT_UNUSED(f); GIT_UNUSED(p); \ - return git_hashsig_create_fromfile((git_hashsig **)out, path, OPT); \ - } \ - static int find_similar__hashsig_for_buf ## NAME( \ - void **out, const git_diff_file *f, const char *buf, size_t len, void *p) { \ - GIT_UNUSED(f); GIT_UNUSED(p); \ - return git_hashsig_create((git_hashsig **)out, buf, len, OPT); \ - } +static int find_similar__hashsig_for_file( + void **out, const git_diff_file *f, const char *path, void *p) +{ + git_hashsig_option_t opt = (git_hashsig_option_t)p; + GIT_UNUSED(f); + return git_hashsig_create_fromfile((git_hashsig **)out, path, opt); +} -FIND_SIMILAR_HASHSIG(_default, GIT_HASHSIG_SMART_WHITESPACE); -FIND_SIMILAR_HASHSIG(_ignore_whitespace, GIT_HASHSIG_IGNORE_WHITESPACE); -FIND_SIMILAR_HASHSIG(_include_whitespace, GIT_HASHSIG_NORMAL); +static int find_similar__hashsig_for_buf( + void **out, const git_diff_file *f, const char *buf, size_t len, void *p) +{ + git_hashsig_option_t opt = (git_hashsig_option_t)p; + GIT_UNUSED(f); + return git_hashsig_create((git_hashsig **)out, buf, len, opt); +} static void find_similar__hashsig_free(void *sig, void *payload) { @@ -200,30 +200,6 @@ static int find_similar__calc_similarity( return 0; } -static git_diff_similarity_metric find_similar__internal_metrics[3] = { - { - find_similar__hashsig_for_file_default, - find_similar__hashsig_for_buf_default, - find_similar__hashsig_free, - find_similar__calc_similarity, - NULL - }, - { - find_similar__hashsig_for_file_ignore_whitespace, - find_similar__hashsig_for_buf_ignore_whitespace, - find_similar__hashsig_free, - find_similar__calc_similarity, - NULL - }, - { - find_similar__hashsig_for_file_include_whitespace, - find_similar__hashsig_for_buf_include_whitespace, - find_similar__hashsig_free, - find_similar__calc_similarity, - NULL - } -}; - #define DEFAULT_THRESHOLD 50 #define DEFAULT_BREAK_REWRITE_THRESHOLD 60 #define DEFAULT_TARGET_LIMIT 200 @@ -292,14 +268,22 @@ static int normalize_find_opts( opts->target_limit = limit; } - /* for now, always assign the same internal metric */ + /* assign the internal metric with whitespace flag as payload */ if (!opts->metric) { + opts->metric = git__malloc(sizeof(git_diff_similarity_metric)); + GITERR_CHECK_ALLOC(opts->metric); + + opts->metric->file_signature = find_similar__hashsig_for_file; + opts->metric->buffer_signature = find_similar__hashsig_for_buf; + opts->metric->free_signature = find_similar__hashsig_free; + opts->metric->similarity = find_similar__calc_similarity; + if (opts->flags & GIT_DIFF_FIND_IGNORE_WHITESPACE) - opts->metric = &find_similar__internal_metrics[1]; + opts->metric->payload = (void *)GIT_HASHSIG_IGNORE_WHITESPACE; else if (opts->flags & GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE) - opts->metric = &find_similar__internal_metrics[2]; + opts->metric->payload = (void *)GIT_HASHSIG_NORMAL; else - opts->metric = &find_similar__internal_metrics[0]; + opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE; } return 0; @@ -667,6 +651,9 @@ cleanup: } git__free(cache); + if (!given_opts || !given_opts->metric) + git__free(opts.metric); + return error; }