cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / lib / assert-cond-base.h
CommitLineData
2bdc32f7
PP
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>
2bdc32f7
PP
27#include "common/macros.h"
28
29/*
30 * Prints the details of an unsatisfied precondition or postcondition
31 * without immediately aborting. You should use this within a function
32 * which checks preconditions or postconditions, but which is called
33 * from a BT_ASSERT_PRE() or BT_ASSERT_POST() context, so that the
34 * function can still return its result for
35 * BT_ASSERT_PRE()/BT_ASSERT_POST() to evaluate it.
36 *
37 * Example:
38 *
39 * static inline bool check_complex_precond(...)
40 * {
41 * ...
42 *
43 * if (...) {
44 * BT_ASSERT_COND_MSG("Invalid object: ...", ...);
45 * return false;
46 * }
47 *
48 * ...
49 * }
50 *
51 * ...
52 *
53 * BT_ASSERT_PRE(check_complex_precond(...),
54 * "Precondition is not satisfied: ...", ...);
55 */
56#define BT_ASSERT_COND_MSG(_fmt, ...) \
57 do { \
71436ae4 58 bt_lib_log(__FILE__, __func__, \
2bdc32f7
PP
59 __LINE__, BT_LOG_FATAL, BT_LOG_TAG, \
60 (_fmt), ##__VA_ARGS__); \
61 } while (0)
62
1778c2a4
PP
63/*
64 * This function:
65 *
66 * 1. Generates a condition ID based on `cond_type`, `func`, and
67 * `id_suffix`.
68 *
69 * 2. Logs (FATAL level) the generated condition ID and function name
70 * (`func`).
71 *
72 * 3. Logs (FATAL level) a message using `fmt` and the optional
73 * arguments (same usage as BT_LIB_LOGF()).
74 *
75 * 4. Aborts.
76 */
1778c2a4
PP
77__attribute__((noreturn))
78void bt_lib_assert_cond_failed(const char *cond_type, const char *func,
79 const char *id_suffix, const char *fmt, ...);
80
2bdc32f7
PP
81/*
82 * Internal to this file: asserts that the library condition `_cond` of
1778c2a4
PP
83 * type `_cond_type` (`pre` or `post`), related to function `_func`,
84 * and having the ID suffix `_id_suffix` is satisfied.
2bdc32f7 85 *
1778c2a4
PP
86 * If `_cond` is false, then this macro calls
87 * bt_lib_assert_cond_failed().
2bdc32f7 88 *
1778c2a4 89 * To assert that an _internal_ precondition or postcondition is
2bdc32f7
PP
90 * satisfied, use BT_ASSERT() or BT_ASSERT_DBG().
91 */
1778c2a4 92#define _BT_ASSERT_COND(_cond_type, _func, _id_suffix, _cond, _fmt, ...) \
2bdc32f7
PP
93 do { \
94 if (!(_cond)) { \
1778c2a4
PP
95 bt_lib_assert_cond_failed(_cond_type, _func, \
96 _id_suffix, _fmt, ##__VA_ARGS__); \
2bdc32f7
PP
97 } \
98 } while (0)
99
100/*
101 * Asserts that the library precondition `_cond` is satisfied.
102 *
1778c2a4
PP
103 * See _BT_ASSERT_COND() for details about the `_func` and `_id_suffix`
104 * parameters.
2bdc32f7 105 */
1778c2a4
PP
106#define BT_ASSERT_PRE_FROM_FUNC(_func, _id_suffix, _cond, _fmt, ...) \
107 _BT_ASSERT_COND("pre", _func, _id_suffix, (_cond), _fmt, ##__VA_ARGS__)
108
109/*
110 * Like BT_ASSERT_PRE_FROM_FUNC(), but uses `__func__` (current function
111 * name) as the `_func` parameter.
112 */
113#define BT_ASSERT_PRE(_id_suffix, _cond, _fmt, ...) \
114 BT_ASSERT_PRE_FROM_FUNC(__func__, _id_suffix, (_cond), _fmt, ##__VA_ARGS__)
2bdc32f7
PP
115
116/*
117 * Asserts that the library postcondition `_cond` is satisfied.
118 *
1778c2a4
PP
119 * See _BT_ASSERT_COND() for details about the `_func` and `_id_suffix`
120 * parameters.
2bdc32f7 121 */
1778c2a4
PP
122#define BT_ASSERT_POST(_func, _id_suffix, _cond, _fmt, ...) \
123 _BT_ASSERT_COND("post", _func, _id_suffix, (_cond), _fmt, ##__VA_ARGS__);
2bdc32f7
PP
124
125#ifdef BT_DEV_MODE
1778c2a4
PP
126/* Developer mode version of BT_ASSERT_PRE_FROM_FUNC(). */
127# define BT_ASSERT_PRE_DEV_FROM_FUNC(_func, _id_suffix, _cond, _fmt, ...) \
128 BT_ASSERT_PRE_FROM_FUNC(_func, _id_suffix, (_cond), _fmt, ##__VA_ARGS__)
129
2bdc32f7 130/* Developer mode version of BT_ASSERT_PRE(). */
1778c2a4
PP
131# define BT_ASSERT_PRE_DEV(_id_suffix, _cond, _fmt, ...) \
132 BT_ASSERT_PRE(_id_suffix, (_cond), _fmt, ##__VA_ARGS__)
2bdc32f7
PP
133
134/* Developer mode version of BT_ASSERT_POST(). */
1778c2a4
PP
135# define BT_ASSERT_POST_DEV(_func, _id_suffix, _cond, _fmt, ...) \
136 BT_ASSERT_POST(_func, _id_suffix, (_cond), _fmt, ##__VA_ARGS__)
2bdc32f7
PP
137
138/* Developer mode version of BT_ASSERT_COND_MSG(). */
139# define BT_ASSERT_COND_DEV_MSG(_fmt, ...) \
140 BT_ASSERT_COND_MSG(_fmt, ##__VA_ARGS__)
141
142/*
143 * Marks a function as being only used within a BT_ASSERT_PRE_DEV() or
144 * BT_ASSERT_POST_DEV() context.
145 */
146# define BT_ASSERT_COND_DEV_FUNC
147#else
148# define BT_ASSERT_COND_DEV_MSG(_fmt, ...)
149
1778c2a4
PP
150# define BT_ASSERT_PRE_DEV_FROM_FUNC(_func, _id_suffix, _cond, _fmt, ...) \
151 BT_USE_EXPR4(_func, _id_suffix, _cond, _fmt)
152
153# define BT_ASSERT_PRE_DEV(_id_suffix, _cond, _fmt, ...) \
154 BT_USE_EXPR3(_id_suffix, _cond, _fmt)
2bdc32f7 155
1778c2a4
PP
156# define BT_ASSERT_POST_DEV(_func, _id_suffix, _cond, _fmt, ...) \
157 BT_USE_EXPR4(_func, _id_suffix, _cond, _fmt)
2bdc32f7
PP
158
159# define BT_ASSERT_COND_DEV_FUNC __attribute__((unused))
160#endif /* BT_DEV_MODE */
161
162/*
163 * Mark anything that includes this file as supporting precondition and
164 * postcondition assertion macros.
165 */
166#define BT_ASSERT_COND_SUPPORTED
167
168#endif /* BABELTRACE_ASSERT_COND_BASE_INTERNAL_H */
This page took 0.052247 seconds and 4 git commands to generate.