extern unsigned int symbol_lookup_debug;
+/* Return true if symbol-lookup debug is turned on at all. */
+
+static inline bool
+symbol_lookup_debug_enabled ()
+{
+ return symbol_lookup_debug > 0;
+}
+
+/* Return true if symbol-lookup debug is turned to verbose mode. */
+
+static inline bool
+symbol_lookup_debug_enabled_v ()
+{
+ return symbol_lookup_debug > 1;
+}
+
/* Print a "symbol-lookup" debug statement if symbol_lookup_debug is >= 1. */
#define symbol_lookup_debug_printf(fmt, ...) \
- debug_prefixed_printf_cond (symbol_lookup_debug >= 1, "symbol-lookup", fmt, \
- ##__VA_ARGS__)
+ debug_prefixed_printf_cond (symbol_lookup_debug_enabled (), \
+ "symbol-lookup", fmt, ##__VA_ARGS__)
/* Print a "symbol-lookup" debug statement if symbol_lookup_debug is >= 2. */
#define symbol_lookup_debug_printf_v(fmt, ...) \
- debug_prefixed_printf_cond (symbol_lookup_debug >= 2, "symbol-lookup", fmt, \
- ##__VA_ARGS__)
+ debug_prefixed_printf_cond (symbol_lookup_debug_enabled_v (), \
+ "symbol-lookup", fmt, ##__VA_ARGS__)
+
+/* Print "symbol-lookup" enter/exit debug statements. */
+
+#define SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT \
+ scoped_debug_enter_exit (symbol_lookup_debug_enabled, "symbol-lookup")
extern bool basenames_may_differ;
it on destruction, such that nested debug statements will be printed with
an indent and appear "inside" this one. */
+template<typename PT>
struct scoped_debug_start_end
{
/* DEBUG_ENABLED is a reference to a variable that indicates whether debugging
separately at construction and destruction, such that the start statement
could be printed but not the end statement, or vice-versa.
+ DEBUG_ENABLED should either be of type 'bool &' or should be a type
+ that can be invoked.
+
MODULE and FUNC are forwarded to debug_prefixed_printf.
START_PREFIX and END_PREFIX are the statements to print on construction and
destruction, respectively.
If the FMT format string is non-nullptr, then a `: ` is appended to the
- messages, followed by the rendering of that format string. The format
- string is rendered during construction and is re-used as is for the
- message on exit. */
+ messages, followed by the rendering of that format string with ARGS.
+ The format string is rendered during construction and is re-used as is
+ for the message on exit. */
- scoped_debug_start_end (bool &debug_enabled, const char *module,
+ scoped_debug_start_end (PT &debug_enabled, const char *module,
const char *func, const char *start_prefix,
- const char *end_prefix, const char *fmt, ...)
- ATTRIBUTE_NULL_PRINTF (7, 8)
+ const char *end_prefix, const char *fmt,
+ va_list args)
+ ATTRIBUTE_NULL_PRINTF (7, 0)
: m_debug_enabled (debug_enabled),
m_module (module),
m_func (func),
m_end_prefix (end_prefix),
m_with_format (fmt != nullptr)
{
- if (m_debug_enabled)
+ if (is_debug_enabled ())
{
if (fmt != nullptr)
{
- va_list args;
- va_start (args, fmt);
m_msg = string_vprintf (fmt, args);
- va_end (args);
-
debug_prefixed_printf (m_module, m_func, "%s: %s",
start_prefix, m_msg->c_str ());
}
DISABLE_COPY_AND_ASSIGN (scoped_debug_start_end);
+ scoped_debug_start_end (scoped_debug_start_end &&other) = default;
+
~scoped_debug_start_end ()
{
if (m_must_decrement_print_depth)
--debug_print_depth;
}
- if (m_debug_enabled)
+ if (is_debug_enabled ())
{
if (m_with_format)
{
}
private:
- bool &m_debug_enabled;
+
+ /* This function is specialized based on the type PT. Returns true if
+ M_DEBUG_ENABLED indicates this debug setting is enabled, otherwise,
+ return false. */
+ bool is_debug_enabled () const;
+
+ /* Reference to the debug setting, or a callback that can read the debug
+ setting. Access the value of this by calling IS_DEBUG_ENABLED. */
+ PT &m_debug_enabled;
+
const char *m_module;
const char *m_func;
const char *m_end_prefix;
bool m_must_decrement_print_depth = false;
};
+/* Implementation of is_debug_enabled when PT is an invokable type. */
+
+template<typename PT>
+inline bool
+scoped_debug_start_end<PT>::is_debug_enabled () const
+{
+ return m_debug_enabled ();
+}
+
+/* Implementation of is_debug_enabled when PT is 'bool &'. */
+
+template<>
+inline bool
+scoped_debug_start_end<bool &>::is_debug_enabled () const
+{
+ return m_debug_enabled;
+}
+
+/* Wrapper around the scoped_debug_start_end constructor to allow the
+ caller to create an object using 'auto' type, the actual type will be
+ based on the type of the PRED argument. All arguments are forwarded to
+ the scoped_debug_start_end constructor. */
+
+template<typename PT>
+static inline scoped_debug_start_end<PT &> ATTRIBUTE_NULL_PRINTF (6, 7)
+make_scoped_debug_start_end (PT &&pred, const char *module, const char *func,
+ const char *start_prefix,
+ const char *end_prefix, const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ auto res = scoped_debug_start_end<PT &> (pred, module, func, start_prefix,
+ end_prefix, fmt, args);
+ va_end (args);
+
+ return res;
+}
+
/* Helper to define a module-specific start/end debug macro. */
-#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \
- scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
- (debug_enabled, module, __func__, "start", "end", fmt, ##__VA_ARGS__)
+#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \
+ auto CONCAT(scoped_debug_start_end, __LINE__) \
+ = make_scoped_debug_start_end (debug_enabled, module, \
+ __func__, "start", "end", \
+ fmt, ##__VA_ARGS__)
/* Helper to define a module-specific enter/exit debug macro. This is a special
case of `scoped_debug_start_end` where the start and end messages are "enter"
and "exit", to denote entry and exit of a function. */
-#define scoped_debug_enter_exit(debug_enabled, module) \
- scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
- (debug_enabled, module, __func__, "enter", "exit", nullptr)
+#define scoped_debug_enter_exit(debug_enabled, module) \
+ auto CONCAT(scoped_debug_start_end, __LINE__) \
+ = make_scoped_debug_start_end (debug_enabled, module, \
+ __func__, "enter", "exit", \
+ nullptr)
#endif /* COMMON_COMMON_DEBUG_H */