introduce got_ref_alloc()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
diff --git a/include/got_reference.h b/include/got_reference.h
index 18c0c22..dfb265d 100644
--- a/include/got_reference.h
+++ b/include/got_reference.h
@@ -33,6 +33,13 @@ struct got_object_id;
const struct got_error * got_ref_open(struct got_reference **,
struct got_repository *, const char *);
+/*
+ * Allocate a new reference for a given object ID.
+ * The caller must dispose of it with got_ref_close().
+ */
+const struct got_error *got_ref_alloc(struct got_reference **, const char *,
+ struct got_object_id *);
+
/* Dispose of a reference. */
void got_ref_close(struct got_reference *);
diff --git a/lib/reference.c b/lib/reference.c
index c0c0768..adbeed1 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -101,27 +101,17 @@ parse_symref(struct got_reference **ref, const char *name, const char *line)
static const struct got_error *
parse_ref_line(struct got_reference **ref, const char *name, const char *line)
{
- uint8_t digest[SHA1_DIGEST_LENGTH];
- char *ref_name;
+ struct got_object_id id;
if (strncmp(line, "ref: ", 5) == 0) {
line += 5;
return parse_symref(ref, name, line);
}
- ref_name = strdup(name);
- if (ref_name == NULL)
- return got_error_from_errno();
-
- if (!got_parse_sha1_digest(digest, line))
+ if (!got_parse_sha1_digest(id.sha1, line))
return got_error(GOT_ERR_BAD_REF_DATA);
- *ref = calloc(1, sizeof(**ref));
- if (*ref == NULL)
- return got_error_from_errno();
- (*ref)->ref.ref.name = ref_name;
- memcpy(&(*ref)->ref.ref.sha1, digest, SHA1_DIGEST_LENGTH);
- return NULL;
+ return got_ref_alloc(ref, name, &id);
}
static const struct got_error *
@@ -169,37 +159,49 @@ get_refs_dir_path(struct got_repository *repo, const char *refname)
return got_repo_get_path_refs(repo);
}
+const struct got_error *
+got_ref_alloc(struct got_reference **ref, const char *name,
+ struct got_object_id *id)
+{
+ const struct got_error *err = NULL;
+
+ *ref = calloc(1, sizeof(**ref));
+ if (*ref == NULL)
+ return got_error_from_errno();
+
+ memcpy(&(*ref)->ref.ref.sha1, id->sha1, SHA1_DIGEST_LENGTH);
+ (*ref)->ref.ref.name = strdup(name);
+ if ((*ref)->ref.ref.name == NULL) {
+ err = got_error_from_errno();
+ free(*ref);
+ *ref = NULL;
+ }
+ return err;
+}
+
static const struct got_error *
parse_packed_ref_line(struct got_reference **ref, const char *abs_refname,
const char *line)
{
- uint8_t digest[SHA1_DIGEST_LENGTH];
- char *name;
+ struct got_object_id id;
+ const char *name;
*ref = NULL;
if (line[0] == '#' || line[0] == '^')
return NULL;
- if (!got_parse_sha1_digest(digest, line))
+ if (!got_parse_sha1_digest(id.sha1, line))
return got_error(GOT_ERR_BAD_REF_DATA);
if (abs_refname) {
if (strcmp(line + SHA1_DIGEST_STRING_LENGTH, abs_refname) != 0)
return NULL;
-
- name = strdup(abs_refname);
- if (name == NULL)
- return got_error_from_errno();
+ name = abs_refname;
} else
- name = strdup(line + SHA1_DIGEST_STRING_LENGTH);
+ name = line + SHA1_DIGEST_STRING_LENGTH;
- *ref = calloc(1, sizeof(**ref));
- if (*ref == NULL)
- return got_error_from_errno();
- (*ref)->ref.ref.name = name;;
- memcpy(&(*ref)->ref.ref.sha1, digest, SHA1_DIGEST_LENGTH);
- return NULL;
+ return got_ref_alloc(ref, name, &id);
}
static const struct got_error *