Skip to content

Commit dac9a7f

Browse files
committed
Improve UTF-8 handling on Windows
1 parent 3ca9533 commit dac9a7f

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

include/fmt/core.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,13 @@
208208
# define FMT_USE_EXPERIMENTAL_STRING_VIEW
209209
#endif
210210

211+
#ifndef FMT_UNICODE
212+
# define FMT_UNICODE 0
213+
#endif
214+
#if FMT_UNICODE
215+
# pragma execution_character_set("utf-8")
216+
#endif
217+
211218
FMT_BEGIN_NAMESPACE
212219

213220
// Implementations of enable_if_t and other metafunctions for pre-C++14 systems.

include/fmt/format-inl.h

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
# include <locale>
2222
#endif
2323

24+
#if FMT_UNICODE
25+
#include <windows.h>
26+
#include <io.h>
27+
#endif
28+
2429
#ifdef _MSC_VER
2530
# pragma warning(push)
2631
# pragma warning(disable : 4702) // unreachable code
@@ -1336,20 +1341,24 @@ FMT_FUNC void report_system_error(int error_code,
13361341
report_error(format_system_error, error_code, message);
13371342
}
13381343

1339-
#ifndef FMT_UNICODE
1340-
# define FMT_UNICODE 0
1341-
#endif
1342-
13431344
FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
13441345
memory_buffer buffer;
13451346
internal::vformat_to(buffer, format_str,
13461347
basic_format_args<buffer_context<char>>(args));
1347-
#if FMT_UNICODE
1348-
internal::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size()));
1349-
std::fputws(u16.c_str(), f);
1350-
#else
1351-
internal::fwrite_fully(buffer.data(), 1, buffer.size(), f);
1348+
#if defined(_WIN32) && FMT_UNICODE
1349+
auto fd = _fileno(f);
1350+
if (_isatty(fd)) {
1351+
internal::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size()));
1352+
auto written = DWORD();
1353+
if (!WriteConsoleW(
1354+
reinterpret_cast<HANDLE>(_get_osfhandle(fd)),
1355+
u16.c_str(), u16.size(), &written, nullptr)) {
1356+
throw format_error("failed to write to console");
1357+
}
1358+
return;
1359+
}
13521360
#endif
1361+
internal::fwrite_fully(buffer.data(), 1, buffer.size(), f);
13531362
}
13541363

13551364
FMT_FUNC void vprint(string_view format_str, format_args args) {

0 commit comments

Comments
 (0)