Merge pull request #1807 from laanwj/2012_09_printf_warnings
Add printf-style warnings to strprintf() and OutputDebugStringF()
This commit is contained in:
commit
5a1a362215
4 changed files with 64 additions and 21 deletions
|
@ -305,7 +305,7 @@ public:
|
||||||
psz++;
|
psz++;
|
||||||
|
|
||||||
// hex string to bignum
|
// 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;
|
*this = 0;
|
||||||
while (isxdigit(*psz))
|
while (isxdigit(*psz))
|
||||||
{
|
{
|
||||||
|
|
|
@ -306,7 +306,7 @@ public:
|
||||||
psz += 2;
|
psz += 2;
|
||||||
|
|
||||||
// hex string to uint
|
// 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;
|
const char* pbegin = psz;
|
||||||
while (phexdigit[(unsigned char)*psz] || *psz == '0')
|
while (phexdigit[(unsigned char)*psz] || *psz == '0')
|
||||||
psz++;
|
psz++;
|
||||||
|
|
21
src/util.cpp
21
src/util.cpp
|
@ -274,7 +274,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
string vstrprintf(const std::string &format, va_list ap)
|
string vstrprintf(const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
char buffer[50000];
|
char buffer[50000];
|
||||||
char* p = buffer;
|
char* p = buffer;
|
||||||
|
@ -284,7 +284,11 @@ string vstrprintf(const std::string &format, va_list ap)
|
||||||
{
|
{
|
||||||
va_list arg_ptr;
|
va_list arg_ptr;
|
||||||
va_copy(arg_ptr, ap);
|
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);
|
va_end(arg_ptr);
|
||||||
if (ret >= 0 && ret < limit)
|
if (ret >= 0 && ret < limit)
|
||||||
break;
|
break;
|
||||||
|
@ -301,7 +305,7 @@ string vstrprintf(const std::string &format, va_list ap)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
string real_strprintf(const std::string &format, int dummy, ...)
|
string real_strprintf(const char *format, int dummy, ...)
|
||||||
{
|
{
|
||||||
va_list arg_ptr;
|
va_list arg_ptr;
|
||||||
va_start(arg_ptr, dummy);
|
va_start(arg_ptr, dummy);
|
||||||
|
@ -310,6 +314,15 @@ string real_strprintf(const std::string &format, int dummy, ...)
|
||||||
return str;
|
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, ...)
|
bool error(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list arg_ptr;
|
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,
|
-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,
|
||||||
|
|
54
src/util.h
54
src/util.h
|
@ -41,7 +41,6 @@ static const int64 CENT = 1000000;
|
||||||
#define UBEGIN(a) ((unsigned char*)&(a))
|
#define UBEGIN(a) ((unsigned char*)&(a))
|
||||||
#define UEND(a) ((unsigned char*)&((&(a))[1]))
|
#define UEND(a) ((unsigned char*)&((&(a))[1]))
|
||||||
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
|
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
|
||||||
#define printf OutputDebugStringF
|
|
||||||
|
|
||||||
#ifndef PRI64d
|
#ifndef PRI64d
|
||||||
#if defined(_MSC_VER) || defined(__MSVCRT__)
|
#if defined(_MSC_VER) || defined(__MSVCRT__)
|
||||||
|
@ -55,6 +54,17 @@ static const int64 CENT = 1000000;
|
||||||
#endif
|
#endif
|
||||||
#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>
|
// 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>
|
#define PAIRTYPE(t1, t2) std::pair<t1, t2>
|
||||||
|
|
||||||
|
@ -80,11 +90,7 @@ T* alignup(T* p)
|
||||||
#define S_IRUSR 0400
|
#define S_IRUSR 0400
|
||||||
#define S_IWUSR 0200
|
#define S_IWUSR 0200
|
||||||
#endif
|
#endif
|
||||||
#define unlink _unlink
|
|
||||||
#else
|
#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
|
#define MAX_PATH 1024
|
||||||
inline void Sleep(int64 n)
|
inline void Sleep(int64 n)
|
||||||
{
|
{
|
||||||
|
@ -94,6 +100,15 @@ inline void Sleep(int64 n)
|
||||||
}
|
}
|
||||||
#endif
|
#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 RandAddSeed();
|
||||||
void RandAddSeedPerfmon();
|
void RandAddSeedPerfmon();
|
||||||
int OutputDebugStringF(const char* pszFormat, ...);
|
int ATTR_WARN_PRINTF(1,2) OutputDebugStringF(const char* pszFormat, ...);
|
||||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
|
||||||
|
|
||||||
/* It is not allowed to use va_start with a pass-by-reference argument.
|
/*
|
||||||
|
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
|
(C++ standard, 18.7, paragraph 3). Use a dummy argument to work around this, and use a
|
||||||
macro to keep similar semantics.
|
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, ...);
|
std::string real_strprintf(const std::string &format, int dummy, ...);
|
||||||
#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__)
|
#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, ...);
|
bool error(const char *format, ...);
|
||||||
void LogException(std::exception* pex, const char* pszThread);
|
void LogException(std::exception* pex, const char* pszThread);
|
||||||
|
@ -237,8 +267,8 @@ inline int64 abs64(int64 n)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
||||||
{
|
{
|
||||||
std::vector<char> rv;
|
std::string rv;
|
||||||
static char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||||
rv.reserve((itend-itbegin)*3);
|
rv.reserve((itend-itbegin)*3);
|
||||||
for(T it = itbegin; it < itend; ++it)
|
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]);
|
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)
|
inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
|
||||||
|
|
Loading…
Reference in a new issue