]> git.proxmox.com Git - ceph.git/blob - ceph/src/pmdk/src/core/out.h
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / core / out.h
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright 2014-2020, Intel Corporation */
3
4 /*
5 * out.h -- definitions for "out" module
6 */
7
8 #ifndef PMDK_OUT_H
9 #define PMDK_OUT_H 1
10
11 #include <stdarg.h>
12 #include <stddef.h>
13 #include <stdlib.h>
14
15 #include "util.h"
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 /*
22 * Suppress errors which are after appropriate ASSERT* macro for nondebug
23 * builds.
24 */
25 #if !defined(DEBUG) && (defined(__clang_analyzer__) || defined(__COVERITY__) ||\
26 defined(__KLOCWORK__))
27 #define OUT_FATAL_DISCARD_NORETURN __attribute__((noreturn))
28 #else
29 #define OUT_FATAL_DISCARD_NORETURN
30 #endif
31
32 #ifndef EVALUATE_DBG_EXPRESSIONS
33 #if defined(DEBUG) || defined(__clang_analyzer__) || defined(__COVERITY__) ||\
34 defined(__KLOCWORK__)
35 #define EVALUATE_DBG_EXPRESSIONS 1
36 #else
37 #define EVALUATE_DBG_EXPRESSIONS 0
38 #endif
39 #endif
40
41 #ifdef DEBUG
42
43 #define OUT_LOG out_log
44 #define OUT_NONL out_nonl
45 #define OUT_FATAL out_fatal
46 #define OUT_FATAL_ABORT out_fatal
47
48 #else
49
50 static __attribute__((always_inline)) inline void
51 out_log_discard(const char *file, int line, const char *func, int level,
52 const char *fmt, ...)
53 {
54 (void) file;
55 (void) line;
56 (void) func;
57 (void) level;
58 (void) fmt;
59 }
60
61 static __attribute__((always_inline)) inline void
62 out_nonl_discard(int level, const char *fmt, ...)
63 {
64 (void) level;
65 (void) fmt;
66 }
67
68 static __attribute__((always_inline)) OUT_FATAL_DISCARD_NORETURN inline void
69 out_fatal_discard(const char *file, int line, const char *func,
70 const char *fmt, ...)
71 {
72 (void) file;
73 (void) line;
74 (void) func;
75 (void) fmt;
76 }
77
78 static __attribute__((always_inline)) NORETURN inline void
79 out_fatal_abort(const char *file, int line, const char *func,
80 const char *fmt, ...)
81 {
82 (void) file;
83 (void) line;
84 (void) func;
85 (void) fmt;
86
87 abort();
88 }
89
90 #define OUT_LOG out_log_discard
91 #define OUT_NONL out_nonl_discard
92 #define OUT_FATAL out_fatal_discard
93 #define OUT_FATAL_ABORT out_fatal_abort
94
95 #endif
96
97 #if defined(__KLOCWORK__)
98 #define TEST_ALWAYS_TRUE_EXPR(cnd)
99 #define TEST_ALWAYS_EQ_EXPR(cnd)
100 #define TEST_ALWAYS_NE_EXPR(cnd)
101 #else
102 #define TEST_ALWAYS_TRUE_EXPR(cnd)\
103 if (__builtin_constant_p(cnd))\
104 ASSERT_COMPILE_ERROR_ON(cnd);
105 #define TEST_ALWAYS_EQ_EXPR(lhs, rhs)\
106 if (__builtin_constant_p(lhs) && __builtin_constant_p(rhs))\
107 ASSERT_COMPILE_ERROR_ON((lhs) == (rhs));
108 #define TEST_ALWAYS_NE_EXPR(lhs, rhs)\
109 if (__builtin_constant_p(lhs) && __builtin_constant_p(rhs))\
110 ASSERT_COMPILE_ERROR_ON((lhs) != (rhs));
111 #endif
112
113 /* produce debug/trace output */
114 #define LOG(level, ...) do { \
115 if (!EVALUATE_DBG_EXPRESSIONS) break;\
116 OUT_LOG(__FILE__, __LINE__, __func__, level, __VA_ARGS__);\
117 } while (0)
118
119 /* produce debug/trace output without prefix and new line */
120 #define LOG_NONL(level, ...) do { \
121 if (!EVALUATE_DBG_EXPRESSIONS) break; \
122 OUT_NONL(level, __VA_ARGS__); \
123 } while (0)
124
125 /* produce output and exit */
126 #define FATAL(...)\
127 OUT_FATAL_ABORT(__FILE__, __LINE__, __func__, __VA_ARGS__)
128
129 /* assert a condition is true at runtime */
130 #define ASSERT_rt(cnd) do { \
131 if (!EVALUATE_DBG_EXPRESSIONS || (cnd)) break; \
132 OUT_FATAL(__FILE__, __LINE__, __func__, "assertion failure: %s", #cnd);\
133 } while (0)
134
135 /* assertion with extra info printed if assertion fails at runtime */
136 #define ASSERTinfo_rt(cnd, info) do { \
137 if (!EVALUATE_DBG_EXPRESSIONS || (cnd)) break; \
138 OUT_FATAL(__FILE__, __LINE__, __func__, \
139 "assertion failure: %s (%s = %s)", #cnd, #info, info);\
140 } while (0)
141
142 /* assert two integer values are equal at runtime */
143 #define ASSERTeq_rt(lhs, rhs) do { \
144 if (!EVALUATE_DBG_EXPRESSIONS || ((lhs) == (rhs))) break; \
145 OUT_FATAL(__FILE__, __LINE__, __func__,\
146 "assertion failure: %s (0x%llx) == %s (0x%llx)", #lhs,\
147 (unsigned long long)(lhs), #rhs, (unsigned long long)(rhs)); \
148 } while (0)
149
150 /* assert two integer values are not equal at runtime */
151 #define ASSERTne_rt(lhs, rhs) do { \
152 if (!EVALUATE_DBG_EXPRESSIONS || ((lhs) != (rhs))) break; \
153 OUT_FATAL(__FILE__, __LINE__, __func__,\
154 "assertion failure: %s (0x%llx) != %s (0x%llx)", #lhs,\
155 (unsigned long long)(lhs), #rhs, (unsigned long long)(rhs)); \
156 } while (0)
157
158 /* assert a condition is true */
159 #define ASSERT(cnd)\
160 do {\
161 /*\
162 * Detect useless asserts on always true expression. Please use\
163 * COMPILE_ERROR_ON(!cnd) or ASSERT_rt(cnd) in such cases.\
164 */\
165 TEST_ALWAYS_TRUE_EXPR(cnd);\
166 ASSERT_rt(cnd);\
167 } while (0)
168
169 /* assertion with extra info printed if assertion fails */
170 #define ASSERTinfo(cnd, info)\
171 do {\
172 /* See comment in ASSERT. */\
173 TEST_ALWAYS_TRUE_EXPR(cnd);\
174 ASSERTinfo_rt(cnd, info);\
175 } while (0)
176
177 /* assert two integer values are equal */
178 #define ASSERTeq(lhs, rhs)\
179 do {\
180 /* See comment in ASSERT. */\
181 TEST_ALWAYS_EQ_EXPR(lhs, rhs);\
182 ASSERTeq_rt(lhs, rhs);\
183 } while (0)
184
185 /* assert two integer values are not equal */
186 #define ASSERTne(lhs, rhs)\
187 do {\
188 /* See comment in ASSERT. */\
189 TEST_ALWAYS_NE_EXPR(lhs, rhs);\
190 ASSERTne_rt(lhs, rhs);\
191 } while (0)
192
193 #define ERR(...)\
194 out_err(__FILE__, __LINE__, __func__, __VA_ARGS__)
195
196 void out_init(const char *log_prefix, const char *log_level_var,
197 const char *log_file_var, int major_version,
198 int minor_version);
199 void out_fini(void);
200 void out(const char *fmt, ...) FORMAT_PRINTF(1, 2);
201 void out_nonl(int level, const char *fmt, ...) FORMAT_PRINTF(2, 3);
202 void out_log(const char *file, int line, const char *func, int level,
203 const char *fmt, ...) FORMAT_PRINTF(5, 6);
204 void out_err(const char *file, int line, const char *func,
205 const char *fmt, ...) FORMAT_PRINTF(4, 5);
206 void NORETURN out_fatal(const char *file, int line, const char *func,
207 const char *fmt, ...) FORMAT_PRINTF(4, 5);
208 void out_set_print_func(void (*print_func)(const char *s));
209 void out_set_vsnprintf_func(int (*vsnprintf_func)(char *str, size_t size,
210 const char *format, va_list ap));
211
212 #ifdef _WIN32
213 #ifndef PMDK_UTF8_API
214 #define out_get_errormsg out_get_errormsgW
215 #else
216 #define out_get_errormsg out_get_errormsgU
217 #endif
218 #endif
219
220 #ifndef _WIN32
221 const char *out_get_errormsg(void);
222 #else
223 const char *out_get_errormsgU(void);
224 const wchar_t *out_get_errormsgW(void);
225 #endif
226
227 #ifdef __cplusplus
228 }
229 #endif
230
231 #endif