/** * Lookup an object in a repository * * @param repo S4 class git_repository * @param hex 4 to 40 char hexadecimal string * @return S4 object with lookup */ SEXP git2r_object_lookup(SEXP repo, SEXP hex) { int err; size_t len; SEXP result = R_NilValue; git_object *object = NULL; git_oid oid; git_repository *repository = NULL; if (git2r_error_check_hex_arg(hex)) error("Invalid arguments to git2r_object_lookup"); repository = git2r_repository_open(repo); if (!repository) error(git2r_err_invalid_repository); len = LENGTH(STRING_ELT(hex, 0)); if (GIT_OID_HEXSZ == len) { git_oid_fromstr(&oid, CHAR(STRING_ELT(hex, 0))); err = git_object_lookup(&object, repository, &oid, GIT_OBJ_ANY); if (err < 0) goto cleanup; } else { git_oid_fromstrn(&oid, CHAR(STRING_ELT(hex, 0)), len); err = git_object_lookup_prefix(&object, repository, &oid, len, GIT_OBJ_ANY); if (err < 0) goto cleanup; } switch (git_object_type(object)) { case GIT_OBJ_COMMIT: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_commit"))); git2r_commit_init((git_commit*)object, repo, result); break; case GIT_OBJ_TREE: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tree"))); git2r_tree_init((git_tree*)object, repo, result); break; case GIT_OBJ_BLOB: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_blob"))); git2r_blob_init((git_blob*)object, repo, result); break; case GIT_OBJ_TAG: PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_tag"))); git2r_tag_init((git_tag*)object, repo, result); break; default: error("Unimplemented"); } cleanup: if (object) git_object_free(object); if (repository) git_repository_free(repository); if (R_NilValue != result) UNPROTECT(1); if (err < 0) error("Error: %s\n", giterr_last()->message); return result; }
/** * Invoked 'callback' for each tag * * @param name The name of the tag * @param oid The id of the tag * @param payload Payload data passed to 'git_tag_foreach' * @return 0 on success, else error code */ static int git2r_tag_foreach_cb(const char *name, git_oid *oid, void *payload) { int err = 0; git_object *object = NULL; git2r_tag_foreach_cb_data *cb_data = (git2r_tag_foreach_cb_data*)payload; /* Check if we have a list to populate */ if (R_NilValue != cb_data->tags) { int skip = 0; SEXP item; err = git_object_lookup(&object, cb_data->repository, oid, GIT_OBJ_ANY); if (err) goto cleanup; switch (git_object_type(object)) { case GIT_OBJ_COMMIT: SET_VECTOR_ELT( cb_data->tags, cb_data->n, item = NEW_OBJECT(MAKE_CLASS("git_commit"))); git2r_commit_init((git_commit*)object, cb_data->repo, item); break; case GIT_OBJ_TREE: SET_VECTOR_ELT( cb_data->tags, cb_data->n, item = NEW_OBJECT(MAKE_CLASS("git_tree"))); git2r_tree_init((git_tree*)object, cb_data->repo, item); break; case GIT_OBJ_BLOB: SET_VECTOR_ELT( cb_data->tags, cb_data->n, item = NEW_OBJECT(MAKE_CLASS("git_blob"))); git2r_blob_init((git_blob*)object, cb_data->repo, item); break; case GIT_OBJ_TAG: SET_VECTOR_ELT( cb_data->tags, cb_data->n, item = NEW_OBJECT(MAKE_CLASS("git_tag"))); git2r_tag_init((git_tag*)object, cb_data->repo, item); break; default: git2r_error(__func__, NULL, git2r_err_object_type, NULL); } if (git__prefixcmp(name, "refs/tags/") == 0) skip = strlen("refs/tags/"); SET_STRING_ELT( getAttrib(cb_data->tags, R_NamesSymbol), cb_data->n, mkChar(name + skip)); if (object) git_object_free(object); object = NULL; } cb_data->n += 1; cleanup: if (object) git_object_free(object); return err; }