diff --git a/headers/os/support/String.h b/headers/os/support/String.h index 005fcd219a..4ce0d13729 100644 --- a/headers/os/support/String.h +++ b/headers/os/support/String.h @@ -6,10 +6,11 @@ #define __BSTRING__ -#include -#include +#include #include +#include + class BStringList; class BStringRef; @@ -55,6 +56,8 @@ public: BString& AdoptChars(BString& from, int32 charCount); BString& SetToFormat(const char* format, ...); + BString& SetToFormatVarArgs(const char* format, + va_list args); // Substring copying BString& CopyInto(BString& into, int32 fromOffset, diff --git a/src/kits/support/String.cpp b/src/kits/support/String.cpp index 7bc0751d56..e29e082464 100644 --- a/src/kits/support/String.cpp +++ b/src/kits/support/String.cpp @@ -428,13 +428,31 @@ BString::AdoptChars(BString& string, int32 charCount) BString& BString::SetToFormat(const char* format, ...) { + va_list args; + va_start(args, format); + SetToFormatVarArgs(format, args); + va_end(args); + + return *this; +} + + +BString& +BString::SetToFormatVarArgs(const char* format, va_list args) +{ + // Use a small on-stack buffer to save a second vsnprintf() call for most + // use cases. int32 bufferSize = 1024; char buffer[bufferSize]; - va_list arg; - va_start(arg, format); - int32 bytes = vsnprintf(buffer, bufferSize, format, arg); - va_end(arg); + va_list clonedArgs; +#if __GNUC__ == 2 + __va_copy(clonedArgs, args); +#else + va_copy(clonedArgs, args); +#endif + int32 bytes = vsnprintf(buffer, bufferSize, format, clonedArgs); + va_end(clonedArgs); if (bytes < 0) return Truncate(0); @@ -444,11 +462,7 @@ BString::SetToFormat(const char* format, ...) return *this; } - va_list arg2; - va_start(arg2, format); - bytes = vsnprintf(LockBuffer(bytes), bytes + 1, format, arg2); - va_end(arg2); - + bytes = vsnprintf(LockBuffer(bytes), bytes + 1, format, args); if (bytes < 0) bytes = 0;