From 9f6434dcde1856840fa738c0005534be203abe8d Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 23 Dec 2019 16:18:48 -0800 Subject: [PATCH] Improve UTF-8 handling on Windows --- include/fmt/core.h | 9 ++++++++- include/fmt/format-inl.h | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 6e5612b3..5812fca4 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1507,8 +1507,10 @@ inline std::basic_string format(const S& format_str, Args&&... args) { {internal::make_args_checked(format_str, args...)}); } -FMT_API void vprint(std::FILE* f, string_view format_str, format_args args); FMT_API void vprint(string_view format_str, format_args args); +FMT_API void vprint(std::FILE* f, string_view format_str, format_args args); +FMT_API void vprint_mojibake(std::FILE* f, string_view format_str, + format_args args); /** \rst @@ -1539,8 +1541,13 @@ inline void print(std::FILE* f, const S& format_str, Args&&... args) { template ::value)> inline void print(const S& format_str, Args&&... args) { +#if !defined(_WIN32) || FMT_UNICODE vprint(to_string_view(format_str), internal::make_args_checked(format_str, args...)); +#else + vprint_mojibake(stdout, to_string_view(format_str), + internal::make_args_checked(format_str, args...)); +#endif } FMT_END_NAMESPACE diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 67329c35..5e326d6d 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -22,8 +22,8 @@ #endif #if FMT_UNICODE -#include -#include +# include +# include #endif #ifdef _MSC_VER @@ -1350,9 +1350,8 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { if (_isatty(fd)) { internal::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size())); auto written = DWORD(); - if (!WriteConsoleW( - reinterpret_cast(_get_osfhandle(fd)), - u16.c_str(), u16.size(), &written, nullptr)) { + if (!WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), + u16.c_str(), u16.size(), &written, nullptr)) { throw format_error("failed to write to console"); } return; @@ -1361,6 +1360,16 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { internal::fwrite_fully(buffer.data(), 1, buffer.size(), f); } +#ifdef _WIN32 +FMT_FUNC void vprint_mojibake(std::FILE* f, string_view format_str, + format_args args) { + memory_buffer buffer; + internal::vformat_to(buffer, format_str, + basic_format_args>(args)); + internal::fwrite_fully(buffer.data(), 1, buffer.size(), f); +} +#endif + FMT_FUNC void vprint(string_view format_str, format_args args) { vprint(stdout, format_str, args); }