| #ifndef VTR_LOG_H |
| #define VTR_LOG_H |
| #include <tuple> |
| #include <unordered_set> |
| #include <string> |
| |
| /* |
| * This header defines useful logging macros for VTR projects. |
| * |
| * Message Type |
| * ============ |
| * |
| * Three types of log message types are defined: |
| * VTR_LOG - The standard 'info' type log message |
| * VTR_LOG_WARN - A warning log message |
| * VTR_LOG_ERROR - An error log message |
| * |
| * For example: |
| * |
| * VTR_LOG("This produces a regular '%s' message\n", "info"); |
| * VTR_LOG_WARN("This produces a '%s' message\n", "warning"); |
| * VTR_LOG_ERROR("This produces an '%s' message\n", "error"); |
| * |
| * Conditional Logging |
| * =================== |
| * |
| * Each of the three message types also have a VTR_LOGV_* variant, |
| * which will cause the message to be logged if a user-defined condition |
| * is satisifed. |
| * |
| * For example: |
| * |
| * VTR_LOGV(verbosity > 5, "This message will be logged only if verbosity is greater than %d\n", 5); |
| * VTR_LOGV_WARN(verbose, "This warning message will be logged if verbose is true\n"); |
| * VTR_LOGV_ERROR(false, "This error message will never be logged\n"); |
| * |
| * Custom Location Logging |
| * ======================= |
| * |
| * Each of the three message types also have a VTR_LOGF_* variant, |
| * which will cause the message to be logged for a custom file and |
| * line loation. |
| * |
| * For example: |
| * |
| * VTR_LOGF("my_file.txt", 42 "This message will be logged from file 'my_file.txt' line %d\n", 42); |
| * |
| * Debug Logging |
| * ============= |
| * |
| * For debug purposes it may be useful to have additional logging. |
| * This is supported by VTR_LOG_DEBUG() and VTR_LOGV_DEBUG(). |
| * |
| * To avoid run-time overhead, these are only enabled if VTR_ENABLE_DEBUG_LOGGING |
| * is defined (disabled by default). |
| */ |
| |
| //Unconditional logging macros |
| #define VTR_LOG(...) VTR_LOGV(true, __VA_ARGS__) |
| #define VTR_LOG_WARN(...) VTR_LOGV_WARN(true, __VA_ARGS__) |
| #define VTR_LOG_ERROR(...) VTR_LOGV_ERROR(true, __VA_ARGS__) |
| #define VTR_LOG_NOP(...) VTR_LOGV_NOP(true, __VA_ARGS__) |
| |
| //Conditional logging macros |
| #define VTR_LOGV(expr, ...) VTR_LOGVF(expr, __FILE__, __LINE__, __VA_ARGS__) |
| #define VTR_LOGV_WARN(expr, ...) VTR_LOGVF_WARN(expr, __FILE__, __LINE__, __VA_ARGS__) |
| #define VTR_LOGV_ERROR(expr, ...) VTR_LOGVF_ERROR(expr, __FILE__, __LINE__, __VA_ARGS__) |
| #define VTR_LOGV_NOP(expr, ...) VTR_LOGVF_NOP(expr, __FILE__, __LINE__, __VA_ARGS__) |
| |
| //Custom file-line location logging macros |
| #define VTR_LOGF(file, line, ...) VTR_LOGVF(true, file, line, __VA_ARGS__) |
| #define VTR_LOGF_WARN(file, line, ...) VTR_LOGVF_WARN(true, file, line, __VA_ARGS__) |
| #define VTR_LOGF_ERROR(file, line, ...) VTR_LOGVF_ERROR(true, file, line, __VA_ARGS__) |
| #define VTR_LOGF_NOP(file, line, ...) VTR_LOGVF_NOP(true, file, line, __VA_ARGS__) |
| |
| //Custom file-line-func location logging macros |
| #define VTR_LOGFF_WARN(file, line, func, ...) VTR_LOGVFF_WARN(true, file, line, func, __VA_ARGS__) |
| |
| //Conditional logging and custom file-line location macros |
| #define VTR_LOGVF(expr, file, line, ...) \ |
| do { \ |
| if (expr) vtr::printf(__VA_ARGS__); \ |
| } while (false) |
| |
| #define VTR_LOGVF_WARN(expr, file, line, ...) \ |
| do { \ |
| if (expr) print_or_suppress_warning(file, line, __func__, __VA_ARGS__); \ |
| } while (false) |
| |
| #define VTR_LOGVF_ERROR(expr, file, line, ...) \ |
| do { \ |
| if (expr) vtr::printf_error(file, line, __VA_ARGS__); \ |
| } while (false) |
| |
| // Conditional logging and custom file-line-func location macros |
| #define VTR_LOGVFF_WARN(expr, file, line, func, ...) \ |
| do { \ |
| if (expr) print_or_suppress_warning(file, line, func, __VA_ARGS__); \ |
| } while (false) |
| |
| //No-op version of logging macro which avoids unused parameter warnings. |
| // |
| //Note that to avoid unused parameter warnings we call sizeof() and cast |
| //the result to void. sizeof is evaluated at compile time so there is no |
| //run-time overhead. |
| // |
| //Also note the use of std::make_tuple to ensure all arguments in VA_ARGS |
| //are used. |
| #define VTR_LOGVF_NOP(expr, file, line, ...) \ |
| do { \ |
| static_cast<void>(sizeof(expr)); \ |
| static_cast<void>(sizeof(file)); \ |
| static_cast<void>(sizeof(line)); \ |
| static_cast<void>(sizeof(std::make_tuple(__VA_ARGS__))); \ |
| } while (false) |
| |
| //Debug logging macros |
| #ifdef VTR_ENABLE_DEBUG_LOGGING //Enable |
| # define VTR_LOG_DEBUG(...) VTR_LOG(__VA_ARGS__) |
| # define VTR_LOGV_DEBUG(expr, ...) VTR_LOGV(expr, __VA_ARGS__) |
| #else //Disable |
| # define VTR_LOG_DEBUG(...) VTR_LOG_NOP(__VA_ARGS__) |
| # define VTR_LOGV_DEBUG(expr, ...) VTR_LOGV_NOP(expr, __VA_ARGS__) |
| #endif |
| |
| namespace vtr { |
| |
| typedef void (*PrintHandlerInfo)(const char* pszMessage, ...); |
| typedef void (*PrintHandlerWarning)(const char* pszFileName, unsigned int lineNum, const char* pszMessage, ...); |
| typedef void (*PrintHandlerError)(const char* pszFileName, unsigned int lineNum, const char* pszMessage, ...); |
| typedef void (*PrintHandlerDirect)(const char* pszMessage, ...); |
| |
| extern PrintHandlerInfo printf; //Same as printf_info |
| extern PrintHandlerInfo printf_info; |
| extern PrintHandlerWarning printf_warning; |
| extern PrintHandlerError printf_error; |
| extern PrintHandlerDirect printf_direct; |
| |
| void set_log_file(const char* filename); |
| |
| } // namespace vtr |
| |
| // The following data structure and functions allow to suppress noisy warnings |
| // and direct them into an external file, if specified. |
| static std::unordered_set<std::string> warnings_to_suppress; |
| static std::string noisy_warn_log_file; |
| |
| void add_warnings_to_suppress(std::string function_name); |
| |
| // This function creates a new log file to hold the suppressed warnings. |
| // If the file already exists, it is cleared out first. |
| void set_noisy_warn_log_file(std::string log_file_name); |
| |
| // This function checks whether the function from which the warning has been called |
| // is in the set of warnings_to_suppress. If so, the warning is printed on the |
| // noisy_warn_log_file, otherwise it is printed on stdout (or the regular log file) |
| void print_or_suppress_warning(const char* pszFileName, unsigned int lineNum, const char* pszFuncName, const char* pszMessage, ...); |
| |
| #endif |