From: Martin Willi Date: Tue, 15 Oct 2013 13:45:11 +0000 (+0200) Subject: printf-hook-builtin: Support Windows console colors using TTY escape codes X-Git-Tag: 5.2.0dr6~24^2~127 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f2b8c8c808163f9b299af5129bc4a9e56f10041;p=thirdparty%2Fstrongswan.git printf-hook-builtin: Support Windows console colors using TTY escape codes --- diff --git a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c index c79d4b87a6..466c673d93 100644 --- a/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c +++ b/src/libstrongswan/utils/printf_hook/printf_hook_builtin.c @@ -1104,6 +1104,128 @@ int builtin_vprintf(const char *format, va_list ap) return builtin_vfprintf(stdout, format, ap); } +#ifdef WIN32 +/** + * Set TTY color on Windows consoles + */ +static void set_console_color(HANDLE handle, int color) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + struct { + /* escape code */ + int color; + /* windows console color combination */ + WORD attributes; + } maps[] = { + { 30, 0 }, + { 31, FOREGROUND_RED }, + { 32, FOREGROUND_GREEN }, + { 33, FOREGROUND_GREEN | FOREGROUND_RED }, + { 34, FOREGROUND_BLUE | FOREGROUND_INTENSITY }, + { 35, FOREGROUND_RED | FOREGROUND_BLUE }, + { 36, FOREGROUND_GREEN | FOREGROUND_BLUE }, + { 37, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED }, + { 39, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED }, + { 40, 0 }, + { 41, BACKGROUND_RED }, + { 42, BACKGROUND_GREEN }, + { 43, BACKGROUND_GREEN | BACKGROUND_RED }, + { 44, BACKGROUND_BLUE }, + { 45, BACKGROUND_RED | BACKGROUND_BLUE }, + { 46, BACKGROUND_GREEN | BACKGROUND_BLUE }, + { 47, BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED }, + { 49, 0 }, + }; + int i; + + if (GetConsoleScreenBufferInfo(handle, &info)) + { + if (color < 40) + { + info.wAttributes &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | + FOREGROUND_RED | FOREGROUND_INTENSITY); + } + else + { + info.wAttributes &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | + BACKGROUND_RED | BACKGROUND_INTENSITY); + } + for (i = 0; i < countof(maps); i++) + { + if (maps[i].color == color) + { + info.wAttributes |= maps[i].attributes; + SetConsoleTextAttribute(handle, info.wAttributes); + break; + } + } + } +} + +int builtin_vfprintf(FILE *stream, const char *format, va_list ap) +{ + char buf[PRINTF_BUF_LEN], *pos, *stop; + HANDLE handle; + int len, total; + DWORD clen, mode; + + total = len = builtin_vsnprintf(buf, sizeof(buf), format, ap); + switch (fileno(stream)) + { + case 1: + handle = GetStdHandle(STD_OUTPUT_HANDLE); + break; + case 2: + handle = GetStdHandle(STD_ERROR_HANDLE); + break; + default: + handle = INVALID_HANDLE_VALUE; + break; + } + /* GetConsoleMode fails if output redirected */ + if (handle == INVALID_HANDLE_VALUE || !GetConsoleMode(handle, &mode)) + { + return fwrite(buf, 1, len, stream); + } + while (len) + { + pos = &buf[total - len]; + if (len > 4) + { + if (pos[0] == '\e' && pos[1] == '[' && pos[4] == 'm') + { + if (isdigit(pos[3])) + { + if (pos[2] == '3' || pos[2] == '4') + { + set_console_color(handle, + (pos[2] - '0') * 10 + pos[3] - '0'); + len -= 5; + continue; + } + } + } + } + stop = memchr(pos + 1, '\e', len); + if (stop) + { + clen = stop - pos; + } + else + { + clen = len; + } + if (clen && !WriteConsole(handle, pos, clen, &clen, NULL)) + { + break; + } + len -= clen; + } + return total - len; +} + +#else /* !WIN32 */ + int builtin_vfprintf(FILE *stream, const char *format, va_list ap) { char buf[PRINTF_BUF_LEN]; @@ -1113,6 +1235,8 @@ int builtin_vfprintf(FILE *stream, const char *format, va_list ap) return fwrite(buf, 1, len, stream); } +#endif /* !WIN32 */ + int builtin_vsprintf(char *str, const char *format, va_list ap) { return builtin_vsnprintf(str, ~(size_t)0, format, ap); diff --git a/src/libstrongswan/utils/utils.c b/src/libstrongswan/utils/utils.c index 03c7b4f7e3..7cca845f73 100644 --- a/src/libstrongswan/utils/utils.c +++ b/src/libstrongswan/utils/utils.c @@ -363,6 +363,9 @@ char* tty_escape_get(int fd, tty_escape_t escape) case TTY_BOLD: case TTY_UNDERLINE: case TTY_BLINKING: +#ifdef WIN32 + return ""; +#endif case TTY_FG_BLACK: case TTY_FG_RED: case TTY_FG_GREEN: @@ -382,7 +385,7 @@ char* tty_escape_get(int fd, tty_escape_t escape) case TTY_BG_WHITE: case TTY_BG_DEF: return enum_to_name(tty_color_names, escape); - /* warn if a excape code is missing */ + /* warn if a escape code is missing */ } return ""; }