summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-02-22 10:19:50 -0800
committerRussell Belfer <rb@github.com>2013-02-22 10:19:50 -0800
commitf8275890676a56735b1af1abde859722f040a61c (patch)
tree2188b1f253f33a4ff4a2e32420a0a72148486282
parent6f9d5ce818f76d305a7aecf727ecda8cff63259c (diff)
downloadlibgit2-f8275890676a56735b1af1abde859722f040a61c.tar.gz
Replace static data with configured metric
Instead of creating three git_diff_similarity_metric statically for the various config options, just create the metric structure on demand and populate it, using the payload to specific the extra flags that should be passed to the hashsig. This removes a level of obfuscation from the code, I think.
-rw-r--r--src/diff_tform.c71
1 files changed, 29 insertions, 42 deletions
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;
}