1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 #ifndef INCLUDE_assert_safe_h__
8 #define INCLUDE_assert_safe_h__
9 
10 /*
11  * In a debug build, we'll assert(3) for aide in debugging.  In release
12  * builds, we will provide macros that will set an error message that
13  * indicate a failure and return.  Note that memory leaks can occur in
14  * a release-mode assertion failure -- it is impractical to provide
15  * safe clean up routines in these very extreme failures, but care
16  * should be taken to not leak very large objects.
17  */
18 
19 #if (defined(_DEBUG) || defined(GIT_ASSERT_HARD)) && GIT_ASSERT_HARD != 0
20 # include <assert.h>
21 
22 # define GIT_ASSERT(expr) assert(expr)
23 # define GIT_ASSERT_ARG(expr) assert(expr)
24 
25 # define GIT_ASSERT_WITH_RETVAL(expr, fail) assert(expr)
26 # define GIT_ASSERT_ARG_WITH_RETVAL(expr, fail) assert(expr)
27 #else
28 
29 /** Internal consistency check to stop the function. */
30 # define GIT_ASSERT(expr) GIT_ASSERT_WITH_RETVAL(expr, -1)
31 
32 /**
33  * Assert that a consumer-provided argument is valid, setting an
34  * actionable error message and returning -1 if it is not.
35  */
36 # define GIT_ASSERT_ARG(expr) GIT_ASSERT_ARG_WITH_RETVAL(expr, -1)
37 
38 /** Internal consistency check to return the `fail` param on failure. */
39 # define GIT_ASSERT_WITH_RETVAL(expr, fail) \
40 	GIT_ASSERT__WITH_RETVAL(expr, GIT_ERROR_INTERNAL, "unrecoverable internal error", fail)
41 
42 /**
43  * Assert that a consumer-provided argument is valid, setting an
44  * actionable error message and returning the `fail` param if not.
45  */
46 # define GIT_ASSERT_ARG_WITH_RETVAL(expr, fail) \
47 	GIT_ASSERT__WITH_RETVAL(expr, GIT_ERROR_INVALID, "invalid argument", fail)
48 
49 # define GIT_ASSERT__WITH_RETVAL(expr, code, msg, fail) do { \
50 		if (!(expr)) { \
51 			git_error_set(code, "%s: '%s'", msg, #expr); \
52 			return fail; \
53 		} \
54 	} while(0)
55 
56 #endif /* GIT_ASSERT_HARD */
57 
58 #endif
59