From ba49a32c3a5b10bfe1ae90edd08f06acad0389fd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 16 Jan 2014 08:34:10 +0100 Subject: Another VarArgs fix. This time using va_copy() on platforms that have it and simple assignment on platforms that don't. --- lib/inifile/iniFile.cpp | 6 ++---- src/CommandOutput.cpp | 6 ++---- src/Log.cpp | 10 ++++------ src/Log.h | 2 +- src/OSSupport/File.cpp | 6 ++---- src/StringUtils.cpp | 44 ++++++++++++++++++++++++++------------------ src/StringUtils.h | 8 ++------ 7 files changed, 39 insertions(+), 43 deletions(-) diff --git a/lib/inifile/iniFile.cpp b/lib/inifile/iniFile.cpp index c118eecaa..afa1c110d 100644 --- a/lib/inifile/iniFile.cpp +++ b/lib/inifile/iniFile.cpp @@ -446,12 +446,10 @@ bool cIniFile::SetValueF(const AString & a_KeyName, const AString & a_ValueName, bool cIniFile::SetValueV(const AString & a_KeyName, const AString & a_ValueName, const char * a_Format, ...) { - va_list args, argsCopy; + va_list args; va_start(args, a_Format); - va_start(argsCopy, a_Format); AString Data; - AppendVPrintf(Data, a_Format, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(Data, a_Format, args); va_end(args); return SetValue(a_KeyName, a_ValueName, Data); } diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index 48a695969..c221682a1 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -16,11 +16,9 @@ void cCommandOutputCallback::Out(const char * a_Fmt, ...) { AString Output; - va_list args, argsCopy; + va_list args; va_start(args, a_Fmt); - va_start(argsCopy, a_Fmt); - AppendVPrintf(Output, a_Fmt, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(Output, a_Fmt, args); va_end(args); Output.append("\n"); Out(Output); diff --git a/src/Log.cpp b/src/Log.cpp index 8f811f14f..2d6be0f59 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -99,10 +99,10 @@ void cLog::ClearLog() -void cLog::Log(const char * a_Format, va_list argList, va_list argListCopy) +void cLog::Log(const char * a_Format, va_list argList) { AString Message; - AppendVPrintf(Message, a_Format, argList, argListCopy); + AppendVPrintf(Message, a_Format, argList); time_t rawtime; time ( &rawtime ); @@ -149,11 +149,9 @@ void cLog::Log(const char * a_Format, va_list argList, va_list argListCopy) void cLog::Log(const char * a_Format, ...) { - va_list argList, argListCopy; + va_list argList; va_start(argList, a_Format); - va_start(argListCopy, a_Format); - Log(a_Format, argList, argListCopy); - va_end(argListCopy); + Log(a_Format, argList); va_end(argList); } diff --git a/src/Log.h b/src/Log.h index d33fc2871..cba248dae 100644 --- a/src/Log.h +++ b/src/Log.h @@ -14,7 +14,7 @@ private: public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList, va_list argListCopy); + void Log(const char * a_Format, va_list argList); void Log(const char * a_Format, ...); // tolua_begin void SimpleLog(const char * a_String); diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index a55346c48..9f7c0d439 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -440,11 +440,9 @@ AString cFile::ReadWholeFile(const AString & a_FileName) int cFile::Printf(const char * a_Fmt, ...) { AString buf; - va_list args, argsCopy; + va_list args; va_start(args, a_Fmt); - va_start(argsCopy, a_Fmt); - AppendVPrintf(buf, a_Fmt, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(buf, a_Fmt, args); va_end(args); return Write(buf.c_str(), buf.length()); } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 16937c8a2..58101779a 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -14,39 +14,52 @@ #pragma comment(lib, "ws2_32.lib") #endif +// For platforms that don't have va_copy, define out own, simplistic one: +#ifndef va_copy + #define va_copy(dst, src) dst = src +#endif va_copy -AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list argsCopy) + +AString & AppendVPrintf(AString & str, const char *format, va_list args) { ASSERT(format != NULL); char buffer[2048]; size_t len; + va_list argsCopy; + va_copy(argsCopy, args); #ifdef _MSC_VER // MS CRT provides secure printf that doesn't behave like in the C99 standard - if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, args)) != -1) + if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, argsCopy)) != -1) #else // _MSC_VER - if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer)) + if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, argsCopy)) < ARRAYCOUNT(buffer)) #endif // else _MSC_VER { // The result did fit into the static buffer + va_end(argsCopy); str.append(buffer, len); return str; } + va_end(argsCopy); - // The result did not fit into the static buffer + // The result did not fit into the static buffer, use a dynamic buffer: #ifdef _MSC_VER // for MS CRT, we need to calculate the result length - len = _vscprintf(format, args); + va_copy(argsCopy, args); + len = _vscprintf(format, argsCopy); if (len == -1) { + va_end(argsCopy); return str; } + va_end(argsCopy); #endif // _MSC_VER // Allocate a buffer and printf into it: + va_copy(argsCopy, args); std::vector Buffer(len + 1); #ifdef _MSC_VER vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); @@ -54,6 +67,7 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); #endif // else _MSC_VER str.append(&(Buffer.front()), Buffer.size() - 1); + va_end(argsCopy); return str; } @@ -64,11 +78,9 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list AString & Printf(AString & str, const char * format, ...) { str.clear(); - va_list args, argsCopy; + va_list args; va_start(args, format); - va_start(argsCopy, format); - std::string &retval = AppendVPrintf(str, format, args, argsCopy); - va_end(argsCopy); + std::string &retval = AppendVPrintf(str, format, args); va_end(args); return retval; } @@ -80,11 +92,9 @@ AString & Printf(AString & str, const char * format, ...) AString Printf(const char * format, ...) { AString res; - va_list args, argsCopy; + va_list args; va_start(args, format); - va_start(argsCopy, format); - AppendVPrintf(res, format, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(res, format, args); va_end(args); return res; } @@ -93,13 +103,11 @@ AString Printf(const char * format, ...) -AString & AppendPrintf(AString &str, const char *format, ...) +AString & AppendPrintf(AString &str, const char * format, ...) { - va_list args, argsCopy; + va_list args; va_start(args, format); - va_start(argsCopy, format); - std::string &retval = AppendVPrintf(str, format, args, argsCopy); - va_end(argsCopy); + std::string &retval = AppendVPrintf(str, format, args); va_end(args); return retval; } diff --git a/src/StringUtils.h b/src/StringUtils.h index 35faeb01b..dfbfc2a75 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -21,12 +21,8 @@ typedef std::list AStringList; -/** Add the formated string to the existing data in the string -It is silly to need to specify the arguments twice, but it is required for x64 / GCC: -Ref.: issue #541, http://www.bailopan.net/blog/?p=30 -va_copy is not available until C++11, so we need to make do with passing a duplicate. -*/ -extern AString & AppendVPrintf(AString & str, const char * format, va_list args, va_list argsCopy); +/** Add the formated string to the existing data in the string */ +extern AString & AppendVPrintf(AString & str, const char * format, va_list args); /// Output the formatted text into the string extern AString & Printf (AString & str, const char * format, ...); -- cgit v1.2.3