Rizin
unix-like reverse engineering framework and cli tools
rz_assert.h
Go to the documentation of this file.
1 #ifndef RZ_ASSERT_H
2 #define RZ_ASSERT_H
3 
4 #include "rz_log.h"
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 
10 #define RZ_STATIC_ASSERT(x) \
11  switch (0) { \
12  case 0: \
13  case (x):; \
14  }
15 
16 RZ_API void rz_assert_log(RzLogLevel level, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3);
17 
18 #if defined(__GNUC__) && defined(__cplusplus)
19 #define RZ_FUNCTION ((const char *)(__PRETTY_FUNCTION__))
20 #elif defined(__STDC__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
21 #define RZ_FUNCTION ((const char *)(__func__))
22 #elif defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER > 1300))
23 #define RZ_FUNCTION ((const char *)(__FUNCTION__))
24 #else
25 #warning Do not know how to get function name in this setup
26 #define RZ_FUNCTION ((const char *)("???"))
27 #endif
28 
29 #define rz_warn_if_reached() \
30  do { \
31  rz_assert_log(RZ_LOGLVL_WARN, "(%s:%d):%s%s code should not be reached\n", \
32  __FILE__, __LINE__, RZ_FUNCTION, RZ_FUNCTION[0] ? ":" : ""); \
33  } while (0)
34 
35 #define rz_warn_if_fail(expr) \
36  do { \
37  if (!(expr)) { \
38  rz_assert_log(RZ_LOGLVL_WARN, "(%s:%d):%s%s runtime check failed: (%s)\n", \
39  __FILE__, __LINE__, RZ_FUNCTION, RZ_FUNCTION[0] ? ":" : "", #expr); \
40  } \
41  } while (0)
42 
43 /*
44  * RZ_CHECKS_LEVEL determines the behaviour of the rz_return_* set of functions.
45  *
46  * 0: completely disable every function and make them like no-operation
47  * 1: silently enable checks. Check expressions and do return, but do not log anything
48  * 2: enable checks and logging (DEFAULT)
49  * 3: transform them into real assertion
50  */
51 #ifndef RZ_CHECKS_LEVEL
52 #define RZ_CHECKS_LEVEL 2
53 #endif
54 
55 #if RZ_CHECKS_LEVEL == 0
56 
57 #define rz_return_if_fail(expr) \
58  do { \
59  ; \
60  } while (0)
61 #define rz_return_val_if_fail(expr, val) \
62  do { \
63  ; \
64  } while (0)
65 #define rz_return_if_reached() \
66  do { \
67  ; \
68  } while (0)
69 #define rz_return_val_if_reached(val) \
70  do { \
71  ; \
72  } while (0)
73 
74 #elif RZ_CHECKS_LEVEL == 1 || RZ_CHECKS_LEVEL == 2 // RZ_CHECKS_LEVEL
75 
76 #if RZ_CHECKS_LEVEL == 1
77 #define H_LOG_(loglevel, fmt, ...)
78 #else
79 #define H_LOG_(loglevel, fmt, ...) rz_assert_log(loglevel, fmt, __VA_ARGS__)
80 #endif
81 
100 #define rz_return_if_fail(expr) \
101  do { \
102  if (!(expr)) { \
103  H_LOG_(RZ_LOGLVL_WARN, "%s: assertion '%s' failed (line %d)\n", RZ_FUNCTION, #expr, __LINE__); \
104  return; \
105  } \
106  } while (0)
107 
108 #define rz_return_val_if_fail(expr, val) \
109  do { \
110  if (!(expr)) { \
111  H_LOG_(RZ_LOGLVL_WARN, "%s: assertion '%s' failed (line %d)\n", RZ_FUNCTION, #expr, __LINE__); \
112  return (val); \
113  } \
114  } while (0)
115 
116 #define rz_return_if_reached() \
117  do { \
118  H_LOG_(RZ_LOGLVL_ERROR, "file %s: line %d (%s): should not be reached\n", __FILE__, __LINE__, RZ_FUNCTION); \
119  return; \
120  } while (0)
121 
122 #define rz_return_val_if_reached(val) \
123  do { \
124  H_LOG_(RZ_LOGLVL_ERROR, "file %s: line %d (%s): should not be reached\n", __FILE__, __LINE__, RZ_FUNCTION); \
125  return (val); \
126  } while (0)
127 
128 #define rz_goto_if_reached(where) \
129  do { \
130  H_LOG_(RZ_LOGLVL_ERROR, "file %s: line %d (%s): should not be reached; jumping to %s\n", __FILE__, __LINE__, RZ_FUNCTION, #where); \
131  goto where; \
132  } while (0)
133 
134 #else // RZ_CHECKS_LEVEL
135 
136 #include <assert.h>
137 
138 #define rz_return_if_fail(expr) \
139  do { \
140  assert(expr); \
141  } while (0)
142 #define rz_return_val_if_fail(expr, val) \
143  do { \
144  assert(expr); \
145  } while (0)
146 #define rz_return_if_reached() \
147  do { \
148  assert(false); \
149  } while (0)
150 #define rz_return_val_if_reached(val) \
151  do { \
152  assert(false); \
153  } while (0)
154 
155 #endif // RZ_CHECKS_LEVEL
156 
157 #ifdef __cplusplus
158 }
159 #endif
160 
161 #endif
#define RZ_API
RZ_API void rz_assert_log(RzLogLevel level, const char *fmt,...) RZ_PRINTF_CHECK(2
enum rz_log_level RzLogLevel
#define RZ_PRINTF_CHECK(fmt, dots)
Definition: rz_types.h:192
static int level
Definition: vmenus.c:2424