feat: add windows-spec console patch

This commit is contained in:
2025-08-22 21:51:32 +08:00
parent 9e994dd4f0
commit 4bfba6f243
7 changed files with 91 additions and 39 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,38 @@
#include "console.hpp"
#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL)
#include <cstdio>
#include "import_guard_head.hpp"
#include <Windows.h>
#include <io.h>
#include "import_guard_tail.hpp"
namespace yycc::windows::console {
static ExecResult<void> 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<void> colorful_console() {
return colorful_fs(stdout).and_then([]() { return colorful_fs(stderr); });
}
} // namespace yycc::windows::console
#endif

View File

@ -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 <expected>
/**
* @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<typename T>
using ExecResult = std::expected<T, ExecError>;
/**
* @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<void> colorful_console();
}
#endif

View File

@ -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

View File

@ -0,0 +1,17 @@
#include <gtest/gtest.h>
#include <yycc.hpp>
#include <yycc/windows/console.hpp>
#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
}