]> git.proxmox.com Git - ceph.git/blame - ceph/src/pmdk/src/core/out.h
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / src / core / out.h
CommitLineData
a4b75251
TL
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
18extern "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
50static __attribute__((always_inline)) inline void
51out_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
61static __attribute__((always_inline)) inline void
62out_nonl_discard(int level, const char *fmt, ...)
63{
64 (void) level;
65 (void) fmt;
66}
67
68static __attribute__((always_inline)) OUT_FATAL_DISCARD_NORETURN inline void
69out_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
78static __attribute__((always_inline)) NORETURN inline void
79out_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
196void out_init(const char *log_prefix, const char *log_level_var,
197 const char *log_file_var, int major_version,
198 int minor_version);
199void out_fini(void);
200void out(const char *fmt, ...) FORMAT_PRINTF(1, 2);
201void out_nonl(int level, const char *fmt, ...) FORMAT_PRINTF(2, 3);
202void out_log(const char *file, int line, const char *func, int level,
203 const char *fmt, ...) FORMAT_PRINTF(5, 6);
204void out_err(const char *file, int line, const char *func,
205 const char *fmt, ...) FORMAT_PRINTF(4, 5);
206void NORETURN out_fatal(const char *file, int line, const char *func,
207 const char *fmt, ...) FORMAT_PRINTF(4, 5);
208void out_set_print_func(void (*print_func)(const char *s));
209void 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
221const char *out_get_errormsg(void);
222#else
223const char *out_get_errormsgU(void);
224const wchar_t *out_get_errormsgW(void);
225#endif
226
227#ifdef __cplusplus
228}
229#endif
230
231#endif