From 4bfba6f2438bb8f721de6b8873db060ed05bb3ff Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Fri, 22 Aug 2025 21:51:32 +0800 Subject: [PATCH] feat: add windows-spec console patch --- src/CMakeLists.txt | 2 ++ src/YYCCLegacy/ConsoleHelper.cpp | 29 ----------------------- src/YYCCLegacy/ConsoleHelper.hpp | 10 -------- src/yycc/windows/console.cpp | 38 ++++++++++++++++++++++++++++++ src/yycc/windows/console.hpp | 33 ++++++++++++++++++++++++++ testbench/CMakeLists.txt | 1 + testbench/yycc/windows/console.cpp | 17 +++++++++++++ 7 files changed, 91 insertions(+), 39 deletions(-) create mode 100644 src/yycc/windows/console.cpp create mode 100644 src/yycc/windows/console.hpp create mode 100644 testbench/yycc/windows/console.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 95fd26e..32e56c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,7 @@ PRIVATE yycc/windows/com.cpp yycc/windows/dialog.cpp yycc/windows/winfct.cpp + yycc/windows/console.cpp yycc/encoding/stl.cpp yycc/encoding/windows.cpp yycc/encoding/iconv.cpp @@ -65,6 +66,7 @@ FILES yycc/windows/com.hpp yycc/windows/dialog.hpp yycc/windows/winfct.hpp + yycc/windows/console.hpp yycc/constraint.hpp yycc/constraint/builder.hpp yycc/encoding/stl.hpp diff --git a/src/YYCCLegacy/ConsoleHelper.cpp b/src/YYCCLegacy/ConsoleHelper.cpp index e6bb634..4cc491c 100644 --- a/src/YYCCLegacy/ConsoleHelper.cpp +++ b/src/YYCCLegacy/ConsoleHelper.cpp @@ -18,19 +18,6 @@ namespace YYCC::ConsoleHelper { #pragma region Windows Specific Functions #if defined(YYCC_OS_WINDOWS) - static bool RawEnableColorfulConsole(FILE* fs) { - if (!_isatty(_fileno(fs))) return false; - - HANDLE h_output; - DWORD dw_mode; - - h_output = (HANDLE)_get_osfhandle(_fileno(fs)); - if (!GetConsoleMode(h_output, &dw_mode)) return false; - if (!SetConsoleMode(h_output, dw_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT)) return false; - - return true; - } - /* Reference: * https://stackoverflow.com/questions/45575863/how-to-print-utf-8-strings-to-stdcout-on-windows @@ -160,22 +147,6 @@ namespace YYCC::ConsoleHelper { #endif #pragma endregion - bool EnableColorfulConsole() { -#if defined(YYCC_OS_WINDOWS) - - bool ret = true; - ret &= RawEnableColorfulConsole(stdout); - ret &= RawEnableColorfulConsole(stderr); - return ret; - -#else - - // just return true and do nothing - return true; - -#endif - } - yycc_u8string ReadLine() { #if defined(YYCC_OS_WINDOWS) diff --git a/src/YYCCLegacy/ConsoleHelper.hpp b/src/YYCCLegacy/ConsoleHelper.hpp index ed29a01..fea84cb 100644 --- a/src/YYCCLegacy/ConsoleHelper.hpp +++ b/src/YYCCLegacy/ConsoleHelper.hpp @@ -11,16 +11,6 @@ */ namespace YYCC::ConsoleHelper { - /** - * @brief Enable console color support for Windows. - * @details This actually is enable virtual console feature for \c stdout and \c stderr. - * @return True if success, otherwise false. - * @remarks - * This function only works on Windows and do nothing on other platforms such as Linux, - * because we assume all terminals existing on other platform support color feature as default. - */ - bool EnableColorfulConsole(); - /** * @brief Reads the next line of UTF8 characters from the standard input stream. * @return diff --git a/src/yycc/windows/console.cpp b/src/yycc/windows/console.cpp new file mode 100644 index 0000000..88e66b5 --- /dev/null +++ b/src/yycc/windows/console.cpp @@ -0,0 +1,38 @@ +#include "console.hpp" +#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL) + +#include + +#include "import_guard_head.hpp" +#include +#include +#include "import_guard_tail.hpp" + +namespace yycc::windows::console { + + static ExecResult colorful_fs(FILE* fs) { + if (!_isatty(_fileno(fs))) { + return std::unexpected(ExecError::NotTty); + } + + HANDLE h_output; + DWORD dw_mode; + + h_output = (HANDLE) _get_osfhandle(_fileno(fs)); + if (!GetConsoleMode(h_output, &dw_mode)) { + return std::unexpected(ExecError::GetMode); + } + if (!SetConsoleMode(h_output, dw_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT)) { + return std::unexpected(ExecError::SetMode); + } + + return {}; + } + + ExecResult colorful_console() { + return colorful_fs(stdout).and_then([]() { return colorful_fs(stderr); }); + } + +} // namespace yycc::windows::console + +#endif diff --git a/src/yycc/windows/console.hpp b/src/yycc/windows/console.hpp new file mode 100644 index 0000000..b33151e --- /dev/null +++ b/src/yycc/windows/console.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "../macro/os_detector.hpp" +#include "../macro/stl_detector.hpp" +#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL) + +#include + +/** + * @brief The namespace provide patches for Windows console. + */ +namespace yycc::windows::console { + + /// @brief Error occurs in this module. + enum class ExecError { + NotTty, ///< Given stream is not TTY. + GetMode, ///< Can not get stream mode. + SetMode, ///< Can not set stream mode. + }; + + /// @brief Result type used in this module. + template + using ExecResult = std::expected; + + /** + * @brief Enable console color support for Windows. + * @details This actually is enable virtual console feature for \c stdout and \c stderr. + * @return Nothing or error occurs. + */ + ExecResult colorful_console(); + +} + +#endif diff --git a/testbench/CMakeLists.txt b/testbench/CMakeLists.txt index b6a649d..731f700 100644 --- a/testbench/CMakeLists.txt +++ b/testbench/CMakeLists.txt @@ -33,6 +33,7 @@ PRIVATE yycc/windows/com.cpp yycc/windows/dialog.cpp yycc/windows/winfct.cpp + yycc/windows/console.cpp yycc/carton/pycodec.cpp yycc/carton/termcolor.cpp diff --git a/testbench/yycc/windows/console.cpp b/testbench/yycc/windows/console.cpp new file mode 100644 index 0000000..e0c8524 --- /dev/null +++ b/testbench/yycc/windows/console.cpp @@ -0,0 +1,17 @@ +#include +#include +#include + +#define CONSOLE ::yycc::windows::console + +namespace yycctest::windows::console { +#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL) + + TEST(WindowsConsole, ColorfulConsole) { + // Set colorful console should always be success. + auto rv = CONSOLE::colorful_console(); + EXPECT_TRUE(rv.has_value()); + } + +#endif +}