mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
Introduce GIT_ASSERT macros
Provide macros to replace usages of `assert`. A true `assert` is punishing as a library. Instead we should do our best to not crash. GIT_ASSERT_ARG(x) will now assert that the given argument complies to some format and sets an error message and returns `-1` if it does not. GIT_ASSERT(x) is for internal usage, and available as an internal consistency check. It will set an error message and return `-1` in the event of failure.
This commit is contained in:
@@ -107,7 +107,8 @@ typedef enum {
|
||||
GIT_ERROR_PATCH,
|
||||
GIT_ERROR_WORKTREE,
|
||||
GIT_ERROR_SHA1,
|
||||
GIT_ERROR_HTTP
|
||||
GIT_ERROR_HTTP,
|
||||
GIT_ERROR_INTERNAL
|
||||
} git_error_t;
|
||||
|
||||
/**
|
||||
|
||||
27
src/common.h
27
src/common.h
@@ -94,6 +94,33 @@
|
||||
#define FILTERIO_BUFSIZE DEFAULT_BUFSIZE
|
||||
#define NETIO_BUFSIZE DEFAULT_BUFSIZE
|
||||
|
||||
/**
|
||||
* Assert that a consumer-provided argument is valid, setting an
|
||||
* actionable error message and returning -1 if it is not.
|
||||
*
|
||||
* Note that memory leaks can occur in a release-mode assertion
|
||||
* failure -- it is impractical to provide safe clean up routines in these very
|
||||
* extreme failures, but care should be taken to not leak very large objects.
|
||||
*/
|
||||
#define GIT_ASSERT_ARG(expr) do { \
|
||||
if (!(expr)) { \
|
||||
git_error_set(GIT_ERROR_INVALID, \
|
||||
"invalid argument: '%s'", \
|
||||
#expr); \
|
||||
return -1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/** Internal consistency check to stop the function. */
|
||||
#define GIT_ASSERT(expr) do { \
|
||||
if (!(expr)) { \
|
||||
git_error_set(GIT_ERROR_INTERNAL, \
|
||||
"unrecoverable internal error: '%s'", \
|
||||
#expr); \
|
||||
return -1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Check a pointer allocation result, returning -1 if it failed.
|
||||
*/
|
||||
|
||||
39
tests/core/assert.c
Normal file
39
tests/core/assert.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "clar_libgit2.h"
|
||||
|
||||
static const char *hello_world = "hello, world";
|
||||
|
||||
static int dummy_fn(const char *myarg)
|
||||
{
|
||||
GIT_ASSERT_ARG(myarg);
|
||||
GIT_ASSERT_ARG(myarg != hello_world);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bad_math(void)
|
||||
{
|
||||
GIT_ASSERT(1 + 1 == 3);
|
||||
return 42;
|
||||
}
|
||||
|
||||
void test_core_assert__argument(void)
|
||||
{
|
||||
cl_git_fail(dummy_fn(NULL));
|
||||
cl_assert(git_error_last());
|
||||
cl_assert_equal_i(GIT_ERROR_INVALID, git_error_last()->klass);
|
||||
cl_assert_equal_s("invalid argument: 'myarg'", git_error_last()->message);
|
||||
|
||||
cl_git_fail(dummy_fn(hello_world));
|
||||
cl_assert(git_error_last());
|
||||
cl_assert_equal_i(GIT_ERROR_INVALID, git_error_last()->klass);
|
||||
cl_assert_equal_s("invalid argument: 'myarg != hello_world'", git_error_last()->message);
|
||||
|
||||
cl_git_pass(dummy_fn("foo"));
|
||||
}
|
||||
|
||||
void test_core_assert__internal(void)
|
||||
{
|
||||
cl_git_fail(bad_math());
|
||||
cl_assert(git_error_last());
|
||||
cl_assert_equal_i(GIT_ERROR_INTERNAL, git_error_last()->klass);
|
||||
cl_assert_equal_s("unrecoverable internal error: '1 + 1 == 3'", git_error_last()->message);
|
||||
}
|
||||
Reference in New Issue
Block a user