From c9d8a04945570b47cc551ca1dc2c6d3ce74528ec Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 24 May 2023 09:41:22 -0700
Subject: [PATCH] Added SDL_swprintf() and SDL_vswprintf()
---
include/SDL3/SDL_stdinc.h | 8 ++
src/dynapi/SDL_dynapi.c | 10 ++
src/dynapi/SDL_dynapi.sym | 2 +
src/dynapi/SDL_dynapi_overrides.h | 2 +
src/dynapi/SDL_dynapi_procs.h | 2 +
src/dynapi/gendynapi.py | 1 +
src/stdlib/SDL_string.c | 55 ++++++++++
test/testautomation_stdlib.c | 172 +++++++++++++++++++++++++++++-
8 files changed, 250 insertions(+), 2 deletions(-)
diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index 61fc27952f19..7f82956d3fa5 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -286,6 +286,8 @@ typedef uint64_t Uint64;
#define SDL_SCANF_FORMAT_STRING
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
#define SDL_SCANF_VARARG_FUNC( fmtargnumber )
+#define SDL_WPRINTF_VARARG_FUNC( fmtargnumber )
+#define SDL_WSCANF_VARARG_FUNC( fmtargnumber )
#else
#if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
#include <sal.h>
@@ -312,9 +314,13 @@ typedef uint64_t Uint64;
#ifdef __GNUC__
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 )))
#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 )))
+#define SDL_WPRINTF_VARARG_FUNC( fmtargnumber ) /* __attribute__ (( format( __wprintf__, fmtargnumber, fmtargnumber+1 ))) */
+#define SDL_WSCANF_VARARG_FUNC( fmtargnumber ) /* __attribute__ (( format( __wscanf__, fmtargnumber, fmtargnumber+1 ))) */
#else
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
#define SDL_SCANF_VARARG_FUNC( fmtargnumber )
+#define SDL_WPRINTF_VARARG_FUNC( fmtargnumber )
+#define SDL_WSCANF_VARARG_FUNC( fmtargnumber )
#endif
#endif /* SDL_DISABLE_ANALYZE_MACROS */
@@ -577,7 +583,9 @@ extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2,
extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2);
extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap);
extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3);
+extern DECLSPEC int SDLCALL SDL_swprintf(SDL_OUT_Z_CAP(maxlen) wchar_t *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const wchar_t *fmt, ... ) SDL_WPRINTF_VARARG_FUNC(3);
extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap);
+extern DECLSPEC int SDLCALL SDL_vswprintf(SDL_OUT_Z_CAP(maxlen) wchar_t *text, size_t maxlen, const wchar_t *fmt, va_list ap);
extern DECLSPEC int SDLCALL SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2);
extern DECLSPEC int SDLCALL SDL_vasprintf(char **strp, const char *fmt, va_list ap);
diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c
index cc97d232fc3b..d09fe9e6ef08 100644
--- a/src/dynapi/SDL_dynapi.c
+++ b/src/dynapi/SDL_dynapi.c
@@ -123,6 +123,16 @@ static void SDL_InitDynamicAPI(void);
va_end(ap); \
return retval; \
} \
+ _static int SDLCALL SDL_swprintf##name(SDL_OUT_Z_CAP(maxlen) wchar_t *buf, size_t maxlen, SDL_PRINTF_FORMAT_STRING const wchar_t *fmt, ...) \
+ { \
+ int retval; \
+ va_list ap; \
+ initcall; \
+ va_start(ap, fmt); \
+ retval = jump_table.SDL_vswprintf(buf, maxlen, fmt, ap); \
+ va_end(ap); \
+ return retval; \
+ } \
_static int SDLCALL SDL_asprintf##name(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
{ \
int retval; \
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index c5bf0b0bc3fc..c306f532f758 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -859,6 +859,8 @@ SDL3_0.0.0 {
SDL_GetWindowDisplayScale;
SDL_GetWindowPixelDensity;
SDL_wcstol;
+ SDL_swprintf;
+ SDL_vswprintf;
# extra symbols go here (don't modify this line)
local: *;
};
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 40db83c912ce..7da9a97e5722 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -885,3 +885,5 @@
#define SDL_GetWindowDisplayScale SDL_GetWindowDisplayScale_REAL
#define SDL_GetWindowPixelDensity SDL_GetWindowPixelDensity_REAL
#define SDL_wcstol SDL_wcstol_REAL
+#define SDL_swprintf SDL_swprintf_REAL
+#define SDL_vswprintf SDL_vswprintf_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index fa68b8969313..9722e2169f7e 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -41,6 +41,7 @@ SDL_DYNAPI_PROC(void,SDL_LogWarn,(int a, SDL_PRINTF_FORMAT_STRING const char *b,
SDL_DYNAPI_PROC(int,SDL_SetError,(SDL_PRINTF_FORMAT_STRING const char *a, ...),(a),return)
SDL_DYNAPI_PROC(int,SDL_asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_snprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, SDL_PRINTF_FORMAT_STRING const char *c, ...),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_swprintf,(SDL_OUT_Z_CAP(b) wchar_t *a, size_t b, SDL_PRINTF_FORMAT_STRING const wchar_t *c, ...),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_sscanf,(const char *a, SDL_SCANF_FORMAT_STRING const char *b, ...),(a,b),return)
#endif
@@ -930,3 +931,4 @@ SDL_DYNAPI_PROC(float,SDL_GetDisplayContentScale,(SDL_DisplayID a),(a),return)
SDL_DYNAPI_PROC(float,SDL_GetWindowDisplayScale,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(float,SDL_GetWindowPixelDensity,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(long,SDL_wcstol,(const wchar_t *a, wchar_t **b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_vswprintf,(wchar_t *a, size_t b, const wchar_t *c, va_list d),(a,b,c,d),return)
diff --git a/src/dynapi/gendynapi.py b/src/dynapi/gendynapi.py
index ada149a826f3..0f6284ab268e 100755
--- a/src/dynapi/gendynapi.py
+++ b/src/dynapi/gendynapi.py
@@ -144,6 +144,7 @@ def main():
func = func.replace("SDL_PRINTF_VARARG_FUNC(1)", "");
func = func.replace("SDL_PRINTF_VARARG_FUNC(2)", "");
func = func.replace("SDL_PRINTF_VARARG_FUNC(3)", "");
+ func = func.replace("SDL_WPRINTF_VARARG_FUNC(3)", "");
func = func.replace("SDL_SCANF_VARARG_FUNC(2)", "");
func = func.replace("__attribute__((analyzer_noreturn))", "");
func = func.replace("SDL_MALLOC", "");
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index b6aae10f51c6..95c19fcab664 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -1466,6 +1466,18 @@ int SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FOR
return retval;
}
+int SDL_swprintf(SDL_OUT_Z_CAP(maxlen) wchar_t *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const wchar_t *fmt, ...)
+{
+ va_list ap;
+ int retval;
+
+ va_start(ap, fmt);
+ retval = SDL_vswprintf(text, maxlen, fmt, ap);
+ va_end(ap);
+
+ return retval;
+}
+
#if defined(HAVE_LIBC) && defined(__WATCOMC__)
/* _vsnprintf() doesn't ensure nul termination */
int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap)
@@ -1979,6 +1991,49 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *f
#undef TEXT_AND_LEN_ARGS
#endif /* HAVE_VSNPRINTF */
+int SDL_vswprintf(SDL_OUT_Z_CAP(maxlen) wchar_t *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const wchar_t *fmt, va_list ap)
+{
+ char *text_utf8 = NULL, *fmt_utf8 = NULL;
+ int retval;
+
+ if (fmt) {
+ fmt_utf8 = SDL_iconv_string("UTF-8", "WCHAR_T", (const char *)fmt, (SDL_wcslen(fmt) + 1) * sizeof(wchar_t));
+ if (!fmt_utf8) {
+ return -1;
+ }
+ }
+
+ if (!maxlen) {
+ /* We still need to generate the text to find the final text length */
+ maxlen = 1024;
+ }
+ text_utf8 = (char *)SDL_malloc(maxlen * 4);
+ if (!text_utf8) {
+ SDL_free(fmt_utf8);
+ return -1;
+ }
+
+ retval = SDL_vsnprintf(text_utf8, maxlen * 4, fmt_utf8, ap);
+
+ if (retval >= 0) {
+ wchar_t *text_wchar = (wchar_t *)SDL_iconv_string("WCHAR_T", "UTF-8", text_utf8, SDL_strlen(text_utf8) + 1);
+ if (text_wchar) {
+ if (text) {
+ SDL_wcslcpy(text, text_wchar, maxlen);
+ }
+ retval = (int)SDL_wcslen(text_wchar);
+ SDL_free(text_wchar);
+ } else {
+ retval = -1;
+ }
+ }
+
+ SDL_free(text_utf8);
+ SDL_free(fmt_utf8);
+
+ return retval;
+}
+
int SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c
index d4ab8d25dcb5..448853a36e22 100644
--- a/test/testautomation_stdlib.c
+++ b/test/testautomation_stdlib.c
@@ -205,6 +205,169 @@ static int stdlib_snprintf(void *arg)
return TEST_COMPLETED;
}
+/**
+ * \brief Call to SDL_swprintf
+ */
+#undef SDL_swprintf
+static int stdlib_swprintf(void *arg)
+{
+ int result;
+ int predicted;
+ wchar_t text[1024];
+ const wchar_t *expected;
+ size_t size;
+
+ result = SDL_swprintf(text, sizeof(text), L"%s", "foo");
+ expected = L"foo";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%s\", \"foo\")");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+
+ result = SDL_swprintf(text, 2, L"%s", "foo");
+ expected = L"f";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%s\", \"foo\") with buffer size 2");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result);
+
+ result = SDL_swprintf(NULL, 0, L"%s", "foo");
+ SDLTest_AssertPass("Call to SDL_swprintf(NULL, 0, \"%%s\", \"foo\")");
+ SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result);
+
+ result = SDL_swprintf(text, 2, L"%s\n", "foo");
+ expected = L"f";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%s\\n\", \"foo\") with buffer size 2");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == 4, "Check result value, expected: 4, got: %d", result);
+
+ result = SDL_swprintf(text, sizeof(text), L"%f", 0.0);
+ predicted = SDL_swprintf(NULL, 0, L"%f", 0.0);
+ expected = L"0.000000";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%f\", 0.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%f", 1.0);
+ predicted = SDL_swprintf(NULL, 0, L"%f", 1.0);
+ expected = L"1.000000";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%f\", 1.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%.f", 1.0);
+ predicted = SDL_swprintf(NULL, 0, L"%.f", 1.0);
+ expected = L"1";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%.f\", 1.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%#.f", 1.0);
+ predicted = SDL_swprintf(NULL, 0, L"%#.f", 1.0);
+ expected = L"1.";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%#.f\", 1.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%f", 1.0 + 1.0 / 3.0);
+ predicted = SDL_swprintf(NULL, 0, L"%f", 1.0 + 1.0 / 3.0);
+ expected = L"1.333333";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%f\", 1.0 + 1.0 / 3.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%+f", 1.0 + 1.0 / 3.0);
+ predicted = SDL_swprintf(NULL, 0, L"%+f", 1.0 + 1.0 / 3.0);
+ expected = L"+1.333333";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%+f\", 1.0 + 1.0 / 3.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%.2f", 1.0 + 1.0 / 3.0);
+ predicted = SDL_swprintf(NULL, 0, L"%.2f", 1.0 + 1.0 / 3.0);
+ expected = L"1.33";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%.2f\", 1.0 + 1.0 / 3.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%6.2f", 1.0 + 1.0 / 3.0);
+ predicted = SDL_swprintf(NULL, 0, L"%6.2f", 1.0 + 1.0 / 3.0);
+ expected = L" 1.33";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%6.2f\", 1.0 + 1.0 / 3.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%06.2f", 1.0 + 1.0 / 3.0);
+ predicted = SDL_swprintf(NULL, 0, L"%06.2f", 1.0 + 1.0 / 3.0);
+ expected = L"001.33";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%06.2f\", 1.0 + 1.0 / 3.0)");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(text), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(text), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, 5, L"%06.2f", 1.0 + 1.0 / 3.0);
+ expected = L"001.";
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%06.2f\", 1.0 + 1.0 / 3.0) with buffer size 5");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == 6, "Check result value, expected: 6, got: %d", result);
+
+ {
+ static struct
+ {
+ float value;
+ const wchar_t *expected_f;
+ const wchar_t *expected_g;
+ } f_and_g_test_cases[] = {
+ { 100.0f, L"100.000000", L"100" },
+ { -100.0f, L"-100.000000", L"-100" },
+ { 100.75f, L"100.750000", L"100.75" },
+ { -100.75f, L"-100.750000", L"-100.75" },
+ { ((100 * 60 * 1000) / 1001) / 100.0f, L"59.939999", L"59.94" },
+ { -((100 * 60 * 1000) / 1001) / 100.0f, L"-59.939999", L"-59.94" },
+ { ((100 * 120 * 1000) / 1001) / 100.0f, L"119.879997", L"119.88" },
+ { -((100 * 120 * 1000) / 1001) / 100.0f, L"-119.879997", L"-119.88" },
+ { 9.9999999f, L"10.000000", L"10" },
+ { -9.9999999f, L"-10.000000", L"-10" },
+ };
+ int i;
+
+ for (i = 0; i < SDL_arraysize(f_and_g_test_cases); ++i) {
+ float value = f_and_g_test_cases[i].value;
+
+ result = SDL_swprintf(text, sizeof(text), L"%f", value);
+ predicted = SDL_swprintf(NULL, 0, L"%f", value);
+ expected = f_and_g_test_cases[i].expected_f;
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%f\", %g)", value);
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(expected), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(expected), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+
+ result = SDL_swprintf(text, sizeof(text), L"%g", value);
+ predicted = SDL_swprintf(NULL, 0, L"%g", value);
+ expected = f_and_g_test_cases[i].expected_g;
+ SDLTest_AssertPass("Call to SDL_swprintf(\"%%g\", %g)", value);
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == SDL_wcslen(expected), "Check result value, expected: %d, got: %d", (int)SDL_wcslen(expected), result);
+ SDLTest_AssertCheck(predicted == result, "Check predicted value, expected: %d, got: %d", result, predicted);
+ }
+ }
+
+ size = 64;
+ result = SDL_swprintf(text, sizeof(text), L"%zu %s", size, "test");
+ expected = L"64 test";
+ SDLTest_AssertPass("Call to SDL_swprintf(text, sizeof(text), \"%%zu %%s\", size, \"test\")");
+ SDLTest_AssertCheck(SDL_wcscmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text);
+ SDLTest_AssertCheck(result == 7, "Check result value, expected: 7, got: %d", result);
+
+ return TEST_COMPLETED;
+}
+
#if defined(HAVE_WFORMAT) || defined(HAVE_WFORMAT_EXTRA_ARGS)
#pragma GCC diagnostic pop
#endif
@@ -635,14 +798,18 @@ static const SDLTest_TestCaseReference stdlibTest2 = {
};
static const SDLTest_TestCaseReference stdlibTest3 = {
- stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED
+ stdlib_swprintf, "stdlib_swprintf", "Call to SDL_swprintf", TEST_ENABLED
};
static const SDLTest_TestCaseReference stdlibTest4 = {
- stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED
+ stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED
};
static const SDLTest_TestCaseReference stdlibTest5 = {
+ stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference stdlibTest6 = {
stdlib_aligned_alloc, "stdlib_aligned_alloc", "Call to SDL_aligned_alloc", TEST_ENABLED
};
@@ -657,6 +824,7 @@ static const SDLTest_TestCaseReference *stdlibTests[] = {
&stdlibTest3,
&stdlibTest4,
&stdlibTest5,
+ &stdlibTest6,
&stdlibTestOverflow,
NULL
};