Added support for printing wide strings using "%ls" syntax (cherry picked from commit 128ca7016018178c0c3231db7db2005dbf234068)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index d71f2da..4a01703 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -1514,6 +1514,19 @@ static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, c
return length;
}
+static size_t SDL_PrintStringW(char *text, size_t maxlen, SDL_FormatInfo *info, const wchar_t *wide_string)
+{
+ size_t length = 0;
+ if (wide_string) {
+ char *string = SDL_iconv_string("UTF-8", "WCHAR_T", (char *)(wide_string), (SDL_wcslen(wide_string) + 1) * sizeof(*wide_string));
+ length = SDL_PrintString(TEXT_AND_LEN_ARGS, info, string);
+ SDL_free(string);
+ } else {
+ length = SDL_PrintString(TEXT_AND_LEN_ARGS, info, NULL);
+ }
+ return length;
+}
+
static void SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info)
{ /* left-pad num with zeroes. */
size_t sz, pad, have_sign;
@@ -1831,23 +1844,17 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *f
done = SDL_TRUE;
break;
case 'S':
- {
- /* In practice this is used on Windows for WCHAR strings */
- wchar_t *wide_arg = va_arg(ap, wchar_t *);
- if (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;
- length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, arg);
- SDL_free(arg);
- } else {
- info.pad_zeroes = SDL_FALSE;
- length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, NULL);
- }
+ info.pad_zeroes = SDL_FALSE;
+ length += SDL_PrintStringW(TEXT_AND_LEN_ARGS, &info, va_arg(ap, wchar_t *));
done = SDL_TRUE;
- } break;
+ break;
case 's':
info.pad_zeroes = SDL_FALSE;
- length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, va_arg(ap, char *));
+ if (inttype > DO_INT) {
+ length += SDL_PrintStringW(TEXT_AND_LEN_ARGS, &info, va_arg(ap, wchar_t *));
+ } else {
+ length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, va_arg(ap, char *));
+ }
done = SDL_TRUE;
break;
default:
diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c
index 3f45cbf..ba7ba88 100644
--- a/test/testautomation_stdlib.c
+++ b/test/testautomation_stdlib.c
@@ -62,6 +62,18 @@ int stdlib_snprintf(void *arg)
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);
+ result = SDL_snprintf(text, sizeof(text), "%S", L"foo");
+ expected = "foo";
+ SDLTest_AssertPass("Call to SDL_snprintf(\"%%S\", \"foo\")");
+ 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);
+
+ result = SDL_snprintf(text, sizeof(text), "%ls", L"foo");
+ expected = "foo";
+ SDLTest_AssertPass("Call to SDL_snprintf(\"%%ls\", \"foo\")");
+ 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);
+
result = SDL_snprintf(text, 2, "%s", "foo");
expected = "f";
SDLTest_AssertPass("Call to SDL_snprintf(\"%%s\", \"foo\") with buffer size 2");