COMMON: Add vformat() function (Common::String analog to vsprintf)

This commit is contained in:
Max Horn 2011-03-18 14:30:57 +01:00
parent 0881f54a06
commit e792adb1b8
3 changed files with 40 additions and 6 deletions

View file

@ -302,6 +302,19 @@
#define MAXPATHLEN 256 #define MAXPATHLEN 256
#endif #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, // Typedef our system types unless they have already been defined by config.h,

View file

@ -25,8 +25,6 @@
#include "common/str.h" #include "common/str.h"
#include "common/util.h" #include "common/util.h"
#include <stdarg.h>
namespace Common { namespace Common {
MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now MemoryPool *g_refCountPool = 0; // FIXME: This is never freed right now
@ -429,10 +427,22 @@ uint String::hash() const {
// static // static
String String::format(const char *fmt, ...) { String String::format(const char *fmt, ...) {
String output; String output;
assert(output.isStorageIntern());
va_list va; va_list va;
va_start(va, fmt); 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); int len = vsnprintf(output._str, _builtinCapacity, fmt, va);
va_end(va); va_end(va);
@ -457,7 +467,7 @@ String String::format(const char *fmt, ...) {
assert(!output.isStorageIntern()); assert(!output.isStorageIntern());
size = output._extern._capacity; size = output._extern._capacity;
va_start(va, fmt); scumm_va_copy(va, args);
len = vsnprintf(output._str, size, fmt, va); len = vsnprintf(output._str, size, fmt, va);
va_end(va); va_end(va);
} while (len == -1 || len >= size - 1); } while (len == -1 || len >= size - 1);
@ -468,7 +478,7 @@ String String::format(const char *fmt, ...) {
} else { } else {
// vsnprintf didn't have enough space, so grow buffer // vsnprintf didn't have enough space, so grow buffer
output.ensureCapacity(len, false); output.ensureCapacity(len, false);
va_start(va, fmt); scumm_va_copy(va, args);
int len2 = vsnprintf(output._str, len+1, fmt, va); int len2 = vsnprintf(output._str, len+1, fmt, va);
va_end(va); va_end(va);
assert(len == len2); assert(len == len2);

View file

@ -24,6 +24,8 @@
#include "common/scummsys.h" #include "common/scummsys.h"
#include <stdarg.h>
namespace Common { namespace Common {
/** /**
@ -213,10 +215,19 @@ public:
uint hash() const; 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); 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: public:
typedef char * iterator; typedef char * iterator;
typedef const char * const_iterator; typedef const char * const_iterator;