diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index de67c6e43..e91b9935e 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -249,10 +249,12 @@ void cConnection::Run(void) void cConnection::Log(const char * a_Format, ...) { - va_list args; + va_list args, argsCopy; va_start(args, a_Format); + va_start(argsCopy, a_Format); AString msg; - AppendVPrintf(msg, a_Format, args); + AppendVPrintf(msg, a_Format, args, argsCopy); + va_end(argsCopy); va_end(args); AString FullMsg; Printf(FullMsg, "[%5.3f] %s\n", GetRelativeTime(), msg.c_str()); @@ -274,10 +276,12 @@ void cConnection::Log(const char * a_Format, ...) void cConnection::DataLog(const void * a_Data, int a_Size, const char * a_Format, ...) { - va_list args; + va_list args, argsCopy; va_start(args, a_Format); + va_start(argsCopy, a_Format); AString msg; - AppendVPrintf(msg, a_Format, args); + AppendVPrintf(msg, a_Format, args, argsCopy); + va_end(argsCopy); va_end(args); AString FullMsg; AString Hex; diff --git a/lib/inifile/iniFile.cpp b/lib/inifile/iniFile.cpp index afa1c110d..c118eecaa 100644 --- a/lib/inifile/iniFile.cpp +++ b/lib/inifile/iniFile.cpp @@ -446,10 +446,12 @@ 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; + va_list args, argsCopy; va_start(args, a_Format); + va_start(argsCopy, a_Format); AString Data; - AppendVPrintf(Data, a_Format, args); + AppendVPrintf(Data, a_Format, args, argsCopy); + va_end(argsCopy); va_end(args); return SetValue(a_KeyName, a_ValueName, Data); } diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index c221682a1..48a695969 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -16,9 +16,11 @@ void cCommandOutputCallback::Out(const char * a_Fmt, ...) { AString Output; - va_list args; + va_list args, argsCopy; va_start(args, a_Fmt); - AppendVPrintf(Output, a_Fmt, args); + va_start(argsCopy, a_Fmt); + AppendVPrintf(Output, a_Fmt, args, argsCopy); + va_end(argsCopy); va_end(args); Output.append("\n"); Out(Output); diff --git a/src/Log.cpp b/src/Log.cpp index a0de4531b..8f811f14f 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) +void cLog::Log(const char * a_Format, va_list argList, va_list argListCopy) { AString Message; - AppendVPrintf(Message, a_Format, argList); + AppendVPrintf(Message, a_Format, argList, argListCopy); time_t rawtime; time ( &rawtime ); @@ -147,11 +147,13 @@ void cLog::Log(const char * a_Format, va_list argList) -void cLog::Log(const char* a_Format, ...) +void cLog::Log(const char * a_Format, ...) { - va_list argList; + va_list argList, argListCopy; va_start(argList, a_Format); - Log( a_Format, argList ); + va_start(argListCopy, a_Format); + Log(a_Format, argList, argListCopy); + va_end(argListCopy); va_end(argList); } @@ -159,9 +161,9 @@ void cLog::Log(const char* a_Format, ...) -void cLog::SimpleLog(const char* a_String) +void cLog::SimpleLog(const char * a_String) { - Log("%s", a_String ); + Log("%s", a_String); } diff --git a/src/Log.h b/src/Log.h index d00022c6f..d33fc2871 100644 --- a/src/Log.h +++ b/src/Log.h @@ -14,11 +14,11 @@ private: public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char* a_Format, va_list argList ); - void Log(const char* a_Format, ...); + void Log(const char * a_Format, va_list argList, va_list argListCopy); + void Log(const char * a_Format, ...); // tolua_begin - void SimpleLog(const char* a_String); - void OpenLog( const char* a_FileName ); + void SimpleLog(const char * a_String); + void OpenLog(const char * a_FileName); void CloseLog(); void ClearLog(); static cLog* GetInstance(); diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 9f7c0d439..a55346c48 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -440,9 +440,11 @@ AString cFile::ReadWholeFile(const AString & a_FileName) int cFile::Printf(const char * a_Fmt, ...) { AString buf; - va_list args; + va_list args, argsCopy; va_start(args, a_Fmt); - AppendVPrintf(buf, a_Fmt, args); + va_start(argsCopy, a_Fmt); + AppendVPrintf(buf, a_Fmt, args, argsCopy); + va_end(argsCopy); va_end(args); return Write(buf.c_str(), buf.length()); } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 2dcd9fec9..16937c8a2 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -18,7 +18,7 @@ -AString & AppendVPrintf(AString & str, const char *format, va_list args) +AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list argsCopy) { ASSERT(format != NULL); @@ -28,10 +28,6 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args) // 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) #else // _MSC_VER - // We need to store a copy of the args, because on AMD64 in GCC the vsnprintf() is allowed to make changes to it (WTF?) - // Ref.: issue #541, http://www.bailopan.net/blog/?p=30 - va_list args2; - va_copy(args2, args); if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer)) #endif // else _MSC_VER { @@ -53,9 +49,9 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args) // Allocate a buffer and printf into it: std::vector Buffer(len + 1); #ifdef _MSC_VER - vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, args); + vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); #else // _MSC_VER - vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, args2); + vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); #endif // else _MSC_VER str.append(&(Buffer.front()), Buffer.size() - 1); return str; @@ -68,9 +64,11 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args) AString & Printf(AString & str, const char * format, ...) { str.clear(); - va_list args; + va_list args, argsCopy; va_start(args, format); - std::string &retval = AppendVPrintf(str, format, args); + va_start(argsCopy, format); + std::string &retval = AppendVPrintf(str, format, args, argsCopy); + va_end(argsCopy); va_end(args); return retval; } @@ -82,9 +80,11 @@ AString & Printf(AString & str, const char * format, ...) AString Printf(const char * format, ...) { AString res; - va_list args; + va_list args, argsCopy; va_start(args, format); - AppendVPrintf(res, format, args); + va_start(argsCopy, format); + AppendVPrintf(res, format, args, argsCopy); + va_end(argsCopy); va_end(args); return res; } @@ -95,9 +95,11 @@ AString Printf(const char * format, ...) AString & AppendPrintf(AString &str, const char *format, ...) { - va_list args; + va_list args, argsCopy; va_start(args, format); - std::string &retval = AppendVPrintf(str, format, args); + va_start(argsCopy, format); + std::string &retval = AppendVPrintf(str, format, args, argsCopy); + va_end(argsCopy); va_end(args); return retval; } diff --git a/src/StringUtils.h b/src/StringUtils.h index 2373f3843..35faeb01b 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -21,8 +21,12 @@ typedef std::list AStringList; -/// Add the formated string to the existing data in the string -extern AString & AppendVPrintf(AString & str, const char * format, va_list args); +/** 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); /// Output the formatted text into the string extern AString & Printf (AString & str, const char * format, ...);