1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright 2014-2020, Intel Corporation */
5 * out.h -- definitions for "out" module
22 * Suppress errors which are after appropriate ASSERT* macro for nondebug
25 #if !defined(DEBUG) && (defined(__clang_analyzer__) || defined(__COVERITY__) ||\
26 defined(__KLOCWORK__))
27 #define OUT_FATAL_DISCARD_NORETURN __attribute__((noreturn))
29 #define OUT_FATAL_DISCARD_NORETURN
32 #ifndef EVALUATE_DBG_EXPRESSIONS
33 #if defined(DEBUG) || defined(__clang_analyzer__) || defined(__COVERITY__) ||\
35 #define EVALUATE_DBG_EXPRESSIONS 1
37 #define EVALUATE_DBG_EXPRESSIONS 0
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
50 static __attribute__((always_inline
)) inline void
51 out_log_discard(const char *file
, int line
, const char *func
, int level
,
61 static __attribute__((always_inline
)) inline void
62 out_nonl_discard(int level
, const char *fmt
, ...)
68 static __attribute__((always_inline
)) OUT_FATAL_DISCARD_NORETURN
inline void
69 out_fatal_discard(const char *file
, int line
, const char *func
,
78 static __attribute__((always_inline
)) NORETURN
inline void
79 out_fatal_abort(const char *file
, int line
, const char *func
,
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
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)
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));
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__);\
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__); \
125 /* produce output and exit */
127 OUT_FATAL_ABORT(__FILE__, __LINE__, __func__, __VA_ARGS__)
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);\
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);\
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)); \
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)); \
158 /* assert a condition is true */
162 * Detect useless asserts on always true expression. Please use\
163 * COMPILE_ERROR_ON(!cnd) or ASSERT_rt(cnd) in such cases.\
165 TEST_ALWAYS_TRUE_EXPR(cnd);\
169 /* assertion with extra info printed if assertion fails */
170 #define ASSERTinfo(cnd, info)\
172 /* See comment in ASSERT. */\
173 TEST_ALWAYS_TRUE_EXPR(cnd);\
174 ASSERTinfo_rt(cnd, info);\
177 /* assert two integer values are equal */
178 #define ASSERTeq(lhs, rhs)\
180 /* See comment in ASSERT. */\
181 TEST_ALWAYS_EQ_EXPR(lhs, rhs);\
182 ASSERTeq_rt(lhs, rhs);\
185 /* assert two integer values are not equal */
186 #define ASSERTne(lhs, rhs)\
188 /* See comment in ASSERT. */\
189 TEST_ALWAYS_NE_EXPR(lhs, rhs);\
190 ASSERTne_rt(lhs, rhs);\
194 out_err(__FILE__, __LINE__, __func__, __VA_ARGS__)
196 void out_init(const char *log_prefix
, const char *log_level_var
,
197 const char *log_file_var
, int major_version
,
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
));
213 #ifndef PMDK_UTF8_API
214 #define out_get_errormsg out_get_errormsgW
216 #define out_get_errormsg out_get_errormsgU
221 const char *out_get_errormsg(void);
223 const char *out_get_errormsgU(void);
224 const wchar_t *out_get_errormsgW(void);