Skip to content

Commit 9847cab

Browse files
committed
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
1 parent 8612cd0 commit 9847cab

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

stdlib/public/stubs/LibcShims.cpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,20 @@
3131

3232
#include "../SwiftShims/LibcShims.h"
3333

34+
#if defined(_WIN32)
35+
static void __attribute__((__constructor__))
36+
_swift_stdlib_configure_console_mode(void) {
37+
static UINT uiPrevConsoleCP = GetConsoleOutputCP();
38+
atexit([]() { SetConsoleOutputCP(uiPrevConsoleCP); });
39+
SetConsoleOutputCP(CP_UTF8);
40+
}
41+
#endif
42+
3443
SWIFT_RUNTIME_STDLIB_INTERNAL
3544
__swift_size_t _swift_stdlib_fwrite_stdout(const void *ptr,
36-
__swift_size_t size,
37-
__swift_size_t nitems) {
38-
return fwrite(ptr, size, nitems, stdout);
45+
__swift_size_t size,
46+
__swift_size_t nitems) {
47+
return fwrite(ptr, size, nitems, stdout);
3948
}
4049

4150
SWIFT_RUNTIME_STDLIB_SPI

0 commit comments

Comments
 (0)