269107ff2de5afc2b68384668bdfee5e4e653b1f
[babeltrace.git] / src / lib / assert-cond-base.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (c) 2018 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2018-2020 Philippe Proulx <pproulx@efficios.com>
6 */
7
8 #ifndef BABELTRACE_ASSERT_COND_BASE_INTERNAL_H
9 #define BABELTRACE_ASSERT_COND_BASE_INTERNAL_H
10
11 /*
12 * The macros in this header use macros defined in "lib/logging.h". We
13 * don't want this header to automatically include "lib/logging.h"
14 * because you need to manually define BT_LOG_TAG before including
15 * "lib/logging.h" and it is unexpected that you also need to define it
16 * before including this header.
17 *
18 * This is a reminder that in order to use "lib/assert-cond.h", you also
19 * need to use logging explicitly.
20 */
21
22 #ifndef BT_LIB_LOG_SUPPORTED
23 # error Include "lib/logging.h" before this header.
24 #endif
25
26 #include <stdbool.h>
27 #include <stdlib.h>
28 #include <inttypes.h>
29 #include "common/common.h"
30 #include "common/macros.h"
31
32 /*
33 * Prints the details of an unsatisfied precondition or postcondition
34 * without immediately aborting. You should use this within a function
35 * which checks preconditions or postconditions, but which is called
36 * from a BT_ASSERT_PRE() or BT_ASSERT_POST() context, so that the
37 * function can still return its result for
38 * BT_ASSERT_PRE()/BT_ASSERT_POST() to evaluate it.
39 *
40 * Example:
41 *
42 * static inline bool check_complex_precond(...)
43 * {
44 * ...
45 *
46 * if (...) {
47 * BT_ASSERT_COND_MSG("Invalid object: ...", ...);
48 * return false;
49 * }
50 *
51 * ...
52 * }
53 *
54 * ...
55 *
56 * BT_ASSERT_PRE(check_complex_precond(...),
57 * "Precondition is not satisfied: ...", ...);
58 */
59 #define BT_ASSERT_COND_MSG(_fmt, ...) \
60 do { \
61 bt_lib_log(_BT_LOG_SRCLOC_FUNCTION, __FILE__, \
62 __LINE__, BT_LOG_FATAL, BT_LOG_TAG, \
63 (_fmt), ##__VA_ARGS__); \
64 } while (0)
65
66 /*
67 * Internal to this file: asserts that the library condition `_cond` of
68 * type `_cond_type` (`pre` or `post`) is satisfied.
69 *
70 * If `_cond` is false, this macro logs a fatal message using `_fmt` and
71 * the optional arguments (same usage as BT_LIB_LOGF()), and abort.
72 *
73 * To assert that an internal precondition or postcondition is
74 * satisfied, use BT_ASSERT() or BT_ASSERT_DBG().
75 */
76 #define _BT_ASSERT_COND(_cond_type, _cond, _fmt, ...) \
77 do { \
78 if (!(_cond)) { \
79 BT_ASSERT_COND_MSG("Babeltrace 2 library " _cond_type "condition not satisfied. Error is:"); \
80 BT_ASSERT_COND_MSG(_fmt, ##__VA_ARGS__); \
81 BT_ASSERT_COND_MSG("Aborting..."); \
82 bt_common_abort(); \
83 } \
84 } while (0)
85
86 /*
87 * Asserts that the library precondition `_cond` is satisfied.
88 *
89 * If `_cond` is false, log a fatal message using `_fmt` and the
90 * optional arguments (same usage as BT_LIB_LOGF()), and abort.
91 *
92 * To assert that a library postcondition is satisfied (return from user
93 * code), use BT_ASSERT_POST().
94 *
95 * To assert that an internal precondition or postcondition is
96 * satisfied, use BT_ASSERT() or BT_ASSERT_DBG().
97 */
98 #define BT_ASSERT_PRE(_cond, _fmt, ...) \
99 _BT_ASSERT_COND("pre", _cond, _fmt, ##__VA_ARGS__)
100
101 /*
102 * Asserts that the library postcondition `_cond` is satisfied.
103 *
104 * If `_cond` is false, log a fatal message using `_fmt` and the
105 * optional arguments (same usage as BT_LIB_LOGF()), and abort.
106 *
107 * To assert that a library precondition is satisfied (return from user
108 * code), use BT_ASSERT_PRE().
109 *
110 * To assert that an internal precondition or postcondition is
111 * satisfied, use BT_ASSERT() or BT_ASSERT_DBG().
112 */
113 #define BT_ASSERT_POST(_cond, _fmt, ...) \
114 _BT_ASSERT_COND("post", _cond, _fmt, ##__VA_ARGS__)
115
116 #ifdef BT_DEV_MODE
117 /* Developer mode version of BT_ASSERT_PRE(). */
118 # define BT_ASSERT_PRE_DEV(_cond, _fmt, ...) \
119 BT_ASSERT_PRE((_cond), _fmt, ##__VA_ARGS__)
120
121 /* Developer mode version of BT_ASSERT_POST(). */
122 # define BT_ASSERT_POST_DEV(_cond, _fmt, ...) \
123 BT_ASSERT_POST((_cond), _fmt, ##__VA_ARGS__)
124
125 /* Developer mode version of BT_ASSERT_COND_MSG(). */
126 # define BT_ASSERT_COND_DEV_MSG(_fmt, ...) \
127 BT_ASSERT_COND_MSG(_fmt, ##__VA_ARGS__)
128
129 /*
130 * Marks a function as being only used within a BT_ASSERT_PRE_DEV() or
131 * BT_ASSERT_POST_DEV() context.
132 */
133 # define BT_ASSERT_COND_DEV_FUNC
134 #else
135 # define BT_ASSERT_COND_DEV_MSG(_fmt, ...)
136
137 # define BT_ASSERT_PRE_DEV(_cond, _fmt, ...) ((void) sizeof((void) (_cond), 0))
138
139 # define BT_ASSERT_POST_DEV(_cond, _fmt, ...) ((void) sizeof((void) (_cond), 0))
140
141 # define BT_ASSERT_COND_DEV_FUNC __attribute__((unused))
142 #endif /* BT_DEV_MODE */
143
144 /*
145 * Mark anything that includes this file as supporting precondition and
146 * postcondition assertion macros.
147 */
148 #define BT_ASSERT_COND_SUPPORTED
149
150 #endif /* BABELTRACE_ASSERT_COND_BASE_INTERNAL_H */
This page took 0.031856 seconds and 3 git commands to generate.