diff options
author | Joost Peters | 2010-10-10 22:36:03 +0000 |
---|---|---|
committer | Joost Peters | 2010-10-10 22:36:03 +0000 |
commit | 426d6749cf534dec673e958f98711ac64a04f9a6 (patch) | |
tree | dd09f995510107a8639a1d350048be3f3139497f /common | |
parent | 96e19382b97846e9faeccba46bf1300a6fc06baa (diff) | |
download | scummvm-rg350-426d6749cf534dec673e958f98711ac64a04f9a6.tar.gz scummvm-rg350-426d6749cf534dec673e958f98711ac64a04f9a6.tar.bz2 scummvm-rg350-426d6749cf534dec673e958f98711ac64a04f9a6.zip |
COMMON: work around different vsnprintf behaviour on IRIX
The return value of vsnprintf when the provided buffer is not large
enough to hold the formatted string is implementation-dependent:
C99: The size the formatted string would take up.
MSVC: -1, with no indication of how large the buffer should be.
IRIX: The number of characters actually written, which is at most
the size of the buffer minus one, as the string is truncated
to fit. This means the only way to be sure the entire string
is written is if the return value is less than the capacity - 1.
This change means that whenever we try to format a string where the size
is 1 below the built-in capacity, that the capacity will be needlessly increased.
If this turns out to be problematic we could make this behaviour __sgi conditional.
svn-id: r53143
Diffstat (limited to 'common')
-rw-r--r-- | common/str.cpp | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/common/str.cpp b/common/str.cpp index 4585905d62..c3c19adfe6 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -439,12 +439,20 @@ String String::printf(const char *fmt, ...) { int len = vsnprintf(output._str, _builtinCapacity, fmt, va); va_end(va); - if (len == -1) { - // MSVC doesn't return the size the full string would take up. - // Try increasing the size of the string until it fits. + if (len == -1 || len == _builtinCapacity - 1) { + // MSVC and IRIX don't return the size the full string would take up. + // MSVC returns -1, IRIX returns the number of characters actually written, + // which is at the most the size of the buffer minus one, as the string is + // truncated to fit. // We assume MSVC failed to output the correct, null-terminated string // if the return value is either -1 or size. + // For IRIX, because we lack a better mechanism, we assume failure + // if the return value equals size - 1. + // The downside to this is that whenever we try to format a string where the + // size is 1 below the built-in capacity, the size is needlessly increased. + + // Try increasing the size of the string until it fits. int size = _builtinCapacity; do { size *= 2; @@ -455,7 +463,7 @@ String String::printf(const char *fmt, ...) { va_start(va, fmt); len = vsnprintf(output._str, size, fmt, va); va_end(va); - } while (len == -1 || len >= size); + } while (len == -1 || len >= size - 1); output._size = len; } else if (len < (int)_builtinCapacity) { // vsnprintf succeeded |