Program Listing for File macros.hpp
↰ Return to documentation for file (rcppsw/er/macros.hpp
)
#pragma once
/*******************************************************************************
* Includes
******************************************************************************/
#include "rcppsw/er/er.hpp"
#if (RCPPSW_ERL >= RCPPSW_ERL_FATAL)
#endif
/* #if (RCPPSW_ERL == RCPPSW_ERL_FATAL) */
/* #include <type_traits> */
/* #endif */
#if (RCPPSW_ERL >= RCPPSW_ERL_FATAL)
#include <array>
#include <cassert>
#include <string>
#include <iostream>
#include "rcppsw/er/stacktrace.hpp"
#endif
/*******************************************************************************
* Macros when ER is enabled for severity level >= FATAL:
*
* - The configured plugin is disabled. Only [FATAL] events are compiled in;
* others are discarded.
******************************************************************************/
#if (RCPPSW_ERL == RCPPSW_ERL_FATAL)
#define ER_FATAL(msg, ...) \
{ \
std::array<char, RCPPSW_ER_MSG_LEN_MAX> _str{}; \
snprintf(_str.data(), RCPPSW_ER_MSG_LEN_MAX, msg, ##__VA_ARGS__); \
std::ostringstream _buf; \
_buf \
<< _str.data() << "\n" \
<< "Backtrace:\n" << rer::stacktrace::stacktrace() << '\n'; \
}
#elif (RCPPSW_ERL > RCPPSW_ERL_FATAL)
#define ER_FATAL(...) ER_FATAL_IMPL(RCPPSW_ER_PLUGIN_HANDLE(), __VA_ARGS__)
/* \cond INTERNAL */
#define ER_FATAL_IMPL(handle, ...) { \
if (RCPPSW_ER_PLUGIN_LVL_CHECK(handle, FATAL)) { \
ER_REPORT(FATAL, handle, __VA_ARGS__) \
} \
}
/* \endcond */
#endif
/*******************************************************************************
* Macros when ER is enabled for severity level >= ERROR:
*
* - The configured plugin is used. Only [FATAL,ERROR] events are compiled in;
* others are discarded.
******************************************************************************/
#if (RCPPSW_ERL >= RCPPSW_ERL_ERROR)
#define ER_ERR(...) ER_ERR_IMPL(RCPPSW_ER_PLUGIN_HANDLE(), __VA_ARGS__)
/* \cond INTERNAL */
#define ER_ERR_IMPL(handle, ...) { \
if (RCPPSW_ER_PLUGIN_LVL_CHECK(handle, ERROR)) { \
ER_REPORT(ERROR, handle, __VA_ARGS__) \
} \
}
/* \endcond */
#endif /* RCPPSW_ERL >= RCPPSW_ERL_ERROR */
/*******************************************************************************
* Macros when ER is enabled for severity level >= WARN:
*
* - The configured plugin is used. Only [FATAL,ERROR,WARN] events are compiled
* in; others are discarded.
******************************************************************************/
#if (RCPPSW_ERL >= RCPPSW_ERL_WARN)
#define ER_WARN(...) ER_WARN_IMPL(RCPPSW_ER_PLUGIN_HANDLE(), __VA_ARGS__)
/* \cond INTERNAL */
#define ER_WARN_IMPL(handle, ...) { \
if (RCPPSW_ER_PLUGIN_LVL_CHECK(handle, WARN)) { \
ER_REPORT(WARN, handle, ## __VA_ARGS__) \
} \
}
/* \endcond */
#endif /* RCPPSW_ERL >= RCPPSW_ERL_WARN */
/*******************************************************************************
* Macros when ER is enabled for severity level >= INFO:
*
* - The configured plugin is used. Only [FATAL,ERROR,WARN,INFO] events are
* compiled in; others are discarded.
******************************************************************************/
#if (RCPPSW_ERL >= RCPPSW_ERL_INFO)
#define ER_INFO(...) ER_INFO_IMPL(RCPPSW_ER_PLUGIN_HANDLE(), __VA_ARGS__)
/* \cond INTERNAL */
#define ER_INFO_IMPL(handle, ...) { \
if (RCPPSW_ER_PLUGIN_LVL_CHECK(handle, INFO)) { \
ER_REPORT(INFO, handle, ## __VA_ARGS__) \
} \
}
/* \endcond */
#endif /* RCPPSW_ERL >= RCPPSW_ERL_INFO */
/*******************************************************************************
* Macros when ER is enabled for severity level >= DEBUG:
*
* - The configured plugin is used. Only [FATAL,ERROR,WARN,INFO,DEBUG] events
* are compiled in; others are discarded.
******************************************************************************/
#if (RCPPSW_ERL >= RCPPSW_ERL_DEBUG)
#define ER_DEBUG(...) ER_DEBUG_IMPL(RCPPSW_ER_PLUGIN_HANDLE(), __VA_ARGS__)
/* \cond INTERNAL */
#define ER_DEBUG_IMPL(handle, ...) { \
if (RCPPSW_ER_PLUGIN_LVL_CHECK(handle, DEBUG)) { \
ER_REPORT(DEBUG, handle, ## __VA_ARGS__) \
} \
}
/* \endcond */
#endif /* RCPPSW_ERL >= RCPPSW_ERL_DEBUG */
/*******************************************************************************
* Macros when ER is enabled for severity level >= TRACE:
*
* - The configured plugin is used. Only [FATAL,ERROR,WARN,INFO,DEBUG,TRACE]
* events are compiled in; others are discarded.
*
* - Debug printing macros enabled.
******************************************************************************/
#if (RCPPSW_ERL >= RCPPSW_ERL_TRACE)
#define ER_TRACE(...) ER_TRACE_IMPL(RCPPSW_ER_PLUGIN_HANDLE(), __VA_ARGS__)
/* \cond INTERNAL */
#define ER_TRACE_IMPL(handle, ...) { \
if (RCPPSW_ER_PLUGIN_LVL_CHECK(handle, TRACE)) { \
ER_REPORT(TRACE, handle, ## __VA_ARGS__) \
} \
}
/* \endcond */
#endif /* RCPPSW_ERL >= RCPPSW_ERL_TRACE */
/*******************************************************************************
* General ER macros for when ER is != NONE.
******************************************************************************/
#if RCPPSW_ERL != RCPPSW_ERL_NONE
#define ER_REPORT(LVL, HANDLE, MSG, ...) \
{ \
RCPPSW_ER_PLUGIN_REPORT(LVL, \
HANDLE, \
MSG "\n", \
## __VA_ARGS__) \
}
#endif /* (RCPPSW_ERL != RCPPSW_ERL_NONE) */
/*******************************************************************************
* General ER macros independent of level
******************************************************************************/
#define PRINTF(...) RCPPSW_ER_PLUGIN_PRINTF(__VA_ARGS__)
/*
* Don't define the macro to be nothing, as that can leave tons of "unused
* variable" warnings in the code for variables which are only used in
* asserts. The sizeof() trick here does *NOT* actually evaluate the
* condition--only the size of whatever it returns. The variables are "used",
* making the compiler happy, but ultimately removed by the optimizer.
*/
#define ER_ASSERT(cond, msg, ...) \
do { \
(void)sizeof((cond)); \
if (RCPPSW_UNLIKELY(!(cond))) { \
ER_FATAL( msg, ##__VA_ARGS__); \
assert(cond); \
} \
} while (0);
#define ER_CONDW(cond, msg, ...) \
{ \
if (RCPPSW_LIKELY((cond))) { \
ER_WARN(msg, ##__VA_ARGS__); \
} \
}
#define ER_CONDI(cond, msg, ...) \
{ \
if (RCPPSW_LIKELY((cond))) { \
ER_INFO(msg, ##__VA_ARGS__); \
} \
}
#define ER_CONDD(cond, msg, ...) \
{ \
if (RCPPSW_LIKELY((cond))) { \
ER_DEBUG(msg, ##__VA_ARGS__); \
} \
}
#define ER_FATAL_SENTINEL(msg, ...) \
{ \
ER_FATAL(msg, ##__VA_ARGS__); \
std::abort(); \
}
#define ER_CHECK(cond, msg, ...) \
{ \
if (RCPPSW_UNLIKELY(!(cond))) { \
ER_ERR(msg, ##__VA_ARGS__); \
goto error; \
} \
}
#define ER_SENTINEL(msg, ...) \
{ \
ER_ERR(msg, ##__VA_ARGS__); \
goto error; \
}
/*******************************************************************************
* Macro Cleanup
*
* Depending on compile-time level, one or more of these macros may be
* undefined, so make sure everything is defined so things build cleanly.
******************************************************************************/
#ifndef ER_FATAL
#define ER_FATAL(...)
#endif
#ifndef ER_ERR
#define ER_ERR(...)
#endif
#ifndef ER_WARN
#define ER_WARN(...)
#endif
#ifndef ER_INFO
#define ER_INFO(...)
#endif
#ifndef ER_DEBUG
#define ER_DEBUG(...)
#endif
#ifndef ER_TRACE
#define ER_TRACE(...)
#endif
#ifndef ER_REPORT
#define ER_REPORT(...)
#endif