diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-01-16 15:52:37 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2014-01-23 16:05:00 +0100 |
commit | b77dfdc9e36e308aa806d63aa3b5628971789d5a (patch) | |
tree | 555894b6364e76c4a5c3d7962f6991de1f5588f8 /src/util.h | |
parent | 53e9d3aa44e24fecd2d58984baff3cb4af23c12e (diff) |
Typesafe strprintf/error/LogPrint functions
Switch to tinyformat-based formatting.
Tinyformat is a typesafe drop-in replacement for C99 printf functions:
https://github.com/c42f/tinyformat
Diffstat (limited to 'src/util.h')
-rw-r--r-- | src/util.h | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/src/util.h b/src/util.h index c6a1318fd7..63bad61d23 100644 --- a/src/util.h +++ b/src/util.h @@ -12,6 +12,7 @@ #include "compat.h" #include "serialize.h" +#include "tinyformat.h" #include <cstdio> #include <exception> @@ -99,21 +100,6 @@ inline void MilliSleep(int64_t n) #endif } -/* This GNU C extension enables the compiler to check the format string against the parameters provided. - * X is the number of the "format string" parameter, and Y is the number of the first variadic parameter. - * Parameters count from 1. - */ -#ifdef __GNUC__ -#define ATTR_WARN_PRINTF(X,Y) __attribute__((format(gnu_printf,X,Y))) -#else -#define ATTR_WARN_PRINTF(X,Y) -#endif - - - - - - extern std::map<std::string, std::string> mapArgs; @@ -130,27 +116,49 @@ extern volatile bool fReopenDebugLog; void RandAddSeed(); void RandAddSeedPerfmon(); -// Print to debug.log if -debug=category switch is given OR category is NULL. -int ATTR_WARN_PRINTF(2,3) LogPrint(const char* category, const char* pszFormat, ...); +/* Return true if log accepts specified category */ +bool LogAcceptCategory(const char* category); +/* Send a string to the log output */ +int LogPrintStr(const std::string &str); + +#define strprintf tfm::format #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) -/* - Rationale for the real_strprintf / strprintf construction: - It is not allowed to use va_start with a pass-by-reference argument. - (C++ standard, 18.7, paragraph 3). Use a dummy argument to work around this, and use a - macro to keep similar semantics. -*/ - -/** Overload strprintf for char*, so that GCC format type warnings can be given */ -std::string ATTR_WARN_PRINTF(1,3) real_strprintf(const char *format, int dummy, ...); -/** Overload strprintf for std::string, to be able to use it with _ (translation). - * This will not support GCC format type warnings (-Wformat) so be careful. +/* When we switch to C++11, this can be switched to variadic templates instead + * of this macro-based construction (see tinyformat.h). + */ +#define MAKE_ERROR_AND_LOG_FUNC(n) \ + /* Print to debug.log if -debug=category switch is given OR category is NULL. */ \ + template<TINYFORMAT_ARGTYPES(n)> \ + static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \ + { \ + if(!LogAcceptCategory(category)) return 0; \ + return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \ + } \ + /* Log error and return false */ \ + template<TINYFORMAT_ARGTYPES(n)> \ + static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \ + { \ + LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n))); \ + return false; \ + } + +TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC) + +/* Zero-arg versions of logging and error, these are not covered by + * TINYFORMAT_FOREACH_ARGNUM */ -std::string real_strprintf(const std::string &format, int dummy, ...); -#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__) -std::string vstrprintf(const char *format, va_list ap); +static inline int LogPrint(const char* category, const char* format) +{ + if(!LogAcceptCategory(category)) return 0; + return LogPrintStr(format); +} +static inline bool error(const char* format) +{ + LogPrintStr(std::string("ERROR: ") + format); + return false; +} -bool ATTR_WARN_PRINTF(1,2) error(const char *format, ...); void LogException(std::exception* pex, const char* pszThread); void PrintException(std::exception* pex, const char* pszThread); |