v3-0001-command-line-colorization-on-windows.patch
application/octet-stream
Filename: v3-0001-command-line-colorization-on-windows.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v3-0001
| File | + | − |
|---|---|---|
| src/common/logging.c | 57 | 1 |
diff --git a/src/common/logging.c b/src/common/logging.c
index c78ae79..8c0377f 100644
--- a/src/common/logging.c
+++ b/src/common/logging.c
@@ -32,6 +32,60 @@ static const char *sgr_locus = NULL;
#define ANSI_ESCAPE_FMT "\x1b[%sm"
#define ANSI_ESCAPE_RESET "\x1b[0m"
+#define str_starts_with(str, substr) (strncmp(str, substr, strlen(substr)) == 0)
+#define str_ends_with(str, substr) (strcmp(str + strlen(str) - strlen(substr), substr) == 0)
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
+
+static bool
+terminal_supports_color(void)
+{
+#ifndef WIN32
+ const char *term_env = getenv("TERM");
+
+ if (!term_env)
+ return false;
+ else if (strcmp(term_env, "ansi") == 0)
+ return true;
+ else if (strcmp(term_env, "cygwin") == 0)
+ return true;
+ else if (strcmp(term_env, "linux") == 0)
+ return true;
+ else if (str_starts_with(term_env, "rxvt"))
+ return true;
+ else if (str_starts_with(term_env, "screen"))
+ return true;
+ else if (str_starts_with(term_env, "xterm"))
+ return true;
+ else if (str_starts_with(term_env, "vt100"))
+ return true;
+ else if (str_ends_with(term_env, "color"))
+ return true;
+ else
+ return false;
+#else
+/*
+ * Windows supports color on console's VT100 mode.
+ * It is disabled by default, so it must be enabled to use color outpout.
+ */
+ /* Check stderr */
+ HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);
+ DWORD dwMode = 0;
+
+ if (hOut == INVALID_HANDLE_VALUE)
+ return false;
+ if (!GetConsoleMode(hOut, &dwMode))
+ return false;
+ if (dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+ return true;
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ if (!SetConsoleMode(hOut, dwMode))
+ return false;
+ return true;
+#endif
+}
+
/*
* This should be called before any output happens.
*/
@@ -40,6 +94,8 @@ pg_logging_init(const char *argv0)
{
const char *pg_color_env = getenv("PG_COLOR");
bool log_color = false;
+ bool color_terminal = isatty(fileno(stderr)) &&
+ terminal_supports_color();
/* usually the default, but not on Windows */
setvbuf(stderr, NULL, _IONBF, 0);
@@ -50,7 +106,7 @@ pg_logging_init(const char *argv0)
if (pg_color_env)
{
if (strcmp(pg_color_env, "always") == 0 ||
- (strcmp(pg_color_env, "auto") == 0 && isatty(fileno(stderr))))
+ (strcmp(pg_color_env, "auto") == 0 && color_terminal))
log_color = true;
}