From 9cbf4024a0e178796382a42abcb815617d6fadaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 13 Aug 2012 23:53:31 +0200 Subject: [PATCH] Add a few basic functions for the repository --- c_src/geef.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++-- geef | 4 +++ src/geef.erl | 15 ++++++++- 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/c_src/geef.c b/c_src/geef.c index d2c1629..b4a17fd 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -5,6 +5,18 @@ #define MAXBUFLEN 1024 +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; + static ERL_NIF_TERM geef_hex_to_raw(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { @@ -50,10 +62,81 @@ 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); + + if (geef_repository_type == NULL) + return -1; + + geef_atoms.ok = enif_make_atom(env, "ok"); + geef_atoms.error = enif_make_atom(env, "error"); + geef_atoms.repository = enif_make_atom(env, "repository"); + + return 0; +} + +static ERL_NIF_TERM +geef_error(ErlNifEnv *env) +{ + const git_error *error; + + error = giterr_last(); + if (error) { + return enif_make_tuple2(env, geef_atoms.error, + enif_make_string(env, error->message, ERL_NIF_LATIN1)); + } + + return enif_make_tuple2(env, geef_atoms.error, + 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} + {"object_exists", 2, geef_object_exists}, + {"repository_open", 1, geef_repository_open}, + {"repository_get_path", 1, geef_repository_path}, }; -ERL_NIF_INIT(geef, geef_funcs, NULL, NULL, NULL, NULL) +ERL_NIF_INIT(geef, geef_funcs, load, NULL, NULL, NULL) diff --git a/geef b/geef index dfa2057..92133ba 100755 --- a/geef +++ b/geef @@ -14,6 +14,10 @@ main([Command|_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), + io:format("Repository path: ~s~n", [geef:repository_path(Repo)]); _Else -> usage() end; diff --git a/src/geef.erl b/src/geef.erl index 6c3bdaa..58325d8 100644 --- a/src/geef.erl +++ b/src/geef.erl @@ -1,5 +1,5 @@ -module(geef). --export([start/0, hex_to_raw/1, object_exists/2]). +-export([start/0, hex_to_raw/1, object_exists/2, repository/1, repository_path/1]). -on_load(start/0). start() -> @@ -18,5 +18,18 @@ hex_to_raw(_Val) -> object_exists(_Val, _Val2) -> nif_error(?LINE). +repository_open(_Val) -> + nif_error(?LINE). + +repository_get_path(_Val) -> + nif_error(?LINE). + +repository_path({repository, Handle}) -> + repository_get_path(Handle). + +repository(Path) -> + {ok, Repository} = repository_open(Path), + {repository, Repository}. + nif_error(Line) -> exit({nif_not_loaded,module,?MODULE,line,Line}).