From 8dbae411f4d55950562e2bdd38ad1201af4a041c Mon Sep 17 00:00:00 2001 From: Roman Koshelev Date: Mon, 2 Oct 2023 19:21:14 +0300 Subject: [PATCH 1/2] refactoring --- include/fmt/format-inl.h | 15 ++++++--------- include/fmt/ostream.h | 11 ++++++----- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 3680794c6211..7d09ca0cadfc 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -73,9 +73,8 @@ FMT_FUNC void report_error(format_func func, int error_code, } // A wrapper around fwrite that throws on error. -inline void fwrite_fully(const void* ptr, size_t size, size_t count, - FILE* stream) { - size_t written = std::fwrite(ptr, size, count, stream); +inline void fwrite_fully(const void* ptr, size_t count, FILE* stream) { + size_t written = std::fwrite(ptr, 1, count, stream); if (written < count) FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); } @@ -1433,13 +1432,11 @@ extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // void*, const void*, dword, dword*, void*); FMT_FUNC bool write_console(std::FILE* f, string_view text) { - auto fd = _fileno(f); + int fd = _fileno(f); if (!_isatty(fd)) return false; auto u16 = utf8_to_utf16(text); - auto written = dword(); return WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), u16.c_str(), - static_cast(u16.size()), &written, - nullptr) != 0; + static_cast(u16.size()), nullptr, nullptr) != 0; } #endif @@ -1448,12 +1445,12 @@ FMT_FUNC bool write_console(std::FILE* f, string_view text) { FMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args) { auto buffer = memory_buffer(); detail::vformat_to(buffer, fmt, args); - fwrite_fully(buffer.data(), 1, buffer.size(), f); + fwrite_fully(buffer.data(), buffer.size(), f); } #endif FMT_FUNC void print(std::FILE* f, string_view text) { - if (!write_console(f, text)) fwrite_fully(text.data(), 1, text.size(), f); + if (!write_console(f, text)) fwrite_fully(text.data(), text.size(), f); } } // namespace detail diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index a5eddcb0874f..021b5e58407c 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -38,24 +38,25 @@ auto get_file(std::filebuf&) -> FILE*; #endif inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data) { + FILE* c_file = nullptr; #if FMT_MSC_VERSION if (auto* buf = dynamic_cast(os.rdbuf())) - if (FILE* f = get_file(*buf)) return write_console(f, data); + c_file = get_file(*buf); #elif defined(_WIN32) && defined(__GLIBCXX__) auto* rdbuf = os.rdbuf(); - FILE* c_file; if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf*>(rdbuf)) c_file = sfbuf->file(); else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf*>(rdbuf)) c_file = fbuf->file(); else return false; - if (c_file) return write_console(c_file, data); #else - ignore_unused(os, data); + ignore_unused(os); #endif - return false; + if (!c_file) return false; + return write_console(c_file, data); } + inline bool write_ostream_unicode(std::wostream&, fmt::basic_string_view) { return false; From 4fe961f796b9f14011d6bdaa442df5c7e067c1c6 Mon Sep 17 00:00:00 2001 From: Roman Koshelev Date: Tue, 3 Oct 2023 10:03:22 +0300 Subject: [PATCH 2/2] add buffer flush before direct write --- include/fmt/format-inl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 7d09ca0cadfc..4dc182f083c1 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -1434,6 +1434,7 @@ extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // FMT_FUNC bool write_console(std::FILE* f, string_view text) { int fd = _fileno(f); if (!_isatty(fd)) return false; + std::fflush(f); auto u16 = utf8_to_utf16(text); return WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), u16.c_str(), static_cast(u16.size()), nullptr, nullptr) != 0;