summaryrefslogtreecommitdiff
path: root/examples/cat-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/cat-file.c')
-rw-r--r--examples/cat-file.c171
1 files changed, 94 insertions, 77 deletions
diff --git a/examples/cat-file.c b/examples/cat-file.c
index ebb6cb0ca..fa6add07b 100644
--- a/examples/cat-file.c
+++ b/examples/cat-file.c
@@ -1,37 +1,18 @@
-#include <stdio.h>
-#include <git2.h>
-#include <stdlib.h>
-#include <string.h>
-
-static git_repository *g_repo;
-
-static void check(int error, const char *message)
-{
- if (error) {
- fprintf(stderr, "%s (%d)\n", message, error);
- exit(1);
- }
-}
-
-static void usage(const char *message, const char *arg)
-{
- if (message && arg)
- fprintf(stderr, "%s: %s\n", message, arg);
- else if (message)
- fprintf(stderr, "%s\n", message);
- fprintf(stderr, "usage: cat-file (-t | -s | -e | -p) [<options>] <object>\n");
- exit(1);
-}
-
-static int check_str_param(
- const char *arg, const char *pattern, const char **val)
-{
- size_t len = strlen(pattern);
- if (strncmp(arg, pattern, len))
- return 0;
- *val = (const char *)(arg + len);
- return 1;
-}
+/*
+ * libgit2 "cat-file" example - shows how to print data from the ODB
+ *
+ * Written by the libgit2 contributors
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include "common.h"
static void print_signature(const char *header, const git_signature *sig)
{
@@ -57,12 +38,14 @@ static void print_signature(const char *header, const git_signature *sig)
sign, hours, minutes);
}
+/** Printing out a blob is simple, get the contents and print */
static void show_blob(const git_blob *blob)
{
/* ? Does this need crlf filtering? */
fwrite(git_blob_rawcontent(blob), git_blob_rawsize(blob), 1, stdout);
}
+/** Show each entry with its type, id and attributes */
static void show_tree(const git_tree *tree)
{
size_t i, max_i = (int)git_tree_entrycount(tree);
@@ -81,6 +64,9 @@ static void show_tree(const git_tree *tree)
}
}
+/**
+ * Commits and tags have a few interesting fields in their header.
+ */
static void show_commit(const git_commit *commit)
{
unsigned int i, max_i;
@@ -123,53 +109,34 @@ enum {
SHOW_PRETTY = 4
};
+/* Forward declarations for option-parsing helper */
+struct opts {
+ const char *dir;
+ const char *rev;
+ int action;
+ int verbose;
+};
+static void parse_opts(struct opts *o, int argc, char *argv[]);
+
+
+/** Entry point for this command */
int main(int argc, char *argv[])
{
- const char *dir = ".", *rev = NULL;
- int i, action = 0, verbose = 0;
+ git_repository *repo;
+ struct opts o = { ".", NULL, 0, 0 };
git_object *obj = NULL;
char oidstr[GIT_OID_HEXSZ + 1];
git_threads_init();
- for (i = 1; i < argc; ++i) {
- char *a = argv[i];
+ parse_opts(&o, argc, argv);
- if (a[0] != '-') {
- if (rev != NULL)
- usage("Only one rev should be provided", NULL);
- else
- rev = a;
- }
- else if (!strcmp(a, "-t"))
- action = SHOW_TYPE;
- else if (!strcmp(a, "-s"))
- action = SHOW_SIZE;
- else if (!strcmp(a, "-e"))
- action = SHOW_NONE;
- else if (!strcmp(a, "-p"))
- action = SHOW_PRETTY;
- else if (!strcmp(a, "-q"))
- verbose = 0;
- else if (!strcmp(a, "-v"))
- verbose = 1;
- else if (!strcmp(a, "--help") || !strcmp(a, "-h"))
- usage(NULL, NULL);
- else if (!check_str_param(a, "--git-dir=", &dir))
- usage("Unknown option", a);
- }
+ check_lg2(git_repository_open_ext(&repo, o.dir, 0, NULL),
+ "Could not open repository", NULL);
+ check_lg2(git_revparse_single(&obj, repo, o.rev),
+ "Could not resolve", o.rev);
- if (!action || !rev)
- usage(NULL, NULL);
-
- check(git_repository_open_ext(&g_repo, dir, 0, NULL),
- "Could not open repository");
-
- if (git_revparse_single(&obj, g_repo, rev) < 0) {
- fprintf(stderr, "Could not resolve '%s'\n", rev);
- exit(1);
- }
- if (verbose) {
+ if (o.verbose) {
char oidstr[GIT_OID_HEXSZ + 1];
git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj));
@@ -177,7 +144,7 @@ int main(int argc, char *argv[])
git_object_type2string(git_object_type(obj)), oidstr);
}
- switch (action) {
+ switch (o.action) {
case SHOW_TYPE:
printf("%s\n", git_object_type2string(git_object_type(obj)));
break;
@@ -185,9 +152,9 @@ int main(int argc, char *argv[])
git_odb *odb;
git_odb_object *odbobj;
- check(git_repository_odb(&odb, g_repo), "Could not open ODB");
- check(git_odb_read(&odbobj, odb, git_object_id(obj)),
- "Could not find obj");
+ check_lg2(git_repository_odb(&odb, repo), "Could not open ODB", NULL);
+ check_lg2(git_odb_read(&odbobj, odb, git_object_id(obj)),
+ "Could not find obj", NULL);
printf("%ld\n", (long)git_odb_object_size(odbobj));
@@ -221,9 +188,59 @@ int main(int argc, char *argv[])
}
git_object_free(obj);
- git_repository_free(g_repo);
+ git_repository_free(repo);
git_threads_shutdown();
return 0;
}
+
+/** Print out usage information */
+static void usage(const char *message, const char *arg)
+{
+ if (message && arg)
+ fprintf(stderr, "%s: %s\n", message, arg);
+ else if (message)
+ fprintf(stderr, "%s\n", message);
+ fprintf(stderr,
+ "usage: cat-file (-t | -s | -e | -p) [-v] [-q] "
+ "[-h|--help] [--git-dir=<dir>] <object>\n");
+ exit(1);
+}
+
+/** Parse the command-line options taken from git */
+static void parse_opts(struct opts *o, int argc, char *argv[])
+{
+ struct args_info args = ARGS_INFO_INIT;
+
+ for (args.pos = 1; args.pos < argc; ++args.pos) {
+ char *a = argv[args.pos];
+
+ if (a[0] != '-') {
+ if (o->rev != NULL)
+ usage("Only one rev should be provided", NULL);
+ else
+ o->rev = a;
+ }
+ else if (!strcmp(a, "-t"))
+ o->action = SHOW_TYPE;
+ else if (!strcmp(a, "-s"))
+ o->action = SHOW_SIZE;
+ else if (!strcmp(a, "-e"))
+ o->action = SHOW_NONE;
+ else if (!strcmp(a, "-p"))
+ o->action = SHOW_PRETTY;
+ else if (!strcmp(a, "-q"))
+ o->verbose = 0;
+ else if (!strcmp(a, "-v"))
+ o->verbose = 1;
+ else if (!strcmp(a, "--help") || !strcmp(a, "-h"))
+ usage(NULL, NULL);
+ else if (!match_str_arg(&o->dir, &args, "--git-dir"))
+ usage("Unknown option", a);
+ }
+
+ if (!o->action || !o->rev)
+ usage(NULL, NULL);
+
+}