From 29d468c90a877d220667404d449a594677effbf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 19 May 2014 12:15:14 +0200 Subject: [PATCH] Add missing files --- c_src/config.c | 94 ++++++++++++++++++++++++++++++++++ c_src/config.h | 17 ++++++ c_src/geef.c | 1 + src/geef_config.erl | 122 ++++++++++++++++++++++++++++++++++++++++++++ src/geef_nif.erl | 4 ++ 5 files changed, 238 insertions(+) create mode 100644 c_src/config.c create mode 100644 c_src/config.h create mode 100644 src/geef_config.erl diff --git a/c_src/config.c b/c_src/config.c new file mode 100644 index 0000000..974d669 --- /dev/null +++ b/c_src/config.c @@ -0,0 +1,94 @@ +#include "config.h" +#include "geef.h" +#include + +void geef_config_free(ErlNifEnv *env, void *cd) +{ + geef_config *cfg = (geef_config *) cd; + git_config_free(cfg->config); +} + +static ERL_NIF_TERM extract(geef_config **cfg, ErlNifBinary *bin, ErlNifEnv *env, const ERL_NIF_TERM argv[]) +{ + if (!enif_get_resource(env, argv[0], geef_config_type, (void **) cfg)) + return enif_make_badarg(env); + + if (!enif_inspect_iolist_as_binary(env, argv[1], bin)) + return enif_make_badarg(env); + + if (!geef_terminate_binary(bin)) + return geef_oom(env); + + return atoms.ok; +} + +ERL_NIF_TERM +geef_config_set_bool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_config *cfg; + ErlNifBinary bin; + int error, val; + ERL_NIF_TERM ret; + + ret = extract(&cfg, &bin, env, argv); + if (ret != atoms.ok) + return ret; + + val = !enif_compare(argv[2], atoms.true); + + error = git_config_set_bool(cfg->config, (char *) bin.data, val); + enif_release_binary(&bin); + + if (error < 0) + return geef_error(env); + + return atoms.ok; +} + +ERL_NIF_TERM +geef_config_get_bool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_config *cfg; + ErlNifBinary bin; + int error, val; + ERL_NIF_TERM ret; + + ret = extract(&cfg, &bin, env, argv); + if (ret != atoms.ok) + return ret; + + error = git_config_get_bool(&val, cfg->config, (char *) bin.data); + enif_release_binary(&bin); + + if (error < 0) + return geef_error(env); + + ret = val ? atoms.true : atoms.false; + return enif_make_tuple2(env, atoms.ok, ret); +} + + +ERL_NIF_TERM +geef_config_set_int(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + geef_config *cfg; + ErlNifBinary bin; + int64_t val; + int error; + ERL_NIF_TERM ret; + + ret = extract(&cfg, &bin, env, argv); + if (ret != atoms.ok) + return ret; + + if (!enif_get_int64(env, argv[2], &val)) + return enif_make_badarg(env); + + error = git_config_set_int64(cfg->config, (char *) bin.data, val); + enif_release_binary(&bin); + + if (error < 0) + return geef_error(env); + + return atoms.ok; +} diff --git a/c_src/config.h b/c_src/config.h new file mode 100644 index 0000000..c91a2a9 --- /dev/null +++ b/c_src/config.h @@ -0,0 +1,17 @@ +#ifndef GEEF_CONFIG_H +#define GEEF_CONFIG_H + +#include "erl_nif.h" +#include + +void geef_config_free(ErlNifEnv *env, void *cd); +ERL_NIF_TERM geef_config_set_bool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM geef_config_get_bool(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +extern ErlNifResourceType *geef_config_type; + +typedef struct { + git_config *config; +} geef_config; + +#endif diff --git a/c_src/geef.c b/c_src/geef.c index 1663183..dbd708b 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -217,6 +217,7 @@ static ErlNifFunc geef_funcs[] = {"signature_default", 1, geef_signature_default}, {"revparse_single", 2, geef_revparse_single}, {"config_set_bool", 3, geef_config_set_bool}, + {"config_get_bool", 2, geef_config_get_bool}, }; ERL_NIF_INIT(geef_nif, geef_funcs, load, NULL, upgrade, unload) diff --git a/src/geef_config.erl b/src/geef_config.erl new file mode 100644 index 0000000..6b86e2e --- /dev/null +++ b/src/geef_config.erl @@ -0,0 +1,122 @@ +%%%------------------------------------------------------------------- +%%% @author Carlos Martín Nieto +%%% @copyright (C) 2014, Carlos Martín Nieto +%%% @doc +%%% +%%% @end +%%% Created : 18 May 2014 by Carlos Martín Nieto +%%%------------------------------------------------------------------- +-module(geef_config). + +-behaviour(gen_server). + +%% API +-export([start_link/1]). +-export([set/3]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-define(SERVER, ?MODULE). + +-record(state, {handle}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +%%-------------------------------------------------------------------- +%% @doc +%% Starts the server +%% +%% @spec start_link() -> {ok, Pid} | ignore | {error, Error} +%% @end +%%-------------------------------------------------------------------- +start_link(Handle) -> + gen_server:start_link(?MODULE, Handle, []). + +%% @doc Set a value in the configuration +set(Pid, Name, Val) when is_boolean(Val) -> + gen_server:call(Pid, {set_bool, Name, Val}). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +%% @private +init(Handle) -> + {ok, #state{handle=Handle}}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Handling call messages +%% +%% @spec handle_call(Request, From, State) -> +%% {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | +%% {stop, Reason, State} +%% @end +%%-------------------------------------------------------------------- +handle_call({set_bool, Name, Val}, _From, State = #state{handle=Handle}) -> + Reply = geef_nif:config_set_bool(Handle, Name, Val), + {reply, Reply, State}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Handling cast messages +%% +%% @spec handle_cast(Msg, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% @end +%%-------------------------------------------------------------------- +handle_cast(_Msg, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Handling all non call/cast messages +%% +%% @spec handle_info(Info, State) -> {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} +%% @end +%%-------------------------------------------------------------------- +handle_info(_Info, State) -> + {noreply, State}. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% This function is called by a gen_server when it is about to +%% terminate. It should be the opposite of Module:init/1 and do any +%% necessary cleaning up. When it returns, the gen_server terminates +%% with Reason. The return value is ignored. +%% +%% @spec terminate(Reason, State) -> void() +%% @end +%%-------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%-------------------------------------------------------------------- +%% @private +%% @doc +%% Convert process state when code is changed +%% +%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} +%% @end +%%-------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== diff --git a/src/geef_nif.erl b/src/geef_nif.erl index 89556a7..bcbc7eb 100644 --- a/src/geef_nif.erl +++ b/src/geef_nif.erl @@ -209,6 +209,10 @@ revparse_single(_Handle, _Str) -> config_set_bool(_Handle, _Name, _Val) -> ?NIF_FN. +-spec config_get_bool(term(), iolist()) -> {ok, boolean()} | {error, term()}. +config_get_bool(_Handle, _Name) -> + ?NIF_FN. + nif_error(Line) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).