The return value of SDL_snprintf is the number of characters that would have been written.

Fixes https://github.com/libsdl-org/SDL/issues/4762
This commit is contained in:
Sam Lantinga 2021-09-22 11:42:10 -07:00
parent 9b74623be9
commit 79b0aae86c
2 changed files with 95 additions and 107 deletions

View File

@ -1472,6 +1472,8 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *f
return vsnprintf(text, maxlen, fmt, ap); return vsnprintf(text, maxlen, fmt, ap);
} }
#else #else
#define TEXT_AND_LEN_ARGS (length < maxlen) ? &text[length] : NULL, (length < maxlen) ? (maxlen - length) : 0
/* FIXME: implement more of the format specifiers */ /* FIXME: implement more of the format specifiers */
typedef enum typedef enum
{ {
@ -1514,27 +1516,29 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str
filllen = SDL_min(width, maxlen); filllen = SDL_min(width, maxlen);
SDL_memset(text, fill, filllen); SDL_memset(text, fill, filllen);
text += filllen; text += filllen;
length += filllen;
maxlen -= filllen; maxlen -= filllen;
length += width;
} }
slen = SDL_strlcpy(text, string, maxlen); SDL_strlcpy(text, string, maxlen);
length += SDL_min(slen, maxlen); length += sz;
if (info) { if (info) {
if (info->precision >= 0 && (size_t)info->precision < sz) { if (info->precision >= 0 && (size_t)info->precision < sz) {
slen = (size_t)info->precision; slen = (size_t)info->precision;
if (slen < maxlen) { if (slen < maxlen) {
text[slen] = 0; text[slen] = '\0';
}
length -= (sz - slen); length -= (sz - slen);
} }
} if (maxlen > 1) {
if (info->force_case == SDL_CASE_LOWER) { if (info->force_case == SDL_CASE_LOWER) {
SDL_strlwr(text); SDL_strlwr(text);
} else if (info->force_case == SDL_CASE_UPPER) { } else if (info->force_case == SDL_CASE_UPPER) {
SDL_strupr(text); SDL_strupr(text);
} }
} }
}
return length; return length;
} }
@ -1585,7 +1589,7 @@ SDL_PrintLong(char *text, size_t maxlen, SDL_FormatInfo *info, long value)
} }
SDL_ltoa(value, p, info ? info->radix : 10); SDL_ltoa(value, p, info ? info->radix : 10);
SDL_IntPrecisionAdjust(num, maxlen, info); SDL_IntPrecisionAdjust(num, sizeof(num), info);
return SDL_PrintString(text, maxlen, info, num); return SDL_PrintString(text, maxlen, info, num);
} }
@ -1595,7 +1599,7 @@ SDL_PrintUnsignedLong(char *text, size_t maxlen, SDL_FormatInfo *info, unsigned
char num[130]; char num[130];
SDL_ultoa(value, num, info ? info->radix : 10); SDL_ultoa(value, num, info ? info->radix : 10);
SDL_IntPrecisionAdjust(num, maxlen, info); SDL_IntPrecisionAdjust(num, sizeof(num), info);
return SDL_PrintString(text, maxlen, info, num); return SDL_PrintString(text, maxlen, info, num);
} }
@ -1609,7 +1613,7 @@ SDL_PrintLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Sint64 value)
} }
SDL_lltoa(value, p, info ? info->radix : 10); SDL_lltoa(value, p, info ? info->radix : 10);
SDL_IntPrecisionAdjust(num, maxlen, info); SDL_IntPrecisionAdjust(num, sizeof(num), info);
return SDL_PrintString(text, maxlen, info, num); return SDL_PrintString(text, maxlen, info, num);
} }
@ -1619,126 +1623,92 @@ SDL_PrintUnsignedLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Uint6
char num[130]; char num[130];
SDL_ulltoa(value, num, info ? info->radix : 10); SDL_ulltoa(value, num, info ? info->radix : 10);
SDL_IntPrecisionAdjust(num, maxlen, info); SDL_IntPrecisionAdjust(num, sizeof(num), info);
return SDL_PrintString(text, maxlen, info, num); return SDL_PrintString(text, maxlen, info, num);
} }
static size_t static size_t
SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg)
{ {
int width; size_t length = 0;
size_t len;
size_t left = maxlen;
char *textstart = text;
if (arg) { if (arg) {
/* This isn't especially accurate, but hey, it's easy. :) */ /* This isn't especially accurate, but hey, it's easy. :) */
unsigned long value; unsigned long value;
if (arg < 0) { if (arg < 0) {
if (left > 1) { if (length < maxlen) {
*text = '-'; text[length] = '-';
--left;
} }
++text; ++length;
arg = -arg; arg = -arg;
} else if (info->force_sign) { } else if (info->force_sign) {
if (left > 1) { if (length < maxlen) {
*text = '+'; text[length] = '+';
--left;
} }
++text; ++length;
} }
value = (unsigned long) arg; value = (unsigned long) arg;
len = SDL_PrintUnsignedLong(text, left, NULL, value); length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, NULL, value);
if (len >= left) {
text += (left > 1) ? left - 1 : 0;
left = SDL_min(left, 1);
} else {
text += len;
left -= len;
}
arg -= value; arg -= value;
if (info->precision < 0) { if (info->precision < 0) {
info->precision = 6; info->precision = 6;
} }
if (info->force_type || info->precision > 0) { if (info->force_type || info->precision > 0) {
int mult = 10; int mult = 10;
if (left > 1) { if (length < maxlen) {
*text = '.'; text[length] = '.';
--left;
} }
++text; ++length;
while (info->precision-- > 0) { while (info->precision-- > 0) {
value = (unsigned long) (arg * mult); value = (unsigned long) (arg * mult);
len = SDL_PrintUnsignedLong(text, left, NULL, value); length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, NULL, value);
if (len >= left) {
text += (left > 1) ? left - 1 : 0;
left = SDL_min(left, 1);
} else {
text += len;
left -= len;
}
arg -= (double) value / mult; arg -= (double) value / mult;
mult *= 10; mult *= 10;
} }
} }
} else { } else {
if (left > 1) { if (length < maxlen) {
*text = '0'; text[length] = '0';
--left;
} }
++text; ++length;
if (info->force_type) { if (info->force_type) {
if (left > 1) { if (length < maxlen) {
*text = '.'; text[length] = '.';
--left;
} }
++text; ++length;
} }
} }
width = info->width - (int)(text - textstart); if (info->width > 0 && (size_t)info->width > length) {
if (width > 0) {
const char fill = info->pad_zeroes ? '0' : ' '; const char fill = info->pad_zeroes ? '0' : ' ';
char *end = text+left-1; size_t width = info->width - length;
len = (text - textstart); size_t filllen, movelen;
for (len = (text - textstart); len--; ) {
if ((textstart+len+width) < end) { filllen = SDL_min(width, maxlen);
*(textstart+len+width) = *(textstart+len); movelen = SDL_min(length, (maxlen - filllen));
} SDL_memmove(&text[filllen], text, movelen);
} SDL_memset(text, fill, filllen);
len = (size_t)width; length += width;
if (len >= left) {
text += (left > 1) ? left - 1 : 0;
left = SDL_min(left, 1);
} else {
text += len;
left -= len;
} }
if (end != textstart) { return length;
const size_t filllen = SDL_min(len, ((size_t) (end - textstart)) - 1);
SDL_memset(textstart, fill, filllen);
}
}
return (text - textstart);
} }
int int
SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap) SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap)
{ {
size_t left = maxlen; size_t length = 0;
char *textstart = text;
if (!text) {
maxlen = 0;
}
if (!fmt) { if (!fmt) {
fmt = ""; fmt = "";
} }
while (*fmt && left > 1) { while (*fmt) {
if (*fmt == '%') { if (*fmt == '%') {
SDL_bool done = SDL_FALSE; SDL_bool done = SDL_FALSE;
size_t len = 0;
SDL_bool check_flag; SDL_bool check_flag;
SDL_FormatInfo info; SDL_FormatInfo info;
enum enum
@ -1800,18 +1770,18 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
while (!done) { while (!done) {
switch (*fmt) { switch (*fmt) {
case '%': case '%':
if (left > 1) { if (length < maxlen) {
*text = '%'; text[length] = '%';
} }
len = 1; ++length;
done = SDL_TRUE; done = SDL_TRUE;
break; break;
case 'c': case 'c':
/* char is promoted to int when passed through (...) */ /* char is promoted to int when passed through (...) */
if (left > 1) { if (length < maxlen) {
*text = (char) va_arg(ap, int); text[length] = (char) va_arg(ap, int);
} }
len = 1; ++length;
done = SDL_TRUE; done = SDL_TRUE;
break; break;
case 'h': case 'h':
@ -1835,15 +1805,15 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
} }
switch (inttype) { switch (inttype) {
case DO_INT: case DO_INT:
len = SDL_PrintLong(text, left, &info, length += SDL_PrintLong(TEXT_AND_LEN_ARGS, &info,
(long) va_arg(ap, int)); (long) va_arg(ap, int));
break; break;
case DO_LONG: case DO_LONG:
len = SDL_PrintLong(text, left, &info, length += SDL_PrintLong(TEXT_AND_LEN_ARGS, &info,
va_arg(ap, long)); va_arg(ap, long));
break; break;
case DO_LONGLONG: case DO_LONGLONG:
len = SDL_PrintLongLong(text, left, &info, length += SDL_PrintLongLong(TEXT_AND_LEN_ARGS, &info,
va_arg(ap, Sint64)); va_arg(ap, Sint64));
break; break;
} }
@ -1876,23 +1846,23 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
} }
switch (inttype) { switch (inttype) {
case DO_INT: case DO_INT:
len = SDL_PrintUnsignedLong(text, left, &info, length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, &info,
(unsigned long) (unsigned long)
va_arg(ap, unsigned int)); va_arg(ap, unsigned int));
break; break;
case DO_LONG: case DO_LONG:
len = SDL_PrintUnsignedLong(text, left, &info, length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, &info,
va_arg(ap, unsigned long)); va_arg(ap, unsigned long));
break; break;
case DO_LONGLONG: case DO_LONGLONG:
len = SDL_PrintUnsignedLongLong(text, left, &info, length += SDL_PrintUnsignedLongLong(TEXT_AND_LEN_ARGS, &info,
va_arg(ap, Uint64)); va_arg(ap, Uint64));
break; break;
} }
done = SDL_TRUE; done = SDL_TRUE;
break; break;
case 'f': case 'f':
len = SDL_PrintFloat(text, left, &info, va_arg(ap, double)); length += SDL_PrintFloat(TEXT_AND_LEN_ARGS, &info, va_arg(ap, double));
done = SDL_TRUE; done = SDL_TRUE;
break; break;
case 'S': case 'S':
@ -1902,18 +1872,18 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
if (wide_arg) { if (wide_arg) {
char *arg = SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(wide_arg), (SDL_wcslen(wide_arg)+1)*sizeof(*wide_arg)); char *arg = SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(wide_arg), (SDL_wcslen(wide_arg)+1)*sizeof(*wide_arg));
info.pad_zeroes = SDL_FALSE; info.pad_zeroes = SDL_FALSE;
len = SDL_PrintString(text, left, &info, arg); length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, arg);
SDL_free(arg); SDL_free(arg);
} else { } else {
info.pad_zeroes = SDL_FALSE; info.pad_zeroes = SDL_FALSE;
len = SDL_PrintString(text, left, &info, NULL); length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, NULL);
} }
done = SDL_TRUE; done = SDL_TRUE;
} }
break; break;
case 's': case 's':
info.pad_zeroes = SDL_FALSE; info.pad_zeroes = SDL_FALSE;
len = SDL_PrintString(text, left, &info, va_arg(ap, char *)); length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, va_arg(ap, char *));
done = SDL_TRUE; done = SDL_TRUE;
break; break;
default: default:
@ -1922,23 +1892,23 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt,
} }
++fmt; ++fmt;
} }
if (len >= left) {
text += (left > 1) ? left - 1 : 0;
left = SDL_min(left, 1);
} else { } else {
text += len; if (length < maxlen) {
left -= len; text[length] = *fmt++;
} }
} else { ++length;
*text++ = *fmt++;
--left;
} }
} }
if (left > 0) { if (length < maxlen) {
*text = '\0'; text[length] = '\0';
} else if (maxlen > 0) {
text[maxlen - 1] = '\0';
} }
return (int)(text - textstart); return (int)length;
} }
#undef TEXT_AND_LEN_ARGS
#endif /* HAVE_VSNPRINTF */ #endif /* HAVE_VSNPRINTF */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -44,6 +44,7 @@ int
stdlib_snprintf(void *arg) stdlib_snprintf(void *arg)
{ {
int result; int result;
int predicted;
char text[1024]; char text[1024];
const char *expected; const char *expected;
@ -60,55 +61,72 @@ stdlib_snprintf(void *arg)
SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result); SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result);
result = SDL_snprintf(NULL, 0, "%s", "foo"); result = SDL_snprintf(NULL, 0, "%s", "foo");
SDLTest_AssertPass("Call to SDL_snprintf(NULL, 0, \"%%s\", \"foo\")");
SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result); SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result);
result = SDL_snprintf(text, sizeof(text), "%f", 1.0); result = SDL_snprintf(text, sizeof(text), "%f", 1.0);
predicted = SDL_snprintf(NULL, 0, "%f", 1.0);
expected = "1.000000"; expected = "1.000000";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", 1.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", 1.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%.f", 1.0); result = SDL_snprintf(text, sizeof(text), "%.f", 1.0);
predicted = SDL_snprintf(NULL, 0, "%.f", 1.0);
expected = "1"; expected = "1";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%.f\", 1.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%.f\", 1.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%#.f", 1.0); result = SDL_snprintf(text, sizeof(text), "%#.f", 1.0);
predicted = SDL_snprintf(NULL, 0, "%#.f", 1.0);
expected = "1."; expected = "1.";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%#.f\", 1.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%#.f\", 1.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%f", 1.0 + 1.0 / 3.0); result = SDL_snprintf(text, sizeof(text), "%f", 1.0 + 1.0 / 3.0);
predicted = SDL_snprintf(NULL, 0, "%f", 1.0 + 1.0 / 3.0);
expected = "1.333333"; expected = "1.333333";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", 1.0 + 1.0 / 3.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", 1.0 + 1.0 / 3.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%+f", 1.0 + 1.0 / 3.0); result = SDL_snprintf(text, sizeof(text), "%+f", 1.0 + 1.0 / 3.0);
predicted = SDL_snprintf(NULL, 0, "%+f", 1.0 + 1.0 / 3.0);
expected = "+1.333333"; expected = "+1.333333";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%+f\", 1.0 + 1.0 / 3.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%+f\", 1.0 + 1.0 / 3.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%.2f", 1.0 + 1.0 / 3.0); result = SDL_snprintf(text, sizeof(text), "%.2f", 1.0 + 1.0 / 3.0);
predicted = SDL_snprintf(NULL, 0, "%.2f", 1.0 + 1.0 / 3.0);
expected = "1.33"; expected = "1.33";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%.2f\", 1.0 + 1.0 / 3.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%.2f\", 1.0 + 1.0 / 3.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%6.2f", 1.0 + 1.0 / 3.0); result = SDL_snprintf(text, sizeof(text), "%6.2f", 1.0 + 1.0 / 3.0);
predicted = SDL_snprintf(NULL, 0, "%6.2f", 1.0 + 1.0 / 3.0);
expected = " 1.33"; expected = " 1.33";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%6.2f\", 1.0 + 1.0 / 3.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%6.2f\", 1.0 + 1.0 / 3.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, sizeof(text), "%06.2f", 1.0 + 1.0 / 3.0); result = SDL_snprintf(text, sizeof(text), "%06.2f", 1.0 + 1.0 / 3.0);
predicted = SDL_snprintf(NULL, 0, "%06.2f", 1.0 + 1.0 / 3.0);
expected = "001.33"; expected = "001.33";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%06.2f\", 1.0 + 1.0 / 3.0)"); SDLTest_AssertPass("Call to SDL_snprintf(\"%%06.2f\", 1.0 + 1.0 / 3.0)");
SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text); SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result);
SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
result = SDL_snprintf(text, 5, "%06.2f", 1.0 + 1.0 / 3.0); result = SDL_snprintf(text, 5, "%06.2f", 1.0 + 1.0 / 3.0);
expected = "001."; expected = "001.";