From 2d1d1456ecd53204a71fc793cb9305eff4ba5928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 31 Mar 2013 22:20:35 +0200 Subject: [PATCH] Bind repository discovery --- c_src/geef.c | 1 + c_src/repository.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ c_src/repository.h | 1 + src/geef.erl | 6 ++++- src/geef_repo.erl | 6 ++++- 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/c_src/geef.c b/c_src/geef.c index c3dc544..5bbd5cc 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -84,6 +84,7 @@ static ErlNifFunc geef_funcs[] = { {"repository_init", 2, geef_repository_init}, {"repository_open", 1, geef_repository_open}, + {"repository_discover", 1, geef_repository_discover}, {"repository_is_bare", 1, geef_repository_is_bare}, {"repository_get_path", 1, geef_repository_path}, {"repository_get_workdir", 1, geef_repository_workdir}, diff --git a/c_src/repository.c b/c_src/repository.c index ff5bf38..cadd174 100644 --- a/c_src/repository.c +++ b/c_src/repository.c @@ -87,6 +87,62 @@ geef_repository_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return enif_make_tuple2(env, atoms.ok, term_repo); } +ERL_NIF_TERM +geef_repository_discover(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + char *path, *buffer; + size_t buffer_len; + ErlNifBinary bin, res_bin; + int error; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &bin)) + return enif_make_badarg(env); + + path = malloc(bin.size + 1); + if (!path) + return atoms.error; + + memcpy(path, bin.data, bin.size); + path[bin.size] = '\0'; + + buffer_len = 256; + buffer = malloc(buffer_len); + if (!buffer) + return atoms.error; + + while ((error = git_repository_discover(buffer, buffer_len, path, 0, NULL)) < 0 && + giterr_last()->klass == GITERR_REPOSITORY) { + char *tmp; + buffer_len *= 2; + tmp = realloc(buffer, buffer_len); + if (!tmp) { + free(path); + free(buffer); + return atoms.error; + } + + buffer = tmp; + } + + free(path); + + if (error < 0) { + free(buffer); + return geef_error(env); + } + + buffer_len = strlen(buffer); + if (!enif_alloc_binary(buffer_len, &res_bin)) { + free(buffer); + return atoms.error; + } + + memcpy(res_bin.data, buffer, buffer_len); + free(buffer); + + return enif_make_tuple2(env, atoms.ok, enif_make_binary(env, &res_bin)); +} + ERL_NIF_TERM geef_repository_path(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { diff --git a/c_src/repository.h b/c_src/repository.h index 9021aef..1c4b59d 100644 --- a/c_src/repository.h +++ b/c_src/repository.h @@ -8,6 +8,7 @@ ERL_NIF_TERM geef_repository_init(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_repository_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_repository_discover(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_workdir(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM geef_repository_is_bare(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); diff --git a/src/geef.erl b/src/geef.erl index 18995bd..19618de 100644 --- a/src/geef.erl +++ b/src/geef.erl @@ -5,7 +5,7 @@ % repository operations -export([repository_get_path/1, repository_get_odb/1, repository_open/1, repository_init/2, - repository_is_bare/1, repository_get_workdir/1]). + repository_is_bare/1, repository_get_workdir/1, repository_discover/1]). % oid parsing -export([oid_fmt/1, oid_parse/1]). @@ -41,6 +41,10 @@ repository_get_odb(_Val) -> repository_init(_Path, _Bare) -> nif_error(?LINE). +-spec repository_discover(iolist()) -> {ok, string()} | error. +repository_discover(_Path) -> + nif_error(?LINE). + reference_list(_Repo) -> nif_error(?LINE). diff --git a/src/geef_repo.erl b/src/geef_repo.erl index bb74eca..8756607 100644 --- a/src/geef_repo.erl +++ b/src/geef_repo.erl @@ -1,6 +1,6 @@ -module(geef_repo). --export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1]). +-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1]). -include("geef_records.hrl"). @@ -29,6 +29,10 @@ is_bare(#repo{handle=Handle}) -> references(#repo{handle=Handle}) -> geef:reference_list(Handle). +-spec discover(iolist()) -> {ok, binary()} | error | {error, term()}. +discover(Path) -> + geef:repository_discover(Path). + -spec open(iolist()) -> {ok, repo()} | {error, term()}. open(Path) -> case geef:repository_open(Path) of