introduce got errors with custom messages; add one for ERR_NO_OBJ
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
diff --git a/include/got_error.h b/include/got_error.h
index 1a82e73..5e8cb64 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -123,6 +123,14 @@ static const struct got_error {
const struct got_error *got_error(int);
/*
+ * Get an error object from the above list, for a given error code.
+ * Use the specified error message instead of the default one.
+ * Caution: If the message buffer lives in dynamically allocated memory,
+ * then this memory likely won't be freed.
+ */
+const struct got_error *got_error_msg(int, const char *);
+
+/*
* Get a statically allocated error object with code GOT_ERR_ERRNO
* and an error message obtained from strerror(3).
*/
@@ -141,3 +149,12 @@ const struct got_error *got_error_set_errno(int);
* with the error code provided in the second argument.
*/
const struct got_error *got_ferror(FILE *, int);
+
+/*
+ * Obtain an error with code GOT_ERR_NO_OBJ and an error message which
+ * contains the specified object ID. The message buffer is statically
+ * allocated; future invocations of this function will overwrite the
+ * message set during earlier invocations.
+ */
+struct got_object_id; /* forward declaration */
+const struct got_error *got_error_no_obj(struct got_object_id *);
diff --git a/lib/commit_graph.c b/lib/commit_graph.c
index f663cec..e91da57 100644
--- a/lib/commit_graph.c
+++ b/lib/commit_graph.c
@@ -639,7 +639,7 @@ got_commit_graph_iter_start(struct got_commit_graph *graph,
start_node = got_object_idset_get(graph->node_ids, id);
if (start_node == NULL)
- return got_error(GOT_ERR_NO_OBJ);
+ return got_error_no_obj(id);
err = got_object_open_as_commit(&commit, repo, &start_node->id);
if (err)
diff --git a/lib/error.c b/lib/error.c
index b12d036..7063a0b 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -14,12 +14,22 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/queue.h>
+
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sha1.h>
+#include <zlib.h>
#include "got_error.h"
+#include "got_object.h"
+
+#include "got_lib_delta.h"
+#include "got_lib_inflate.h"
+#include "got_lib_object.h"
+#include "got_lib_sha1.h"
#ifndef nitems
#define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
@@ -39,6 +49,23 @@ got_error(int code)
}
const struct got_error *
+got_error_msg(int code, const char *msg)
+{
+ static struct got_error err;
+ int i;
+
+ for (i = 0; i < nitems(got_errors); i++) {
+ if (code == got_errors[i].code) {
+ err.code = code;
+ err.msg = msg;
+ return (const struct got_error *)&err;
+ }
+ }
+
+ abort();
+}
+
+const struct got_error *
got_error_from_errno()
{
static struct got_error err;
@@ -62,3 +89,21 @@ got_ferror(FILE *f, int code)
return got_error_from_errno();
return got_error(code);
}
+
+const struct got_error *
+got_error_no_obj(struct got_object_id *id)
+{
+ static char msg[sizeof("object not found") +
+ SHA1_DIGEST_STRING_LENGTH];
+ char id_str[SHA1_DIGEST_STRING_LENGTH];
+ int ret;
+
+ if (!got_sha1_digest_to_str(id->sha1, id_str, sizeof(id_str)))
+ return got_error(GOT_ERR_NO_OBJ);
+
+ ret = snprintf(msg, sizeof(msg), "object %s not found", id_str);
+ if (ret == -1 || ret >= sizeof(msg))
+ return got_error(GOT_ERR_NO_OBJ);
+
+ return got_error_msg(GOT_ERR_NO_OBJ, msg);
+}
diff --git a/lib/object.c b/lib/object.c
index abcc58c..97f5a2e 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -232,7 +232,7 @@ got_object_open(struct got_object **obj, struct got_repository *repo,
fd = open(path, O_RDONLY | O_NOFOLLOW, GOT_DEFAULT_FILE_MODE);
if (fd == -1) {
if (errno == ENOENT)
- err = got_error(GOT_ERR_NO_OBJ);
+ err = got_error_no_obj(id);
else
err = got_error_from_errno();
goto done;
diff --git a/lib/repository.c b/lib/repository.c
index 42722b7..3becb1c 100644
--- a/lib/repository.c
+++ b/lib/repository.c
@@ -673,7 +673,7 @@ got_repo_search_packidx(struct got_packidx **packidx, int *idx,
goto done;
}
- err = got_error(GOT_ERR_NO_OBJ);
+ err = got_error_no_obj(id);
done:
free(path_packdir);
if (packdir && closedir(packdir) != 0 && err == 0)
diff --git a/regress/delta/Makefile b/regress/delta/Makefile
index f616387..6ac1f2f 100644
--- a/regress/delta/Makefile
+++ b/regress/delta/Makefile
@@ -1,7 +1,7 @@
.PATH:${.CURDIR}/../../lib
PROG = delta_test
-SRCS = delta.c error.c opentemp.c path.c inflate.c delta_test.c
+SRCS = delta.c error.c opentemp.c path.c inflate.c sha1.c delta_test.c
CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
LDADD = -lz