diff options
Diffstat (limited to 'src/util.h')
-rw-r--r-- | src/util.h | 86 |
1 files changed, 56 insertions, 30 deletions
diff --git a/src/util.h b/src/util.h index 2409ccb79c..d80b3c28b2 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,26 @@ static const int64 CENT = 1000000; #endif #endif +/* Format characters for (s)size_t and ptrdiff_t */ +#if defined(_MSC_VER) || defined(__MSVCRT__) + /* (s)size_t and ptrdiff_t have the same size specifier in MSVC: + http://msdn.microsoft.com/en-us/library/tcxf1dw6%28v=vs.100%29.aspx + */ + #define PRIszx "Ix" + #define PRIszu "Iu" + #define PRIszd "Id" + #define PRIpdx "Ix" + #define PRIpdu "Iu" + #define PRIpdd "Id" +#else /* C99 standard */ + #define PRIszx "zx" + #define PRIszu "zu" + #define PRIszd "zd" + #define PRIpdx "tx" + #define PRIpdu "tu" + #define PRIpdd "td" +#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 +99,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 +109,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,18 +145,34 @@ 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); + +bool ATTR_WARN_PRINTF(1,2) error(const char *format, ...); + +/* 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); void PrintException(std::exception* pex, const char* pszThread); void PrintExceptionContinue(std::exception* pex, const char* pszThread); @@ -237,9 +277,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 +290,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) @@ -366,20 +406,6 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue); -// Randomize the stack to help protect against buffer overrun exploits -#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ - { \ - static char nLoops; \ - if (nLoops <= 0) \ - nLoops = GetRand(20) + 1; \ - if (nLoops-- > 1) \ - { \ - ThreadFn; \ - return; \ - } \ - } - - template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend) { |