Simplify workaround for starting console and CLI-wrapper
* Disable workaround by default; with the CLI-wrapper available it makes no sense to run this code unnecassarily when the main executable is invoked * Remove check for Mintty; with the workaround disabled by default it is no longer necassary to avoid it * Simplify the CLI-wrapper to rely on main application for enabling UTF-8 and virtual terminal processing as it relies on it for attaching to the parent's console anyways
This commit is contained in:
parent
c6396f92fc
commit
0d0685d4c7
|
@ -134,12 +134,10 @@ bool handleVirtualTerminalProcessing()
|
|||
return true;
|
||||
}
|
||||
// disable use of ANSI escape codes otherwise if it makes sense
|
||||
const char *const msyscon = std::getenv("MSYSCON");
|
||||
if (isMintty()) {
|
||||
return false; // no need to disable escape codes if it is just mintty
|
||||
}
|
||||
const char *const term = std::getenv("TERM");
|
||||
if (term && std::strstr(term, "xterm")) {
|
||||
if (const char *const term = std::getenv("TERM"); term && std::strstr(term, "xterm")) {
|
||||
return false; // no need to disable escape codes if it is some xterm-like terminal
|
||||
}
|
||||
return EscapeCodes::enabled = false;
|
||||
|
@ -160,14 +158,21 @@ void stopConsole()
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Ensure the process has a console attached and sets its output code page to UTF-8.
|
||||
* \brief Ensure the process has a console attached and properly setup.
|
||||
* \remarks
|
||||
* - Only available (and required) under Windows where otherwise stdout/stderr is not printed to the console (at
|
||||
* least when using `cmd.exe`).
|
||||
* - Used to start a console from a GUI application. Does *not* create a new console if the process already has one.
|
||||
* - Closes the console automatically when the application exits.
|
||||
* - It breaks redirecting stdout/stderr so this can be opted-out by setting the environment
|
||||
* variable `ENABLE_CONSOLE=0` and/or `ENABLE_CP_UTF8=0`.
|
||||
* - Only available (and required) under Windows where otherwise standard I/O is not possible via the console (unless
|
||||
* when using Mintty).
|
||||
* - Attaching a console breaks redirections/pipes so this needs to be opted-in by setting the environment variable
|
||||
* `ENABLE_CONSOLE=1`.
|
||||
* - Note that this is only useful to start a console from a GUI application. It is not necassary to call this function
|
||||
* from a console application.
|
||||
* - The console is automatically closed when the application exits.
|
||||
* - This function alone does not provide good results. It still breaks redirections in PowerShell and other shells and
|
||||
* after the application exists the command prompt is not displayed. A CLI-wrapper is required for proper behavior. The
|
||||
* build system automatically generates one when the CMake variable BUILD_CLI_WRAPPER is set. Note that this CLI-wrapper
|
||||
* still relies on this function (and thus sets `ENABLE_CONSOLE=1`). Without this standard I/O would still not be
|
||||
* possible via the console. The part for skipping in case there's a redirection is still required. Otherwise
|
||||
* redirections/pipes are broken when using the CLI-wrapper as well.
|
||||
* \sa
|
||||
* - https://docs.microsoft.com/en-us/windows/console/AttachConsole
|
||||
* - https://docs.microsoft.com/en-us/windows/console/AllocConsole
|
||||
|
@ -176,16 +181,12 @@ void stopConsole()
|
|||
*/
|
||||
void startConsole()
|
||||
{
|
||||
if (isMintty()) {
|
||||
// skip if ENABLE_CONSOLE is set to 0 or not set at all
|
||||
if (const auto e = isEnvVariableSet("ENABLE_CONSOLE"); !e.has_value() || !e.value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// skip if ENABLE_CONSOLE is set to 0
|
||||
if (const auto consoleEnabled = isEnvVariableSet("ENABLE_CONSOLE"); consoleEnabled.has_value() && !consoleEnabled.value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check whether there's a redirection; skip messing with any streams then
|
||||
// check whether there's a redirection; skip messing with any streams then to not break redirections/pipes
|
||||
auto pos = std::fpos_t();
|
||||
std::fgetpos(stdout, &pos);
|
||||
const auto skipstdout = pos >= 0;
|
||||
|
@ -264,14 +265,15 @@ void startConsole()
|
|||
}
|
||||
|
||||
// set console character set to UTF-8
|
||||
const auto utf8Enabled = isEnvVariableSet("ENABLE_CP_UTF8");
|
||||
if (!utf8Enabled.has_value() || utf8Enabled.value()) {
|
||||
if (const auto e = isEnvVariableSet("ENABLE_CP_UTF8"); !e.has_value() || e.value()) {
|
||||
SetConsoleCP(CP_UTF8);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
}
|
||||
|
||||
// enable virtual terminal processing or disable ANSI-escape if that's not possible
|
||||
handleVirtualTerminalProcessing();
|
||||
if (const auto e = isEnvVariableSet("ENABLE_HANDLING_VIRTUAL_TERMINAL_PROCESSING"); !e.has_value() || e.value()) {
|
||||
handleVirtualTerminalProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -6,27 +6,10 @@
|
|||
#include <system_error>
|
||||
#include <string_view>
|
||||
|
||||
/*!
|
||||
* \brief Enables virutal terminal processing.
|
||||
*/
|
||||
static bool enableVirtualTerminalProcessing(DWORD nStdHandle)
|
||||
{
|
||||
auto stdHandle = GetStdHandle(nStdHandle);
|
||||
if (stdHandle == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
auto dwMode = DWORD();
|
||||
if (!GetConsoleMode(stdHandle, &dwMode)) {
|
||||
return false;
|
||||
}
|
||||
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
return SetConsoleMode(stdHandle, dwMode);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns \a replacement if \a value matches \a key; otherwise returns \a value.
|
||||
*/
|
||||
static std::size_t replace(std::size_t value, std::size_t key, std::size_t replacement)
|
||||
static constexpr std::size_t replace(std::size_t value, std::size_t key, std::size_t replacement)
|
||||
{
|
||||
return value == key ? replacement : value;
|
||||
}
|
||||
|
@ -36,22 +19,14 @@ static std::size_t replace(std::size_t value, std::size_t key, std::size_t repla
|
|||
*/
|
||||
int main()
|
||||
{
|
||||
// setup console
|
||||
// -> enable UTF-8 as this is used by all my applications
|
||||
// ensure environment variables are set so the main executable will attach to the parent's console
|
||||
// note: This is still required for this wrapper to receive standard I/O. We also still rely on the main
|
||||
// process to enable UTF-8 and virtual terminal processing.
|
||||
SetConsoleCP(CP_UTF8);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
// -> ensure environment variables for hack to attach to parent's console are enabled; this is still required
|
||||
// for this wrapper to receive standard I/O
|
||||
SetEnvironmentVariableW(L"ENABLE_CONSOLE", L"1");
|
||||
SetEnvironmentVariableW(L"ENABLE_CP_UTF8", L"1");
|
||||
// -> unset environment variables that would lead to skipping the hack; for the wrapper the hack is even
|
||||
// required when using Mintty
|
||||
SetEnvironmentVariableW(L"MSYSCON", L"");
|
||||
SetEnvironmentVariableW(L"TERM_PROGRAM", L"");
|
||||
// -> enable support for ANSI escape codes if possible
|
||||
if (enableVirtualTerminalProcessing(STD_OUTPUT_HANDLE) && enableVirtualTerminalProcessing(STD_ERROR_HANDLE)) {
|
||||
SetEnvironmentVariableW(L"ENABLE_ESCAPE_CODES", L"1");
|
||||
}
|
||||
SetEnvironmentVariableW(L"ENABLE_HANDLING_VIRTUAL_TERMINAL_PROCESSING", L"1");
|
||||
|
||||
// determine the wrapper executable path
|
||||
wchar_t pathBuffer[MAX_PATH];
|
||||
|
|
Loading…
Reference in New Issue