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
This commit is contained in:
72
src/util.h
72
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).
|
||||
*/
|
||||
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);
|
||||
#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
|
||||
*/
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user