My pretty neat website
git clone git://soophie.de/soso
blob: 58a3acb504a913a0975813b8864f6b85b43690f5 (3643 bytes)[raw]
1
#include "git_repo.h"2
#include "git_repo_blob.h"4
#include "../templ/duc_git_repo_blob.h"6
static orb_rc_t init(orb_module_t *self) {7
duc_git_repo_blob_t *data = self->data;8
git_repo_blob_param_list_t *param_list = self->param_list;9
if (param_list) {10
data->repo = param_list->repo;11
data->is_markdown = param_list->is_markdown;12
data->is_raw = param_list->is_raw;13
}14
return ORB_OK;15
}17
static int _fetch_tree_cb(const char *root, const git_tree_entry *entry_handle, void *data) {18
git_repo_blob_tree_cb_t *handle = data;19
const char *name = git_tree_entry_name(entry_handle);20
git_filemode_t mode_handle = git_tree_entry_filemode(entry_handle);21
if (mode_handle != GIT_FILEMODE_TREE) {22
const git_oid *oid = git_tree_entry_id(entry_handle);23
size_t file_path_len = strlen(root) + strlen(name);24
char file_path[file_path_len + 1];25
snprintf(file_path, sizeof(file_path), "%s%s", root, name);26
if (strcmp(handle->file_path, file_path) == 0) {27
git_oid_cpy(handle->blob_oid, oid);28
return -1;29
}30
}31
return 0;32
}34
static orb_rc_t fetch(orb_module_t *self) {35
duc_git_repo_blob_t *data = self->data;36
if (!data->repo) return ORB_FATAL(1);37
git_oid blob_oid;38
if (data->repo->flag_oid) {39
if (git_oid_fromstr(&blob_oid, data->repo->flag_oid) != 0) return ORB_FATAL(2);40
}41
if (data->repo->flag_path) {42
char *ref_oid = NULL;43
if (data->repo->ref_head) ref_oid = data->repo->ref_head->oid;44
if (data->repo->ref) ref_oid = data->repo->ref->oid;45
if (!ref_oid) return ORB_ERR(2);46
const char *spec_suffix = "^{commit}";47
size_t spec_len = strlen(ref_oid) + strlen(spec_suffix) + 1;48
char spec[spec_len];49
snprintf(spec, spec_len, "%s%s", ref_oid, spec_suffix);50
git_object *obj = NULL;51
if (git_revparse_single(&obj, data->repo->handle, spec) == 0) {52
git_commit *commit_handle = (git_commit *) obj;53
git_tree *tree_handle = NULL;54
if (git_commit_tree(&tree_handle, commit_handle) == 0) {55
git_tree_walk(tree_handle, GIT_TREEWALK_PRE, _fetch_tree_cb, &((git_repo_blob_tree_cb_t) {56
.blob_oid = &blob_oid,57
.file_path = data->repo->flag_path,58
}));59
git_tree_free(tree_handle);60
}61
git_object_free(obj);62
}63
if (git_oid_is_zero(&blob_oid)) return ORB_FATAL(3);64
}65
git_blob *blob_handle = NULL;66
if (git_blob_lookup(&blob_handle, data->repo->handle, &blob_oid) != 0) return ORB_FATAL(4);67
data->blob = calloc(1, sizeof(git_repo_blob_t));68
git_repo_blob_t *blob = data->blob;69
char oid_str[GIT_OID_HEXSZ + 1];70
git_oid_tostr(oid_str, sizeof(oid_str), &blob_oid);71
blob->oid = strdup(oid_str);72
blob->name = NULL;73
size_t size = (size_t) git_blob_rawsize(blob_handle);74
const char *content = git_blob_rawcontent(blob_handle);75
if (content) {76
blob->content = malloc(size + 1);77
memcpy(blob->content, content, size);78
blob->content[size] = '\0';79
blob->size = size;80
}81
blob->is_binary = git_blob_is_binary(blob_handle);82
git_blob_free(blob_handle);83
return ORB_OK;84
}86
static orb_rc_t render(orb_module_t *self, void *out) {87
return ORB_ERR(duc_git_repo_blob_render(out, (duc_git_repo_blob_t *) self->data));88
}90
static void cleanup(orb_module_t *self) {91
duc_git_repo_blob_t *data = self->data;92
if (data->blob) {93
free(data->blob->oid);94
if (data->blob->name) free(data->blob->name);95
if (data->blob->content) free(data->blob->content);96
free(data->blob);97
data->blob = NULL;98
}99
}101
const orb_module_type_t GIT_REPO_BLOB_TYPE = {102
.size = sizeof(duc_git_repo_blob_t),103
.init = init,104
.fetch = fetch,105
.render = render,106
.cleanup = cleanup,107
};