From 27e72e51738667b2fbbe7a4e1c7da3d1292dc200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 14 Aug 2012 02:22:46 +0200 Subject: [PATCH] Refactor the code into separate files Separate repository/odb functions into their own file. Add odb_exists to go through the repository's odb. Adjust the test script. --- c_src/geef.c | 70 +++++++++-------------------------- c_src/geef.h | 18 +++++++++ c_src/repository.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ c_src/repository.h | 29 +++++++++++++++ geef | 12 +++--- src/geef.erl | 15 +++++++- 6 files changed, 176 insertions(+), 59 deletions(-) create mode 100644 c_src/geef.h create mode 100644 c_src/repository.c create mode 100644 c_src/repository.h diff --git a/c_src/geef.c b/c_src/geef.c index b4a17fd..371ac6c 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -1,21 +1,14 @@ #include "erl_nif.h" +#include "repository.h" +#include "geef.h" #include #include #include -#define MAXBUFLEN 1024 +ErlNifResourceType *geef_repository_type; +ErlNifResourceType *geef_odb_type; -static ErlNifResourceType *geef_repository_type; - -typedef struct { - git_repository *repo; -} geef_repository; - -static struct { - ERL_NIF_TERM ok; - ERL_NIF_TERM error; - ERL_NIF_TERM repository; -} geef_atoms; +geef_atoms_t geef_atoms; static ERL_NIF_TERM geef_hex_to_raw(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) @@ -62,28 +55,30 @@ geef_object_exists(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return enif_make_atom(env, "false"); } -static void repository_free(ErlNifEnv *env, void *cd) -{ - geef_repository *grepo = (geef_repository *) cd; - git_repository_free(grepo->repo); -} - static int load(ErlNifEnv *env, void **priv, ERL_NIF_TERM load_info) { geef_repository_type = enif_open_resource_type(env, NULL, - "repository_type", repository_free, ERL_NIF_RT_CREATE, NULL); + "repository_type", geef_repository_free, ERL_NIF_RT_CREATE, NULL); if (geef_repository_type == NULL) return -1; + geef_odb_type = enif_open_resource_type(env, NULL, + "odb_type", geef_odb_free, ERL_NIF_RT_CREATE, NULL); + + if (geef_odb_type == NULL) + return -1; + geef_atoms.ok = enif_make_atom(env, "ok"); geef_atoms.error = enif_make_atom(env, "error"); + geef_atoms.true = enif_make_atom(env, "true"); + geef_atoms.false = enif_make_atom(env, "false"); geef_atoms.repository = enif_make_atom(env, "repository"); return 0; } -static ERL_NIF_TERM +ERL_NIF_TERM geef_error(ErlNifEnv *env) { const git_error *error; @@ -98,45 +93,14 @@ geef_error(ErlNifEnv *env) enif_make_string(env, "No message specified", ERL_NIF_LATIN1)); } -static ERL_NIF_TERM -geef_repository_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) -{ - char path[MAXBUFLEN]; - git_repository *repo; - geef_repository *res_repo; - ERL_NIF_TERM term_repo; - - if (enif_get_string(env, argv[0], path, sizeof(path), ERL_NIF_LATIN1) < 1) - return enif_make_badarg(env); - - if (git_repository_open(&repo, path) < 0) - return geef_error(env); - - res_repo = enif_alloc_resource(geef_repository_type, sizeof(geef_repository)); - res_repo->repo = repo; - term_repo = enif_make_resource(env, res_repo); - enif_release_resource(res_repo); - - return enif_make_tuple2(env, geef_atoms.ok, term_repo); -} - -static ERL_NIF_TERM -geef_repository_path(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) -{ - geef_repository *repo; - - if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo)) - return enif_make_badarg(env); - - return enif_make_string(env, git_repository_path(repo->repo), ERL_NIF_LATIN1); -} - static ErlNifFunc geef_funcs[] = { {"hex_to_raw", 1, geef_hex_to_raw}, {"object_exists", 2, geef_object_exists}, {"repository_open", 1, geef_repository_open}, {"repository_get_path", 1, geef_repository_path}, + {"repository_get_odb", 1, geef_repository_odb}, + {"odb_object_exists", 2, geef_odb_exists}, }; ERL_NIF_INIT(geef, geef_funcs, load, NULL, NULL, NULL) diff --git a/c_src/geef.h b/c_src/geef.h new file mode 100644 index 0000000..6731133 --- /dev/null +++ b/c_src/geef.h @@ -0,0 +1,18 @@ +#ifndef GEEF_H +#define GEEF_H + +#include "erl_nif.h" + +ERL_NIF_TERM geef_error(ErlNifEnv *env); + +typedef struct { + ERL_NIF_TERM ok; + ERL_NIF_TERM error; + ERL_NIF_TERM true; + ERL_NIF_TERM false; + ERL_NIF_TERM repository; +} geef_atoms_t; + +extern geef_atoms_t geef_atoms; + +#endif diff --git a/c_src/repository.c b/c_src/repository.c new file mode 100644 index 0000000..e24b138 --- /dev/null +++ b/c_src/repository.c @@ -0,0 +1,91 @@ +#include "repository.h" +#include "geef.h" +#include + +void geef_repository_free(ErlNifEnv *env, void *cd) +{ + geef_repository *grepo = (geef_repository *) cd; + git_repository_free(grepo->repo); +} + +void geef_odb_free(ErlNifEnv *env, void *cd) +{ + geef_odb *odb = (geef_odb *) cd; + git_odb_free(odb->odb); +} + +ERL_NIF_TERM +geef_repository_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + char path[MAXBUFLEN]; + git_repository *repo; + geef_repository *res_repo; + ERL_NIF_TERM term_repo; + + if (enif_get_string(env, argv[0], path, sizeof(path), ERL_NIF_LATIN1) < 1) + return enif_make_badarg(env); + + if (git_repository_open(&repo, path) < 0) + return geef_error(env); + + res_repo = enif_alloc_resource(geef_repository_type, sizeof(geef_repository)); + res_repo->repo = repo; + term_repo = enif_make_resource(env, res_repo); + enif_release_resource(res_repo); + + return enif_make_tuple2(env, geef_atoms.ok, term_repo); +} + +ERL_NIF_TERM +geef_repository_path(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_repository *repo; + + if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo)) + return enif_make_badarg(env); + + return enif_make_string(env, git_repository_path(repo->repo), ERL_NIF_LATIN1); +} + +ERL_NIF_TERM +geef_repository_odb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_repository *repo; + geef_odb *odb; + ERL_NIF_TERM term_odb; + + if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo)) + return enif_make_badarg(env); + + odb = enif_alloc_resource(geef_odb_type, sizeof(geef_odb)); + if (git_repository_odb(&odb->odb, repo->repo) < 0) + return geef_error(env); + + term_odb = enif_make_resource(env, odb); + enif_release_resource(odb); + + return enif_make_tuple2(env, geef_atoms.ok, term_odb); +} + +ERL_NIF_TERM +geef_odb_exists(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + char sha[MAXBUFLEN] = {0}; + geef_odb *odb; + git_oid oid; + int exists; + + if (!enif_get_resource(env, argv[0], geef_odb_type, (void **) &odb)) + return enif_make_badarg(env); + + if (enif_get_string(env, argv[1], sha, sizeof(sha), ERL_NIF_LATIN1) < 1) + return enif_make_badarg(env); + + git_oid_fromstr(&oid, sha); + exists = git_odb_exists(odb->odb, &oid); + + if (exists) + return geef_atoms.true; + + return geef_atoms.false; +} diff --git a/c_src/repository.h b/c_src/repository.h new file mode 100644 index 0000000..068304e --- /dev/null +++ b/c_src/repository.h @@ -0,0 +1,29 @@ +#ifndef GEEF_REPOSTIORY_H +#define GEEF_REPOSTIORY_H + +#include "erl_nif.h" +#include + +#define MAXBUFLEN 1024 + +ERL_NIF_TERM geef_repository_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_repository_path(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_repository_odb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_odb_exists(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + + +void geef_repository_free(ErlNifEnv *env, void *cd); +void geef_odb_free(ErlNifEnv *env, void *cd); + +extern ErlNifResourceType *geef_repository_type; +extern ErlNifResourceType *geef_odb_type; + +typedef struct { + git_repository *repo; +} geef_repository; + +typedef struct { + git_odb *odb; +} geef_odb; + +#endif diff --git a/geef b/geef index c188741..32df128 100755 --- a/geef +++ b/geef @@ -2,17 +2,19 @@ %% -*- erlang -*- %%! debug verbose -noshell -pa ebin +main(["exists"|_Args]) -> + [Path|_Rest] = _Args, + [Object|_] = _Rest, + Repo = geef:repository(Path), + Odb = geef:repository_odb(Repo), + Exists = geef:odb_exists(Odb, Object), + io:format("Exists: ~w~n", [Exists]); main([Command|_Args]) -> case Command of "h2r" -> [Object|_Rest] = _Args, Raw = geef:hex_to_raw(Object), io:format("Raw: ~w~n", [Raw]); - "exists" -> - [Path|_Rest] = _Args, - [Object|_None] = _Rest, - Exists = geef:object_exists(Path, Object), - io:format("Exists: ~w~n", [Exists]); "repo-path" -> [Path|_Rest] = _Args, Repo = geef:repository(Path), diff --git a/src/geef.erl b/src/geef.erl index 4bb8bc7..c1baeb7 100644 --- a/src/geef.erl +++ b/src/geef.erl @@ -1,5 +1,5 @@ -module(geef). --export([hex_to_raw/1, object_exists/2, repository/1, repository_path/1]). +-export([hex_to_raw/1, object_exists/2, repository/1, repository_path/1, repository_odb/1, odb_exists/2]). -on_load(load_enif/0). hex_to_raw(_Val) -> @@ -14,6 +14,9 @@ repository_open(_Val) -> repository_get_path(_Val) -> nif_error(?LINE). +repository_get_odb(_Val) -> + nif_error(?LINE). + repository_path({repository, Handle}) -> repository_get_path(Handle). @@ -21,6 +24,16 @@ repository(Path) -> {ok, Repository} = repository_open(Path), {repository, Repository}. +repository_odb({repository, Handle}) -> + {ok, Odb} = repository_get_odb(Handle), + {odb, Odb}. + +odb_object_exists(_Val, _Val) -> + nif_error(?LINE). + +odb_exists({odb, Handle}, Sha) -> + odb_object_exists(Handle, Sha). + nif_error(Line) -> exit({nif_not_loaded,module,?MODULE,line,Line}).