aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2012-09-25 22:56:29 -0700
committerWladimir J. van der Laan <laanwj@gmail.com>2012-09-25 22:56:29 -0700
commit5a1a3622153662b948537ad950be07a49864f82e (patch)
tree816fe70b3e9a700790b63a3568fad79dba2af00e /src
parent1381ad2b21733071acb2a43c251dbecef524f110 (diff)
parent3b3d9996181d9c93c81667f610e31212997fd184 (diff)
Merge pull request #1807 from laanwj/2012_09_printf_warnings
Add printf-style warnings to strprintf() and OutputDebugStringF()
Diffstat (limited to 'src')
-rw-r--r--src/bignum.h2
-rw-r--r--src/uint256.h2
-rw-r--r--src/util.cpp21
-rw-r--r--src/util.h60
4 files changed, 64 insertions, 21 deletions
diff --git a/src/bignum.h b/src/bignum.h
index 9fea3f70fb..96b1b2e6ae 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -305,7 +305,7 @@ public:
psz++;
// hex string to bignum
- static signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
+ static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
*this = 0;
while (isxdigit(*psz))
{
diff --git a/src/uint256.h b/src/uint256.h
index fc5ed26592..abd0b71e6f 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -306,7 +306,7 @@ public:
psz += 2;
// hex string to uint
- static unsigned char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
+ static const unsigned char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
const char* pbegin = psz;
while (phexdigit[(unsigned char)*psz] || *psz == '0')
psz++;
diff --git a/src/util.cpp b/src/util.cpp
index d1270348e0..a8bd8228e5 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -274,7 +274,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
return ret;
}
-string vstrprintf(const std::string &format, va_list ap)
+string vstrprintf(const char *format, va_list ap)
{
char buffer[50000];
char* p = buffer;
@@ -284,7 +284,11 @@ string vstrprintf(const std::string &format, va_list ap)
{
va_list arg_ptr;
va_copy(arg_ptr, ap);
- ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
+#ifdef WIN32
+ ret = _vsnprintf(p, limit, format, arg_ptr);
+#else
+ ret = vsnprintf(p, limit, format, arg_ptr);
+#endif
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
break;
@@ -301,7 +305,7 @@ string vstrprintf(const std::string &format, va_list ap)
return str;
}
-string real_strprintf(const std::string &format, int dummy, ...)
+string real_strprintf(const char *format, int dummy, ...)
{
va_list arg_ptr;
va_start(arg_ptr, dummy);
@@ -310,6 +314,15 @@ string real_strprintf(const std::string &format, int dummy, ...)
return str;
}
+string real_strprintf(const std::string &format, int dummy, ...)
+{
+ va_list arg_ptr;
+ va_start(arg_ptr, dummy);
+ string str = vstrprintf(format.c_str(), arg_ptr);
+ va_end(arg_ptr);
+ return str;
+}
+
bool error(const char *format, ...)
{
va_list arg_ptr;
@@ -411,7 +424,7 @@ bool ParseMoney(const char* pszIn, int64& nRet)
}
-static signed char phexdigit[256] =
+static const signed char phexdigit[256] =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
diff --git a/src/util.h b/src/util.h
index 2409ccb79c..54b53582b5 100644
--- a/src/util.h
+++ b/src/util.h
@@ -41,7 +41,6 @@ static const int64 CENT = 1000000;
#define UBEGIN(a) ((unsigned char*)&(a))
#define UEND(a) ((unsigned char*)&((&(a))[1]))
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
-#define printf OutputDebugStringF
#ifndef PRI64d
#if defined(_MSC_VER) || defined(__MSVCRT__)
@@ -55,6 +54,17 @@ static const int64 CENT = 1000000;
#endif
#endif
+/* Format characters for (s)size_t and ptrdiff_t */
+#if defined(_MSC_VER) || defined(__MSVCRT__)
+ #define PRIszx "%Ix"
+ #define PRIszu "%Iu"
+ #define PRIszd "%Id"
+#else
+ #define PRIszx "%zx"
+ #define PRIszu "%zu"
+ #define PRIszd "%zd"
+#endif
+
// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
#define PAIRTYPE(t1, t2) std::pair<t1, t2>
@@ -80,11 +90,7 @@ T* alignup(T* p)
#define S_IRUSR 0400
#define S_IWUSR 0200
#endif
-#define unlink _unlink
#else
-#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
-#define strlwr(psz) to_lower(psz)
-#define _strlwr(psz) to_lower(psz)
#define MAX_PATH 1024
inline void Sleep(int64 n)
{
@@ -94,6 +100,15 @@ inline void Sleep(int64 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(printf,X,Y)))
+#else
+#define ATTR_WARN_PRINTF(X,Y)
+#endif
@@ -121,16 +136,31 @@ extern bool fReopenDebugLog;
void RandAddSeed();
void RandAddSeedPerfmon();
-int OutputDebugStringF(const char* pszFormat, ...);
-int my_snprintf(char* buffer, size_t limit, const char* format, ...);
+int ATTR_WARN_PRINTF(1,2) OutputDebugStringF(const char* pszFormat, ...);
-/* 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.
+/*
+ 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.
+ */
std::string real_strprintf(const std::string &format, int dummy, ...);
#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__)
-std::string vstrprintf(const std::string &format, va_list ap);
+std::string vstrprintf(const char *format, va_list ap);
+
+/* Redefine printf so that it directs output to debug.log
+ *
+ * Do this *after* defining the other printf-like functions, because otherwise the
+ * __attribute__((format(printf,X,Y))) gets expanded to __attribute__((format(OutputDebugStringF,X,Y)))
+ * which confuses gcc.
+ */
+#define printf OutputDebugStringF
bool error(const char *format, ...);
void LogException(std::exception* pex, const char* pszThread);
@@ -237,9 +267,9 @@ inline int64 abs64(int64 n)
template<typename T>
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
{
- std::vector<char> rv;
- static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ std::string rv;
+ static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
rv.reserve((itend-itbegin)*3);
for(T it = itbegin; it < itend; ++it)
{
@@ -250,7 +280,7 @@ std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
rv.push_back(hexmap[val&15]);
}
- return std::string(rv.begin(), rv.end());
+ return rv;
}
inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)