summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/errors.h15
-rw-r--r--src/errors.c64
-rw-r--r--src/win32/posix_w32.c8
-rw-r--r--tests-clar/object/tree/frompath.c2
4 files changed, 86 insertions, 3 deletions
diff --git a/include/git2/errors.h b/include/git2/errors.h
index f617986e1..54da869b4 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -113,8 +113,23 @@ typedef enum {
/** The buffer is too short to satisfy the request */
GIT_ESHORTBUFFER = -32,
+} git_error_t;
+
+typedef struct {
+ char *message;
+ int klass;
} git_error;
+typedef enum {
+ GITERR_NOMEMORY,
+
+} git_error_class;
+
+GIT_EXTERN(void) giterr_set(git_error **error_out, int error_class, const char *string, ...);
+GIT_EXTERN(void) giterr_set_oom(git_error **error);
+GIT_EXTERN(void) giterr_free(git_error *error);
+GIT_EXTERN(void) giterr_clear(git_error **error);
+
/**
* Return a detailed error string with the latest error
* that occurred in the library.
diff --git a/src/errors.c b/src/errors.c
index 58e0976f2..0105c2538 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -6,6 +6,7 @@
*/
#include "common.h"
#include "global.h"
+#include "posix.h"
#include <stdarg.h>
static struct {
@@ -102,3 +103,66 @@ void git_clearerror(void)
char *last_error = GIT_GLOBAL->error.last;
last_error[0] = '\0';
}
+
+/********************************************
+ * New error handling
+ ********************************************/
+
+void giterr_set(git_error **error_out, int error_class, const char *string, ...)
+{
+ char error_str[1024];
+ va_list arglist;
+ git_error *error;
+
+ if (error_out == NULL)
+ return;
+
+ error = git__malloc(sizeof(git_error));
+ if (!error) {
+ giterr_set_oom(error_out);
+ return;
+ }
+
+ va_start(arglist, string);
+ p_vsnprintf(error_str, sizeof(error_str), string, arglist);
+ va_end(arglist);
+
+ error->message = git__strdup(error_str);
+ error->klass = error_class;
+
+ if (error->message == NULL) {
+ free(error);
+ giterr_set_oom(error_out);
+ return;
+ }
+
+ *error_out = error;
+}
+
+static git_error g_git_oom_error = {
+ "Out of memory",
+ GITERR_NOMEMORY
+};
+
+void giterr_set_oom(git_error **error)
+{
+ if (error != NULL)
+ *error = &g_git_oom_error;
+}
+
+void giterr_free(git_error *error)
+{
+ if (error == NULL || error == &g_git_oom_error)
+ return;
+
+ free(error->message);
+ free(error);
+}
+
+void giterr_clear(git_error **error)
+{
+ if (error != NULL) {
+ giterr_free(*error);
+ *error = NULL;
+ }
+}
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 91585aeae..8e70719f9 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -341,8 +341,12 @@ done:
int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
{
#ifdef _MSC_VER
- int len = _vsnprintf(buffer, count, format, argptr);
- return (len < 0) ? _vscprintf(format, argptr) : len;
+ int len;
+
+ if (count == 0 || (len = _vsnprintf(buffer, count, format, argptr)) < 0)
+ return p_vscprintf(format, argptr);
+
+ return len;
#else /* MinGW */
return vsnprintf(buffer, count, format, argptr);
#endif
diff --git a/tests-clar/object/tree/frompath.c b/tests-clar/object/tree/frompath.c
index 3857d42a8..523a0b99e 100644
--- a/tests-clar/object/tree/frompath.c
+++ b/tests-clar/object/tree/frompath.c
@@ -24,7 +24,7 @@ void test_object_tree_frompath__cleanup(void)
cl_fixture_cleanup("testrepo.git");
}
-static void assert_tree_from_path(git_tree *root, const char *path, git_error expected_result, const char *expected_raw_oid)
+static void assert_tree_from_path(git_tree *root, const char *path, int expected_result, const char *expected_raw_oid)
{
git_tree *containing_tree = NULL;