Commit 6816f30c by Edward Thomson

Use the correct function definition for function pointers

Passing a function pointer with different parameters is UB, even if
those params are (void *). Use our separate `_cb` functions that will do
the correct casting.
parent 032a8c2d
...@@ -26,9 +26,10 @@ ...@@ -26,9 +26,10 @@
#define iterator__ignore_dot_git(I) iterator__flag(I,IGNORE_DOT_GIT) #define iterator__ignore_dot_git(I) iterator__flag(I,IGNORE_DOT_GIT)
#define iterator__descend_symlinks(I) iterator__flag(I,DESCEND_SYMLINKS) #define iterator__descend_symlinks(I) iterator__flag(I,DESCEND_SYMLINKS)
static void iterator_set_ignore_case(git_iterator *iter, bool ignore_case) static void iterator_set_ignore_case(git_iterator *iter, bool ignore_case)
{ {
int (*vector_cmp)(const void *a, const void *b);
if (ignore_case) if (ignore_case)
iter->flags |= GIT_ITERATOR_IGNORE_CASE; iter->flags |= GIT_ITERATOR_IGNORE_CASE;
else else
...@@ -39,7 +40,9 @@ static void iterator_set_ignore_case(git_iterator *iter, bool ignore_case) ...@@ -39,7 +40,9 @@ static void iterator_set_ignore_case(git_iterator *iter, bool ignore_case)
iter->prefixcomp = ignore_case ? git__prefixcmp_icase : git__prefixcmp; iter->prefixcomp = ignore_case ? git__prefixcmp_icase : git__prefixcmp;
iter->entry_srch = ignore_case ? git_index_entry_isrch : git_index_entry_srch; iter->entry_srch = ignore_case ? git_index_entry_isrch : git_index_entry_srch;
git_vector_set_cmp(&iter->pathlist, (git_vector_cmp)iter->strcomp); vector_cmp = ignore_case ? git__strcasecmp_cb : git__strcmp_cb;
git_vector_set_cmp(&iter->pathlist, vector_cmp);
} }
static int iterator_range_init( static int iterator_range_init(
...@@ -299,6 +302,7 @@ typedef enum { ...@@ -299,6 +302,7 @@ typedef enum {
static iterator_pathlist_search_t iterator_pathlist_search( static iterator_pathlist_search_t iterator_pathlist_search(
git_iterator *iter, const char *path, size_t path_len) git_iterator *iter, const char *path, size_t path_len)
{ {
int (*vector_cmp)(const void *a, const void *b);
const char *p; const char *p;
size_t idx; size_t idx;
int error; int error;
...@@ -308,8 +312,10 @@ static iterator_pathlist_search_t iterator_pathlist_search( ...@@ -308,8 +312,10 @@ static iterator_pathlist_search_t iterator_pathlist_search(
git_vector_sort(&iter->pathlist); git_vector_sort(&iter->pathlist);
error = git_vector_bsearch2(&idx, &iter->pathlist, vector_cmp = (iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0 ?
(git_vector_cmp)iter->strcomp, path); git__strcasecmp_cb : git__strcmp_cb;
error = git_vector_bsearch2(&idx, &iter->pathlist, vector_cmp, path);
/* the given path was found in the pathlist. since the pathlist only /* the given path was found in the pathlist. since the pathlist only
* matches directories when they're suffixed with a '/', analyze the * matches directories when they're suffixed with a '/', analyze the
......
...@@ -1080,6 +1080,12 @@ int git_reference_cmp( ...@@ -1080,6 +1080,12 @@ int git_reference_cmp(
return git_oid__cmp(&ref1->target.oid, &ref2->target.oid); return git_oid__cmp(&ref1->target.oid, &ref2->target.oid);
} }
int git_reference__cmp_cb(const void *a, const void *b)
{
return git_reference_cmp(
(const git_reference *)a, (const git_reference *)b);
}
/* /*
* Starting with the reference given by `ref_name`, follows symbolic * Starting with the reference given by `ref_name`, follows symbolic
* references until a direct reference is found and updated the OID * references until a direct reference is found and updated the OID
......
...@@ -92,6 +92,12 @@ int git_reference__is_tag(const char *ref_name); ...@@ -92,6 +92,12 @@ int git_reference__is_tag(const char *ref_name);
int git_reference__is_note(const char *ref_name); int git_reference__is_note(const char *ref_name);
const char *git_reference__shorthand(const char *name); const char *git_reference__shorthand(const char *name);
/*
* A `git_reference_cmp` wrapper suitable for passing to generic
* comparators, like `vector_cmp` / `tsort` / etc.
*/
int git_reference__cmp_cb(const void *a, const void *b);
/** /**
* Lookup a reference by name and try to resolve to an OID. * Lookup a reference by name and try to resolve to an OID.
* *
......
...@@ -585,9 +585,9 @@ void test_iterator_workdir__filesystem(void) ...@@ -585,9 +585,9 @@ void test_iterator_workdir__filesystem(void)
expect_iterator_items(i, 5, expect_noauto, 18, expect_trees); expect_iterator_items(i, 5, expect_noauto, 18, expect_trees);
git_iterator_free(i); git_iterator_free(i);
git__tsort((void **)expect_base, 8, (git__tsort_cmp)git__strcasecmp); git__tsort((void **)expect_base, 8, git__strcasecmp_cb);
git__tsort((void **)expect_trees, 18, (git__tsort_cmp)git__strcasecmp); git__tsort((void **)expect_trees, 18, git__strcasecmp_cb);
git__tsort((void **)expect_noauto, 5, (git__tsort_cmp)git__strcasecmp); git__tsort((void **)expect_noauto, 5, git__strcasecmp_cb);
i_opts.flags = GIT_ITERATOR_IGNORE_CASE; i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
cl_git_pass(git_iterator_for_filesystem(&i, "status/subdir", &i_opts)); cl_git_pass(git_iterator_for_filesystem(&i, "status/subdir", &i_opts));
......
...@@ -216,7 +216,7 @@ void test_network_remote_rename__symref_head(void) ...@@ -216,7 +216,7 @@ void test_network_remote_rename__symref_head(void)
cl_assert_equal_i(0, problems.count); cl_assert_equal_i(0, problems.count);
git_strarray_dispose(&problems); git_strarray_dispose(&problems);
cl_git_pass(git_vector_init(&refs, 2, (git_vector_cmp) git_reference_cmp)); cl_git_pass(git_vector_init(&refs, 2, git_reference__cmp_cb));
cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE)); cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));
while ((error = git_branch_next(&ref, &btype, iter)) == 0) { while ((error = git_branch_next(&ref, &btype, iter)) == 0) {
......
...@@ -7,6 +7,11 @@ typedef struct { ...@@ -7,6 +7,11 @@ typedef struct {
size_t position; size_t position;
} fake_backend; } fake_backend;
static void odb_backend_free(git_odb_backend *odb)
{
git__free(odb);
}
static git_odb_backend *new_backend(size_t position) static git_odb_backend *new_backend(size_t position)
{ {
fake_backend *b; fake_backend *b;
...@@ -15,7 +20,7 @@ static git_odb_backend *new_backend(size_t position) ...@@ -15,7 +20,7 @@ static git_odb_backend *new_backend(size_t position)
if (b == NULL) if (b == NULL)
return NULL; return NULL;
b->base.free = (void (*)(git_odb_backend *)) git__free; b->base.free = odb_backend_free;
b->base.version = GIT_ODB_BACKEND_VERSION; b->base.version = GIT_ODB_BACKEND_VERSION;
b->position = position; b->position = position;
return (git_odb_backend *)b; return (git_odb_backend *)b;
......
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