Using a 2nd argument instead of va_copy().
This seems to be the only reasonable C++03-only solution.
This commit is contained in:
parent
3fd19df9fd
commit
dd6c5779ec
@ -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, ...)
|
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(args, a_Format);
|
||||||
|
va_start(argsCopy, a_Format);
|
||||||
AString Data;
|
AString Data;
|
||||||
AppendVPrintf(Data, a_Format, args);
|
AppendVPrintf(Data, a_Format, args, argsCopy);
|
||||||
|
va_end(argsCopy);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return SetValue(a_KeyName, a_ValueName, Data);
|
return SetValue(a_KeyName, a_ValueName, Data);
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,11 @@
|
|||||||
void cCommandOutputCallback::Out(const char * a_Fmt, ...)
|
void cCommandOutputCallback::Out(const char * a_Fmt, ...)
|
||||||
{
|
{
|
||||||
AString Output;
|
AString Output;
|
||||||
va_list args;
|
va_list args, argsCopy;
|
||||||
va_start(args, a_Fmt);
|
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);
|
va_end(args);
|
||||||
Output.append("\n");
|
Output.append("\n");
|
||||||
Out(Output);
|
Out(Output);
|
||||||
|
16
src/Log.cpp
16
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;
|
AString Message;
|
||||||
AppendVPrintf(Message, a_Format, argList);
|
AppendVPrintf(Message, a_Format, argList, argListCopy);
|
||||||
|
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
time ( &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);
|
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ private:
|
|||||||
public:
|
public:
|
||||||
cLog(const AString & a_FileName);
|
cLog(const AString & a_FileName);
|
||||||
~cLog();
|
~cLog();
|
||||||
void Log(const char* a_Format, va_list argList );
|
void Log(const char * a_Format, va_list argList, va_list argListCopy);
|
||||||
void Log(const char* a_Format, ...);
|
void Log(const char * a_Format, ...);
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
void SimpleLog(const char* a_String);
|
void SimpleLog(const char * a_String);
|
||||||
void OpenLog( const char* a_FileName );
|
void OpenLog(const char * a_FileName);
|
||||||
void CloseLog();
|
void CloseLog();
|
||||||
void ClearLog();
|
void ClearLog();
|
||||||
static cLog* GetInstance();
|
static cLog* GetInstance();
|
||||||
|
@ -440,9 +440,11 @@ AString cFile::ReadWholeFile(const AString & a_FileName)
|
|||||||
int cFile::Printf(const char * a_Fmt, ...)
|
int cFile::Printf(const char * a_Fmt, ...)
|
||||||
{
|
{
|
||||||
AString buf;
|
AString buf;
|
||||||
va_list args;
|
va_list args, argsCopy;
|
||||||
va_start(args, a_Fmt);
|
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);
|
va_end(args);
|
||||||
return Write(buf.c_str(), buf.length());
|
return Write(buf.c_str(), buf.length());
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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
|
// 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, args)) != -1)
|
||||||
#else // _MSC_VER
|
#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))
|
if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer))
|
||||||
#endif // else _MSC_VER
|
#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:
|
// Allocate a buffer and printf into it:
|
||||||
std::vector<char> Buffer(len + 1);
|
std::vector<char> Buffer(len + 1);
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, args);
|
vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, argsCopy);
|
||||||
#else // _MSC_VER
|
#else // _MSC_VER
|
||||||
vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, args2);
|
vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, argsCopy);
|
||||||
#endif // else _MSC_VER
|
#endif // else _MSC_VER
|
||||||
str.append(&(Buffer.front()), Buffer.size() - 1);
|
str.append(&(Buffer.front()), Buffer.size() - 1);
|
||||||
return str;
|
return str;
|
||||||
@ -68,9 +64,11 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args)
|
|||||||
AString & Printf(AString & str, const char * format, ...)
|
AString & Printf(AString & str, const char * format, ...)
|
||||||
{
|
{
|
||||||
str.clear();
|
str.clear();
|
||||||
va_list args;
|
va_list args, argsCopy;
|
||||||
va_start(args, format);
|
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);
|
va_end(args);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -82,9 +80,11 @@ AString & Printf(AString & str, const char * format, ...)
|
|||||||
AString Printf(const char * format, ...)
|
AString Printf(const char * format, ...)
|
||||||
{
|
{
|
||||||
AString res;
|
AString res;
|
||||||
va_list args;
|
va_list args, argsCopy;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
AppendVPrintf(res, format, args);
|
va_start(argsCopy, format);
|
||||||
|
AppendVPrintf(res, format, args, argsCopy);
|
||||||
|
va_end(argsCopy);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -95,9 +95,11 @@ AString Printf(const char * format, ...)
|
|||||||
|
|
||||||
AString & AppendPrintf(AString &str, const char *format, ...)
|
AString & AppendPrintf(AString &str, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args, argsCopy;
|
||||||
va_start(args, format);
|
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);
|
va_end(args);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,12 @@ typedef std::list<AString> AStringList;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Add the formated string to the existing data in the string
|
/** Add the formated string to the existing data in the string
|
||||||
extern AString & AppendVPrintf(AString & str, const char * format, va_list args);
|
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
|
/// Output the formatted text into the string
|
||||||
extern AString & Printf (AString & str, const char * format, ...);
|
extern AString & Printf (AString & str, const char * format, ...);
|
||||||
|
Loading…
Reference in New Issue
Block a user