mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-30 23:00:21 -04:00
Allow using ANSI escape codes on windows when writing to the console
This commit is contained in:
parent
bd80269072
commit
df70399661
@ -36,6 +36,34 @@ log_error(const char *fmt, ...) {
|
||||
va_end(ar);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static bool stdout_is_a_tty = false, stderr_is_a_tty = false;
|
||||
DWORD console_old_mode = 0;
|
||||
static bool console_mode_changed = false;
|
||||
|
||||
static void
|
||||
detect_tty() {
|
||||
stdout_is_a_tty = _isatty(_fileno(stdout));
|
||||
stderr_is_a_tty = _isatty(_fileno(stderr));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_vt_terminal_mode() {
|
||||
if (stdout_is_a_tty || stderr_is_a_tty) {
|
||||
HANDLE h = GetStdHandle(stdout_is_a_tty ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
|
||||
if (h != INVALID_HANDLE_VALUE) {
|
||||
if (GetConsoleMode(h, &console_old_mode)) {
|
||||
console_mode_changed = true;
|
||||
SetConsoleMode(h, console_old_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
restore_vt_terminal_mode() {
|
||||
if (console_mode_changed) SetConsoleMode(GetStdHandle(stdout_is_a_tty ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE), console_old_mode);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
log_error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
@ -227,12 +255,14 @@ run_interpreter() {
|
||||
#ifdef _WIN32
|
||||
UINT code_page = GetConsoleOutputCP();
|
||||
if (code_page != CP_UTF8) SetConsoleOutputCP(CP_UTF8);
|
||||
setup_vt_terminal_mode();
|
||||
#endif
|
||||
|
||||
int ret = Py_RunMain();
|
||||
PyConfig_Clear(&config);
|
||||
#ifdef _WIN32
|
||||
if (code_page != CP_UTF8) SetConsoleOutputCP(CP_UTF8);
|
||||
restore_vt_terminal_mode();
|
||||
#endif
|
||||
exit(ret);
|
||||
#undef CHECK_STATUS
|
||||
|
@ -20,8 +20,6 @@
|
||||
static int GUI_APP = 0;
|
||||
static char python_dll[] = PYDLL;
|
||||
|
||||
void set_gui_app(int yes) { GUI_APP = yes; }
|
||||
|
||||
static int _show_error(const wchar_t *preamble, const wchar_t *msg, const int code) {
|
||||
static wchar_t buf[4096];
|
||||
static char utf8_buf[4096] = {0};
|
||||
@ -105,20 +103,9 @@ load_python_dll() {
|
||||
|
||||
const static wchar_t out_of_memory[] = L"Out of memory";
|
||||
|
||||
UINT
|
||||
setup_streams() {
|
||||
UINT code_page = GetConsoleOutputCP();
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
//printf("input cp: %d output cp: %d\r\n", GetConsoleCP(), GetConsoleOutputCP());
|
||||
|
||||
return code_page;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
redirect_out_stream(FILE *stream) {
|
||||
if (_isatty(_fileno(stream))) return;
|
||||
FILE *f = NULL;
|
||||
errno_t err;
|
||||
|
||||
@ -151,13 +138,14 @@ execute_python_entrypoint(const wchar_t *basename, const wchar_t *module, const
|
||||
int ret = 0;
|
||||
// Prevent Windows' idiotic error dialog popups when various win32 api functions fail
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
||||
detect_tty();
|
||||
|
||||
if (is_gui_app) {
|
||||
// Redirect stdout and stderr to NUL so that python does not fail writing to them
|
||||
redirect_out_stream(stdout);
|
||||
redirect_out_stream(stderr);
|
||||
if (!stdout_is_a_tty) redirect_out_stream(stdout);
|
||||
if (!stderr_is_a_tty) redirect_out_stream(stderr);
|
||||
}
|
||||
set_gui_app(is_gui_app);
|
||||
GUI_APP = is_gui_app;
|
||||
// Disable the invalid parameter handler
|
||||
_set_invalid_parameter_handler(null_invalid_parameter_handler);
|
||||
interpreter_data.argv = CommandLineToArgvW(GetCommandLineW(), &interpreter_data.argc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user