Files
geef/c_src/geef.c
Carlos Martín Nieto 22ab293910 Basic reflog support
For now it simply includes reading in the reflog as a list of
entries. This does mean that the drop/append functions don't need to be
wrapped, as we can use erlang's list handling.

It however also means that we cannot write this back out, as there is
currently no way to create an empty reflog that we can fill with our own
list.
2014-02-13 17:41:11 +01:00

214 lines
6.1 KiB
C

#include "erl_nif.h"
#include "repository.h"
#include "reference.h"
#include "oid.h"
#include "object.h"
#include "commit.h"
#include "tree.h"
#include "blob.h"
#include "tag.h"
#include "library.h"
#include "revwalk.h"
#include "index.h"
#include "signature.h"
#include "revparse.h"
#include "reflog.h"
#include "geef.h"
#include <stdio.h>
#include <string.h>
#include <git2.h>
ErlNifResourceType *geef_repository_type;
ErlNifResourceType *geef_odb_type;
ErlNifResourceType *geef_ref_iter_type;
ErlNifResourceType *geef_object_type;
ErlNifResourceType *geef_revwalk_type;
ErlNifResourceType *geef_index_type;
geef_atoms atoms;
static int load(ErlNifEnv *env, void **priv, ERL_NIF_TERM load_info)
{
git_threads_init();
geef_repository_type = enif_open_resource_type(env, 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_ref_iter_type = enif_open_resource_type(env, NULL,
"ref_iter_type", geef_ref_iter_free, ERL_NIF_RT_CREATE, NULL);
if (geef_ref_iter_type == NULL)
return -1;
geef_object_type = enif_open_resource_type(env, NULL,
"object_type", geef_object_free, ERL_NIF_RT_CREATE, NULL);
geef_revwalk_type = enif_open_resource_type(env, NULL,
"revwalk_type", geef_revwalk_free, ERL_NIF_RT_CREATE, NULL);
geef_index_type = enif_open_resource_type(env, NULL,
"index_type", geef_index_free, ERL_NIF_RT_CREATE, NULL);
if (geef_repository_type == NULL)
return -1;
atoms.ok = enif_make_atom(env, "ok");
atoms.error = enif_make_atom(env, "error");
atoms.true = enif_make_atom(env, "true");
atoms.false = enif_make_atom(env, "false");
atoms.repository = enif_make_atom(env, "repository");
atoms.oid = enif_make_atom(env, "oid");
atoms.symbolic = enif_make_atom(env, "symbolic");
atoms.commit = enif_make_atom(env, "commit");
atoms.tree = enif_make_atom(env, "tree");
atoms.blob = enif_make_atom(env, "blob");
atoms.tag = enif_make_atom(env, "tag");
atoms.undefined = enif_make_atom(env, "undefined");
atoms.reflog_entry = enif_make_atom(env, "geef_reflog_entry");
/* Revwalk */
atoms.toposort = enif_make_atom(env, "sort_topo");
atoms.timesort = enif_make_atom(env, "sort_time");
atoms.reversesort = enif_make_atom(env, "sort_reverse");
atoms.iterover = enif_make_atom(env, "iterover");
/* Errors */
atoms.enomem = enif_make_atom(env, "enomem");
atoms.eunknown = enif_make_atom(env, "eunknown");
return 0;
}
int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)
{
return 0;
}
static void unload(ErlNifEnv* env, void* priv_data)
{
git_threads_shutdown();
}
ERL_NIF_TERM
geef_error(ErlNifEnv *env)
{
const git_error *error;
ErlNifBinary bin;
size_t len;
error = giterr_last();
if (!error)
return enif_make_tuple2(env, atoms.error, atoms.eunknown);
if (error->klass == GITERR_NOMEMORY)
return geef_oom(env);
if (!error->message)
return enif_make_tuple2(env, atoms.error, atoms.eunknown);
len = strlen(error->message);
if (!enif_alloc_binary(len, &bin))
return geef_oom(env);
memcpy(bin.data, error->message, len);
return enif_make_tuple2(env, atoms.error, enif_make_binary(env, &bin));
}
ERL_NIF_TERM
geef_oom(ErlNifEnv *env)
{
return enif_make_tuple2(env, atoms.error, atoms.enomem);
}
int geef_terminate_binary(ErlNifBinary *bin)
{
if (!enif_realloc_binary(bin, bin->size + 1))
return 0;
bin->data[bin->size - 1] = '\0';
return 1;
}
int geef_string_to_bin(ErlNifBinary *bin, const char *str)
{
size_t len;
if (str == NULL)
len = 0;
else
len = strlen(str);
if (!enif_alloc_binary(len, bin))
return -1;
memcpy(bin->data, str, len);
return 0;
}
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},
{"repository_get_odb", 1, geef_repository_odb},
{"odb_object_exists", 2, geef_odb_exists},
{"odb_write", 3, geef_odb_write},
{"reference_list", 1, geef_reference_list},
{"reference_to_id", 2, geef_reference_to_id},
{"reference_glob", 2, geef_reference_glob},
{"reference_lookup", 2, geef_reference_lookup},
{"reference_iterator", 2, geef_reference_iterator},
{"reference_next", 1, geef_reference_next},
{"reference_resolve", 2, geef_reference_resolve},
{"reference_create", 5, geef_reference_create},
{"reference_dwim", 2, geef_reference_dwim},
{"reference_has_log", 2, geef_reference_has_log},
{"reflog_read", 2, geef_reflog_read},
{"oid_fmt", 1, geef_oid_fmt},
{"oid_parse", 1, geef_oid_parse},
{"object_lookup", 2, geef_object_lookup},
{"object_id", 1, geef_object_id},
{"commit_tree", 1, geef_commit_tree},
{"commit_tree_id", 1, geef_commit_tree_id},
{"commit_create", 8, geef_commit_create},
{"tree_bypath", 2, geef_tree_bypath},
{"tree_nth", 2, geef_tree_nth},
{"tree_count", 1, geef_tree_count},
{"blob_size", 1, geef_blob_size},
{"blob_content", 1, geef_blob_content},
{"tag_peel", 1, geef_tag_peel},
{"library_version", 0, geef_library_version},
{"revwalk_new", 1, geef_revwalk_new},
{"revwalk_push", 3, geef_revwalk_push},
{"revwalk_next", 1, geef_revwalk_next},
{"revwalk_sorting", 2, geef_revwalk_sorting},
{"revwalk_reset", 1, geef_revwalk_reset},
{"index_new", 0, geef_index_new},
{"index_write", 1, geef_index_write},
{"index_write_tree", 1, geef_index_write_tree},
{"index_write_tree", 2, geef_index_write_tree},
{"index_add", 2, geef_index_add},
{"index_count", 1, geef_index_count},
{"index_get", 3, geef_index_get},
{"index_nth", 2, geef_index_nth},
{"index_clear", 1, geef_index_clear},
{"index_read_tree", 2, geef_index_read_tree},
{"signature_default", 1, geef_signature_default},
{"revparse_single", 2, geef_revparse_single},
};
ERL_NIF_INIT(geef_nif, geef_funcs, load, NULL, upgrade, unload)