aboutsummaryrefslogtreecommitdiff
path: root/src/util.h
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-01-16 15:52:37 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-01-23 16:05:00 +0100
commitb77dfdc9e36e308aa806d63aa3b5628971789d5a (patch)
tree555894b6364e76c4a5c3d7962f6991de1f5588f8 /src/util.h
parent53e9d3aa44e24fecd2d58984baff3cb4af23c12e (diff)
downloadbitcoin-b77dfdc9e36e308aa806d63aa3b5628971789d5a.tar.xz
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.h72
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);