From e792adb1b889580fa198d56e16f9098fd4227bb0 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 18 Mar 2011 14:30:57 +0100 Subject: COMMON: Add vformat() function (Common::String analog to vsprintf) --- common/scummsys.h | 13 +++++++++++++ common/str.cpp | 20 +++++++++++++++----- common/str.h | 13 ++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/common/scummsys.h b/common/scummsys.h index a425befecf..9d4b6a9677 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -302,6 +302,19 @@ #define MAXPATHLEN 256 #endif +#ifndef scumm_va_copy + #if defined(va_copy) + #define scumm_va_copy va_copy + #elif defined(__va_copy) + #define scumm_va_copy __va_copy + #elif defined(_MSC_VER) + #define scumm_va_copy(dst, src) ((dst) = (src)) + #else + #error scumm_va_copy undefined for this port + #endif +#endif + + // // Typedef our system types unless they have already been defined by config.h, diff --git a/common/str.cpp b/common/str.cpp index 223188bdd6..a2cd4a0193 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -25,8 +25,6 @@ #include "common/str.h" #include "common/util.h" -#include - namespace Common { MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now @@ -429,10 +427,22 @@ uint String::hash() const { // static String String::format(const char *fmt, ...) { String output; - assert(output.isStorageIntern()); va_list va; va_start(va, fmt); + output = String::vformat(fmt, va); + va_end(va); + + return output; +} + +// static +String String::vformat(const char *fmt, va_list args) { + String output; + assert(output.isStorageIntern()); + + va_list va; + scumm_va_copy(va, args); int len = vsnprintf(output._str, _builtinCapacity, fmt, va); va_end(va); @@ -457,7 +467,7 @@ String String::format(const char *fmt, ...) { assert(!output.isStorageIntern()); size = output._extern._capacity; - va_start(va, fmt); + scumm_va_copy(va, args); len = vsnprintf(output._str, size, fmt, va); va_end(va); } while (len == -1 || len >= size - 1); @@ -468,7 +478,7 @@ String String::format(const char *fmt, ...) { } else { // vsnprintf didn't have enough space, so grow buffer output.ensureCapacity(len, false); - va_start(va, fmt); + scumm_va_copy(va, args); int len2 = vsnprintf(output._str, len+1, fmt, va); va_end(va); assert(len == len2); diff --git a/common/str.h b/common/str.h index 7b97dfe945..8e07b6233d 100644 --- a/common/str.h +++ b/common/str.h @@ -24,6 +24,8 @@ #include "common/scummsys.h" +#include + namespace Common { /** @@ -213,10 +215,19 @@ public: uint hash() const; /** - * Printf-like function. Returns a formatted String. + * Print formatted data into a String object. Similar to sprintf, + * except that it stores the result in (variably sized) String + * instead of a fixed size buffer. */ static Common::String format(const char *fmt, ...) GCC_PRINTF(1,2); + /** + * Print formatted data into a String object. Similar to vsprintf, + * except that it stores the result in (variably sized) String + * instead of a fixed size buffer. + */ + static Common::String vformat(const char *fmt, va_list args); + public: typedef char * iterator; typedef const char * const_iterator; -- cgit v1.2.3