Fix: global logging symbols defined multiple times
[babeltrace.git] / include / babeltrace / logging-internal.h
index bbe3596b905fbd9724ff91533afe68a42e87d8a5..ee93660fa677395d9e75f699274962ee0915c463 100644 (file)
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <babeltrace/logging.h>
+#include <babeltrace/babeltrace-internal.h>
 
 /* To detect incompatible changes you can define BT_LOG_VERSION_REQUIRED to be
  * the current value of BT_LOG_VERSION before including this file (or via
 #if defined(BT_LOG_OUTPUT_LEVEL)
        #define _BT_LOG_OUTPUT_LEVEL BT_LOG_OUTPUT_LEVEL
 #else
-       #define _BT_LOG_OUTPUT_LEVEL _bt_log_global_output_lvl
+       /*
+        * We disallow this to make sure Babeltrace modules always
+        * have their own local log level.
+        */
+       #error No log level symbol specified: please define BT_LOG_OUTPUT_LEVEL before including this header.
 #endif
 
 /* "Tag" is a compound string that could be associated with a log message. It
  * corresponding BT_LOG_DEFINE_XXX macro MUST be used exactly once somewhere.
  * Otherwise build will fail with link error (undefined symbol).
  */
-#define BT_LOG_DEFINE_TAG_PREFIX const char *_bt_log_tag_prefix
-#define BT_LOG_DEFINE_GLOBAL_FORMAT bt_log_format _bt_log_global_format
-#define BT_LOG_DEFINE_GLOBAL_OUTPUT bt_log_output _bt_log_global_output
-#define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL int _bt_log_global_output_lvl
+#define BT_LOG_DEFINE_TAG_PREFIX BT_HIDDEN const char *_bt_log_tag_prefix
+#define BT_LOG_DEFINE_GLOBAL_FORMAT BT_HIDDEN bt_log_format _bt_log_global_format
+#define BT_LOG_DEFINE_GLOBAL_OUTPUT BT_HIDDEN bt_log_output _bt_log_global_output
+#define BT_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL BT_HIDDEN int _bt_log_global_output_lvl
 
 /* Pointer to global format options. Direct modification is not allowed. Use
  * bt_log_set_mem_width() instead. Could be used to initialize bt_log_spec
 #if defined(__printflike)
        #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
                __printflike(str_index, first_to_check)
+#elif defined(__MINGW_PRINTF_FORMAT)
+       #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
+               __attribute__((format(__MINGW_PRINTF_FORMAT, str_index, first_to_check)))
 #elif defined(__GNUC__)
        #define _BT_LOG_PRINTFLIKE(str_index, first_to_check) \
                __attribute__((format(__printf__, str_index, first_to_check)))
@@ -727,6 +735,14 @@ void _bt_log_write_mem_aux(
  * - BT_LOGE("format string", args, ...)
  * - BT_LOGF("format string", args, ...)
  *
+ * Message and error string (errno) logging macros:
+ * - BT_LOGV_ERRNO("initial message", "format string", args, ...)
+ * - BT_LOGD_ERRNO("initial message", "format string", args, ...)
+ * - BT_LOGI_ERRNO("initial message", "format string", args, ...)
+ * - BT_LOGW_ERRNO("initial message", "format string", args, ...)
+ * - BT_LOGE_ERRNO("initial message", "format string", args, ...)
+ * - BT_LOGF_ERRNO("initial message", "format string", args, ...)
+ *
  * Memory logging macros:
  * - BT_LOGV_MEM(data_ptr, data_sz, "format string", args, ...)
  * - BT_LOGD_MEM(data_ptr, data_sz, "format string", args, ...)
@@ -821,6 +837,13 @@ void _bt_log_write_mem_aux(
                        } _BT_LOG_ONCE
 #endif
 
+#define BT_LOG_WRITE_ERRNO(lvl, tag, _msg, _fmt, args...) \
+               do { \
+                       const char *error_str; \
+                       error_str = g_strerror(errno); \
+                       BT_LOG_WRITE(lvl, tag, _msg ": %s" _fmt, error_str, ## args); \
+               } _BT_LOG_ONCE
+
 static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 
 #define _BT_LOG_UNUSED(...) \
@@ -829,6 +852,8 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 #if BT_LOG_ENABLED_VERBOSE
        #define BT_LOGV(...) \
                        BT_LOG_WRITE(BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__)
+       #define BT_LOGV_ERRNO(...) \
+                       BT_LOG_WRITE_ERRNO(BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGV_AUX(log, ...) \
                        BT_LOG_WRITE_AUX(log, BT_LOG_VERBOSE, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGV_MEM(d, d_sz, ...) \
@@ -845,6 +870,8 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 #if BT_LOG_ENABLED_DEBUG
        #define BT_LOGD(...) \
                        BT_LOG_WRITE(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
+       #define BT_LOGD_ERRNO(...) \
+                       BT_LOG_WRITE_ERRNO(BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGD_AUX(log, ...) \
                        BT_LOG_WRITE_AUX(log, BT_LOG_DEBUG, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGD_MEM(d, d_sz, ...) \
@@ -861,6 +888,8 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 #if BT_LOG_ENABLED_INFO
        #define BT_LOGI(...) \
                        BT_LOG_WRITE(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
+       #define BT_LOGI_ERRNO(...) \
+                       BT_LOG_WRITE_ERRNO(BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGI_AUX(log, ...) \
                        BT_LOG_WRITE_AUX(log, BT_LOG_INFO, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGI_MEM(d, d_sz, ...) \
@@ -877,6 +906,8 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 #if BT_LOG_ENABLED_WARN
        #define BT_LOGW(...) \
                        BT_LOG_WRITE(BT_LOG_WARN, _BT_LOG_TAG, __VA_ARGS__)
+       #define BT_LOGW_ERRNO(...) \
+                       BT_LOG_WRITE_ERRNO(BT_LOG_WARN, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGW_AUX(log, ...) \
                        BT_LOG_WRITE_AUX(log, BT_LOG_WARN, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGW_MEM(d, d_sz, ...) \
@@ -893,6 +924,8 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 #if BT_LOG_ENABLED_ERROR
        #define BT_LOGE(...) \
                        BT_LOG_WRITE(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
+       #define BT_LOGE_ERRNO(...) \
+                       BT_LOG_WRITE_ERRNO(BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGE_AUX(log, ...) \
                        BT_LOG_WRITE_AUX(log, BT_LOG_ERROR, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGE_MEM(d, d_sz, ...) \
@@ -909,6 +942,8 @@ static _BT_LOG_INLINE void _bt_log_unused(const int dummy, ...) {(void)dummy;}
 #if BT_LOG_ENABLED_FATAL
        #define BT_LOGF(...) \
                        BT_LOG_WRITE(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
+       #define BT_LOGF_ERRNO(...) \
+                       BT_LOG_WRITE_ERRNO(BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGF_AUX(log, ...) \
                        BT_LOG_WRITE_AUX(log, BT_LOG_FATAL, _BT_LOG_TAG, __VA_ARGS__)
        #define BT_LOGF_MEM(d, d_sz, ...) \
@@ -946,6 +981,8 @@ extern "C" {
  *   bt_log_set_output_v(BT_LOG_OUT_STDERR);
  */
 enum { BT_LOG_OUT_STDERR_MASK = BT_LOG_PUT_STD };
+
+BT_HIDDEN
 void bt_log_out_stderr_callback(const bt_log_message *const msg, void *arg);
 #define BT_LOG_OUT_STDERR BT_LOG_OUT_STDERR_MASK, 0, bt_log_out_stderr_callback
 
@@ -999,8 +1036,19 @@ end:
        return level;
 }
 
+#define BT_LOG_LEVEL_EXTERN_SYMBOL(_level_sym)                         \
+       extern int _level_sym
+
+#define BT_LOG_INIT_LOG_LEVEL(_level_sym, _env_var)                    \
+       BT_HIDDEN int _level_sym = BT_LOG_NONE;                         \
+       static                                                          \
+       void __attribute__((constructor)) _bt_log_level_ctor(void)      \
+       {                                                               \
+               _level_sym = bt_log_get_level_from_env(_env_var);       \
+       }
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif
+#endif /* BABELTRACE_LOGGING_INTERNAL_H */
This page took 0.024741 seconds and 4 git commands to generate.