summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-10-12 09:59:01 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-10-12 09:59:01 +0200
commitbcf7c3d9ec2ea5636282256a8f6819a0cf3cde89 (patch)
tree8040b18b3402381edac03fe708edb45b2f6be2b8
parent1454645d1e10da8e7e69a6d3700bbef0894d9f1c (diff)
downloadlibgit2-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.h16
-rw-r--r--src/backends.c43
-rw-r--r--src/backends.h24
-rw-r--r--tests/odb/registration.c27
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);
+}