mirror of
https://github.com/libretro/scummvm.git
synced 2025-05-13 17:46:22 +00:00
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
This commit is contained in:
parent
96e19382b9
commit
426d6749cf
@ -439,12 +439,20 @@ String String::printf(const char *fmt, ...) {
|
|||||||
int len = vsnprintf(output._str, _builtinCapacity, fmt, va);
|
int len = vsnprintf(output._str, _builtinCapacity, fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
if (len == -1) {
|
if (len == -1 || len == _builtinCapacity - 1) {
|
||||||
// MSVC doesn't return the size the full string would take up.
|
// MSVC and IRIX don't return the size the full string would take up.
|
||||||
// Try increasing the size of the string until it fits.
|
// 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
|
// We assume MSVC failed to output the correct, null-terminated string
|
||||||
// if the return value is either -1 or size.
|
// 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;
|
int size = _builtinCapacity;
|
||||||
do {
|
do {
|
||||||
size *= 2;
|
size *= 2;
|
||||||
@ -455,7 +463,7 @@ String String::printf(const char *fmt, ...) {
|
|||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
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);
|
} while (len == -1 || len >= size - 1);
|
||||||
output._size = len;
|
output._size = len;
|
||||||
} else if (len < (int)_builtinCapacity) {
|
} else if (len < (int)_builtinCapacity) {
|
||||||
// vsnprintf succeeded
|
// vsnprintf succeeded
|
||||||
|
Loading…
x
Reference in New Issue
Block a user