Get rid of snprintf (except one) with fixed buffers, shorten code

- Use strprintf or vstrprintf instead of snprintf
This commit is contained in:
Wladimir J. van der Laan 2012-05-14 19:53:02 +02:00
parent a6f18e4686
commit 29b79e4c0e
2 changed files with 37 additions and 81 deletions

View File

@ -180,8 +180,6 @@ int GetRandInt(int nMax)
inline int OutputDebugStringF(const char* pszFormat, ...) inline int OutputDebugStringF(const char* pszFormat, ...)
{ {
int ret = 0; int ret = 0;
@ -228,68 +226,30 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
{ {
static CCriticalSection cs_OutputDebugStringF; static CCriticalSection cs_OutputDebugStringF;
// accumulate a line at a time // accumulate and output a line at a time
{ {
LOCK(cs_OutputDebugStringF); LOCK(cs_OutputDebugStringF);
static char pszBuffer[50000]; static std::string buffer;
static char* pend;
if (pend == NULL)
pend = pszBuffer;
va_list arg_ptr; va_list arg_ptr;
va_start(arg_ptr, pszFormat); va_start(arg_ptr, pszFormat);
int limit = END(pszBuffer) - pend - 2; buffer += vstrprintf(pszFormat, arg_ptr);
int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
va_end(arg_ptr); va_end(arg_ptr);
if (ret < 0 || ret >= limit)
int line_start = 0, line_end;
while((line_end = buffer.find('\n', line_start)) != -1)
{ {
pend = END(pszBuffer) - 2; OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
*pend++ = '\n'; line_start = line_end + 1;
} }
else buffer.erase(0, line_start);
pend += ret;
*pend = '\0';
char* p1 = pszBuffer;
char* p2;
while ((p2 = strchr(p1, '\n')))
{
p2++;
char c = *p2;
*p2 = '\0';
OutputDebugStringA(p1);
*p2 = c;
p1 = p2;
}
if (p1 != pszBuffer)
memmove(pszBuffer, p1, pend - p1 + 1);
pend -= (p1 - pszBuffer);
} }
} }
#endif #endif
return ret; return ret;
} }
string vstrprintf(const std::string &format, va_list ap)
// Safer snprintf
// - prints up to limit-1 characters
// - output string is always null terminated even if limit reached
// - return value is the number of characters actually printed
int my_snprintf(char* buffer, size_t limit, const char* format, ...)
{
if (limit == 0)
return 0;
va_list arg_ptr;
va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= (int)limit)
{
ret = limit - 1;
buffer[limit-1] = 0;
}
return ret;
}
string real_strprintf(const std::string &format, int dummy, ...)
{ {
char buffer[50000]; char buffer[50000];
char* p = buffer; char* p = buffer;
@ -298,7 +258,7 @@ string real_strprintf(const std::string &format, int dummy, ...)
loop loop
{ {
va_list arg_ptr; va_list arg_ptr;
va_start(arg_ptr, dummy); va_copy(arg_ptr, ap);
ret = _vsnprintf(p, limit, format.c_str(), arg_ptr); ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
va_end(arg_ptr); va_end(arg_ptr);
if (ret >= 0 && ret < limit) if (ret >= 0 && ret < limit)
@ -316,19 +276,22 @@ 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, arg_ptr);
va_end(arg_ptr);
return str;
}
bool error(const char *format, ...) bool error(const char *format, ...)
{ {
char buffer[50000];
int limit = sizeof(buffer);
va_list arg_ptr; va_list arg_ptr;
va_start(arg_ptr, format); va_start(arg_ptr, format);
int ret = _vsnprintf(buffer, limit, format, arg_ptr); std::string str = vstrprintf(format, arg_ptr);
va_end(arg_ptr); va_end(arg_ptr);
if (ret < 0 || ret >= limit) printf("ERROR: %s\n", str.c_str());
{
buffer[limit - 1] = 0;
}
printf("ERROR: %s\n", buffer);
return false; return false;
} }
@ -756,7 +719,7 @@ bool WildcardMatch(const string& str, const string& mask)
void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) static std::string FormatException(std::exception* pex, const char* pszThread)
{ {
#ifdef WIN32 #ifdef WIN32
char pszModule[MAX_PATH] = ""; char pszModule[MAX_PATH] = "";
@ -765,37 +728,34 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea
const char* pszModule = "bitcoin"; const char* pszModule = "bitcoin";
#endif #endif
if (pex) if (pex)
snprintf(pszMessage, 1000, return strprintf(
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
else else
snprintf(pszMessage, 1000, return strprintf(
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
} }
void LogException(std::exception* pex, const char* pszThread) void LogException(std::exception* pex, const char* pszThread)
{ {
char pszMessage[10000]; std::string message = FormatException(pex, pszThread);
FormatException(pszMessage, pex, pszThread); printf("\n%s", message.c_str());
printf("\n%s", pszMessage);
} }
void PrintException(std::exception* pex, const char* pszThread) void PrintException(std::exception* pex, const char* pszThread)
{ {
char pszMessage[10000]; std::string message = FormatException(pex, pszThread);
FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", message.c_str());
printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
fprintf(stderr, "\n\n************************\n%s\n", pszMessage); strMiscWarning = message;
strMiscWarning = pszMessage;
throw; throw;
} }
void PrintExceptionContinue(std::exception* pex, const char* pszThread) void PrintExceptionContinue(std::exception* pex, const char* pszThread)
{ {
char pszMessage[10000]; std::string message = FormatException(pex, pszThread);
FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", message.c_str());
printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
fprintf(stderr, "\n\n************************\n%s\n", pszMessage); strMiscWarning = message;
strMiscWarning = pszMessage;
} }
boost::filesystem::path GetDefaultDataDir() boost::filesystem::path GetDefaultDataDir()

View File

@ -43,11 +43,6 @@ static const int64 CENT = 1000000;
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
#define printf OutputDebugStringF #define printf OutputDebugStringF
#ifdef snprintf
#undef snprintf
#endif
#define snprintf my_snprintf
#ifndef PRI64d #ifndef PRI64d
#if defined(_MSC_VER) || defined(__MSVCRT__) #if defined(_MSC_VER) || defined(__MSVCRT__)
#define PRI64d "I64d" #define PRI64d "I64d"
@ -133,6 +128,7 @@ int my_snprintf(char* buffer, size_t limit, const char* format, ...);
*/ */
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);
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);