2017-02-16 102 views
1

在我的項目中,我有很多文件,我想用C++宏來管理調試。對於每個文件,我想使用自己的開關啓用或禁用調試並調整調試級別。所以基本上共享文件與設置:定義另一組宏的多行宏

這是共享文件debug.h的外觀:

#define DEBUG_LEVEL_LOG    -1 
#define DEBUG_LEVEL_NONE   0 
#define DEBUG_LEVEL_ERROR   1 
#define DEBUG_LEVEL_WARNING   2 
#define DEBUG_LEVEL_INFO   3 
#define DEBUG_LEVEL_DEBUG   4 
#define DEBUG_LEVEL_TRACE   5 

#ifndef ON 
#define ON 1 
#endif 

#ifndef OFF 
#define OFF 0 
#endif 

// setings for component "wireless" 
#define WIRELESS_DEBUGGING     ON 
#define WIRELESS_DEBUGGING_LEVEL   DEBUG_LEVEL_ERROR 

// settings for another components 
... 

在我想這個設置,我需要定義宏的另一個一堆調試的每個文件。例如文件「wireless.h」

#ifndef WIRELESS_DEBUGGING 
#define WIRELESS_DEBUGGING_LEVEL   DEBUG_LEVEL_NONE 
#endif 

#if WIRELESS_DEBUGGING 
    #if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_LOG 
     #define WIRELESS_LOG(...);   Logger::log(__VA_ARGS__); 
    #else 
     #define WIRELESS_LOG(...);   {} 
    #endif 

    #if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_ERROR 
     #define WIRELESS_ERROR(...);  Logger::error(__VA_ARGS__); 
    #else 
     #define WIRELESS_ERROR(...);  {} 
    #endif 

    #if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_WARNING 
     #define WIRELESS_WARNING(...);  Logger::warning(__VA_ARGS__); 
    #else 
     #define WIRELESS_WARNING(...);  {} 
    #endif 

    #if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_INFO 
     #define WIRELESS_INFO(...);   Logger::info(__VA_ARGS__); 
    #else 
     #define WIRELESS_INFO(...);   {} 
    #endif 

    #if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_DEBUG 
     #define WIRELESS_DEBUG(...);  Logger::debug(__VA_ARGS__); 
    #else 
     #define WIRELESS_DEBUG(...);  {} 
    #endif 

    #if WIRELESS_DEBUGGING_LEVEL >= DEBUG_LEVEL_TRACE 
     #define WIRELESS_TRACE(...);  Logger::trace(__VA_ARGS__); 
    #else 
     #define WIRELESS_TRACE(...);  {} 
    #endif 

#else 
    #define WIRELESS_LOG(...);    {} 
    #define WIRELESS_ERROR(...);   {} 
    #define WIRELESS_WARNING(...);   {} 
    #define WIRELESS_INFO(...);    {} 
    #define WIRELESS_DEBUG(...);   {} 
    #define WIRELESS_TRACE(...);   {} 
#endif 

當我想調試定的組件,我只是用這樣的事情(在wireless.cpp)

WIRELESS_TRACE("wireless: hello world\n"); 
... etc ... 

到目前爲止,它的工作。這裏是一個問題:我不想在每個使用不同前綴的組件中使用類似於「wireless.h」文件中定義的「本地」定義。取而代之的是我想有一些「超微距」,這將類似於此

REGISTER_DEBUG(WIRELESS); 

有沒有辦法如何使用一些級聯和多線宏來實現這一目標?我發現在#define內使用#define是禁止的。

+3

更好地使用強類型的東西(這就是C++主要提供的C),以及使用RAII進行自動清理。爲了調試,使用一個很好的GUI調試器,比如Visual Studio中的調試器。簡而言之,在這種情況下,這是不夠的,需要良好的預防性編程和良好的工具。 –

+0

您希望在編譯時控制多少消息傳遞,以及您希望在運行時控制多少消息。例如,您是否希望能夠傳遞參數「--debug-level = trace」,並希望打印所有「跟蹤」消息? –

回答

0

這有點笨拙,但應該做的伎倆:

#define DEBUG_LEVEL_LOG    -1 
#define DEBUG_LEVEL_NONE   0 
#define DEBUG_LEVEL_ERROR   1 
#define DEBUG_LEVEL_WARNING   2 
#define DEBUG_LEVEL_INFO   3 
#define DEBUG_LEVEL_DEBUG   4 
#define DEBUG_LEVEL_TRACE   5 

#define TRACE(a,...) _TRACE(a,__VA_ARGS__) 
#define _TRACE(a,...) __TRACE_##a(__VA_ARGS__) 

#define __TRACE_5(...) do{Logger::trace(__VA_ARGS__);}while(0) 

這裏是笨拙:您還需要定義__TRACE_4__TRACE_3等是空的。然後你需要定義調試同樣的事情:

#define __DEBUG_4(...) do{Logger::debug(__VA_ARGS__);}while(0) 

但最終,你確定你的無線日誌級別後:

#define WIRELESS_LEVEL 5 

你可以調用宏就像這樣:

TRACE(WIRELESS_LEVEL,"wireless: hello world\n"); 

編輯 或者(這可能是清潔劑):

#define __PRINT_55(...) do{Logger::trace(__VA_ARGS__);}while(0) 
#define __PRINT_44(...) do{Logger::debug(__VA_ARGS__);}while(0) 

// etc... 
// Also need to define what you need to be not printed: 

#define __PRINT_01(...) 

// etc... 

#define PRINT(a,b,...) _PRINT(a,b,__VA_ARGS__) 
#define _PRINT(a,b,...) __PRINT_##a##b(__VA_ARGS__) 

現在你可以打電話給你的功能是這樣的:

PRINT(DEBUG_LEVEL_TRACE, WIRELESS_LEVEL, "Hello world\n"); 
0

您可以通過從宏切換到內聯函數那裏。就像這樣:

// debug.h 
enum DebugLevel { 
    DEBUG_LEVEL_LOG = -1, 
    DEBUG_LEVEL_NONE = 0, 
    DEBUG_LEVEL_ERROR = 1, 
    DEBUG_LEVEL_WARNING = 2, 
    DEBUG_LEVEL_INFO = 3, 
    DEBUG_LEVEL_DEBUG = 4, 
    DEBUG_LEVEL_TRACE = 5 
}; 

// settings for component "wireless" 
constexpr bool WIRELESS_DEBUGGING = true; 
constexpr DebugLevel WIRELESS_DEBUGGING_LEVEL = DEBUG_LEVEL_ERROR; 

#define REGISTER_DEBUG_FUNC(topic, level, func) \ 
template <typename... Args> \ 
inline void topic##_##level(Args&& ... args) { \ 
    if (topic##_DEBUGGING && topic##_DEBUGGING_LEVEL >= DEBUG_LEVEL_##level) \ 
     Logger::func(std::forward<Args>(args)...); \ 
} 

#define REGISTER_DEBUG(topic) \ 
    REGISTER_DEBUG_FUNC(topic, LOG, log) \ 
    REGISTER_DEBUG_FUNC(topic, ERROR, error) \ 
    REGISTER_DEBUG_FUNC(topic, WARNING, warning) \ 
    REGISTER_DEBUG_FUNC(topic, INFO, info) \ 
    REGISTER_DEBUG_FUNC(topic, DEBUG, debug) \ 
    REGISTER_DEBUG_FUNC(topic, TRACE, trace) 

// wireless.h 
REGISTER_DEBUG(WIRELESS)