From 9847cab8d3e5b74101a54bd3871f5002ffaf688c Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sun, 19 Dec 2021 15:33:45 -0800 Subject: [PATCH] stdlib: change the console to UTF-8 on start This adjusts the Windows console to switch the codepage to UTF-8. This is important as the default codepage (CP437) does not allow for UTF-8 output, but expects ASCII. However, strings in Swift are assumed to be UTF-8, which means that there is now a conversion mismatch. Because the console mode persists beyond the duration of the application as it is state local to the console and not the C runtime, we should restore the state of the console before termination. We do this by registering a termination handler via `atexit`. This means that an abnormal termination (e.g. via `fatalError`) will irrevocably alter the state of the console (interestingly enough, `chcp` will still report the original console codepage even though the console will internally be set to UTF-8). Fixes: SR-13807 --- stdlib/public/stubs/LibcShims.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp index abf201468fa4a..1ee4f5e0c9e4d 100644 --- a/stdlib/public/stubs/LibcShims.cpp +++ b/stdlib/public/stubs/LibcShims.cpp @@ -31,11 +31,20 @@ #include "../SwiftShims/LibcShims.h" +#if defined(_WIN32) +static void __attribute__((__constructor__)) +_swift_stdlib_configure_console_mode(void) { + static UINT uiPrevConsoleCP = GetConsoleOutputCP(); + atexit([]() { SetConsoleOutputCP(uiPrevConsoleCP); }); + SetConsoleOutputCP(CP_UTF8); +} +#endif + SWIFT_RUNTIME_STDLIB_INTERNAL __swift_size_t _swift_stdlib_fwrite_stdout(const void *ptr, - __swift_size_t size, - __swift_size_t nitems) { - return fwrite(ptr, size, nitems, stdout); + __swift_size_t size, + __swift_size_t nitems) { + return fwrite(ptr, size, nitems, stdout); } SWIFT_RUNTIME_STDLIB_SPI