diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-10-12 09:59:01 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-10-12 09:59:01 +0200 |
commit | bcf7c3d9ec2ea5636282256a8f6819a0cf3cde89 (patch) | |
tree | 8040b18b3402381edac03fe708edb45b2f6be2b8 | |
parent | 1454645d1e10da8e7e69a6d3700bbef0894d9f1c (diff) | |
download | libgit2-bcf7c3d9ec2ea5636282256a8f6819a0cf3cde89.tar.gz |
odb: support registering an ODB by name
This will be used for the repository format v1 extensions to allow a
user-provided backend to be automatically loaded when configured.
-rw-r--r-- | include/git2/odb_backend.h | 16 | ||||
-rw-r--r-- | src/backends.c | 43 | ||||
-rw-r--r-- | src/backends.h | 24 | ||||
-rw-r--r-- | tests/odb/registration.c | 27 |
4 files changed, 110 insertions, 0 deletions
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index b17cfd8ba..596dd18d9 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -129,6 +129,22 @@ struct git_odb_writepack { void (*free)(git_odb_writepack *writepack); }; +/** + * Constructor for an odb backend which is registered. + */ +typedef int (*git_odb_backend_ctor)(void *payload); + +/** + * Register a backend to be used instead of the default of the + * repository is configured to do so. + * + * @param name the name of the extension + * @param ctor constructor to call + * @param payload data passed to the constructor + * @return 0 or an error code + */ +GIT_EXTERN(int) git_odb_backend_register(const char *name, git_odb_backend_ctor ctor, void *payload); + GIT_END_DECL #endif diff --git a/src/backends.c b/src/backends.c new file mode 100644 index 000000000..0028fc0a3 --- /dev/null +++ b/src/backends.c @@ -0,0 +1,43 @@ +#include "git2.h" +#include "vector.h" +#include "backends.h" + +static git_vector odb_registrations = GIT_VECTOR_INIT; + +git_odb_registration *git_odb_backend__find(const char *name) +{ + size_t i; + git_odb_registration *reg; + + git_vector_foreach(&odb_registrations, i, reg) { + if (!strcmp(name, reg->name)) + return reg; + } + + return NULL; +} + +int git_odb_backend_register(const char *name, git_odb_backend_ctor ctor, void *payload) +{ + int error; + git_odb_registration *reg; + + reg = git__calloc(1, sizeof(git_odb_registration)); + GITERR_CHECK_ALLOC(reg); + + reg->name = git__strdup(name); + GITERR_CHECK_ALLOC(reg->name); + + reg->ctor = ctor; + reg->payload = payload; + + if ((error = git_vector_insert(&odb_registrations, reg)) < 0) + goto on_error; + + return 0; + +on_error: + git__free(reg->name); + git__free(reg); + return error; +} diff --git a/src/backends.h b/src/backends.h new file mode 100644 index 000000000..2b88676fe --- /dev/null +++ b/src/backends.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_backends_h__ +#define INCLUDE_backends_h__ + +#include "git2/common.h" +#include "git2/odb_backend.h" + +typedef struct { + char *name; + git_odb_backend_ctor ctor; + void *payload; +} git_odb_registration; + +/** + * Find an ODB registration by name + */ +git_odb_registration *git_odb_backend__find(const char *name); + +#endif diff --git a/tests/odb/registration.c b/tests/odb/registration.c new file mode 100644 index 000000000..c17cef45a --- /dev/null +++ b/tests/odb/registration.c @@ -0,0 +1,27 @@ +#include "clar_libgit2.h" +#include "backends.h" + +int payload_target; + +int odb_ctor(void *payload) +{ + GIT_UNUSED(payload); + + return 0; +} + +void test_odb_registration__register(void) +{ + git_odb_registration *reg; + + cl_git_pass(git_odb_backend_register("foo", odb_ctor, &payload_target)); + reg = git_odb_backend__find("foo"); + + cl_assert(reg); + cl_assert_equal_s("foo", reg->name); + cl_assert_equal_p(odb_ctor, reg->ctor); + cl_assert_equal_p(&payload_target, reg->payload); + + reg = git_odb_backend__find("bar"); + cl_assert_equal_p(NULL, reg); +} |