From: barbieri Date: Wed, 1 Aug 2012 15:34:13 +0000 (+0000) Subject: eina log: expose cross platform way to set console colors. X-Git-Tag: submit/2.0alpha-wayland/20121127.222009~74 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5b677b1555163cff80789430394dbfb1fe4e5c41;p=profile%2Fivi%2Feina.git eina log: expose cross platform way to set console colors. changed the win32 color parse to be malloc-less and also support more colors. It should be more correct, but I have no windows machine to test. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eina@74742 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/include/eina_log.h b/src/include/eina_log.h index 65d5dcd..d8843d0 100644 --- a/src/include/eina_log.h +++ b/src/include/eina_log.h @@ -19,6 +19,7 @@ #ifndef EINA_LOG_H_ #define EINA_LOG_H_ +#include #include #include #include @@ -890,6 +891,19 @@ EAPI void eina_log_print_cb_file(const Eina_Log_Domain *d, void *data, va_list args); +/** + * Configure console color of given file. + * + * @param fp file to configure console color (usually stderr or stdout). + * @param color a VT color code such as #EINA_COLOR_RED or #EINA_COLOR_RESET. + * + * @note if color is disabled, nothing is done. See + * eina_log_color_disable_get() + * @note on windows, both @a fp and @a color is converted automatically. + */ +EAPI void eina_log_console_color_set(FILE *fp, + const char *color) EINA_ARG_NONNULL(1, 2); + #include "eina_inline_log.x" /** diff --git a/src/lib/eina_log.c b/src/lib/eina_log.c index 2373823..944a695 100644 --- a/src/lib/eina_log.c +++ b/src/lib/eina_log.c @@ -252,75 +252,110 @@ static const char *_names[] = { }; #ifdef _WIN32 +/* TODO: query win32_def_attr on eina_log_init() */ +static int win32_def_attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + +/* NOTE: can't use eina_log from inside this function */ static int -eina_log_win32_color_get(const char *domain_str) +eina_log_win32_color_convert(const char *color, const char **endptr) { - char *str; - char *tmp; - char *tmp2; - int code = -1; - int lighted = 0; - int ret = 0; - - str = strdup(domain_str); - if (!str) - return 0; - - /* this should not append */ - if (str[0] != '\033') - { - free(str); - return 0; - } + const char *p; + int attr = 0; + + if (endptr) *endptr = color; + + if (color[0] != '\033') return 0; + if (color[1] != '[') return 0; - /* we skip the first char and the [ */ - tmp = tmp2 = str + 2; - while (*tmp != 'm') + p = color + 2; + while (1) { - if (*tmp == ';') + char *end; + int code = strtol(p, &end, 10); + + if (p == end) { - *tmp = '\0'; - code = atol(tmp2); - tmp++; - tmp2 = tmp; + //fputs("empty color string\n", stderr); + if (endptr) *endptr = end; + attr = 0; /* assume it was not color, must end with 'm' */ + break; } - tmp++; - } - *tmp = '\0'; - if (code < 0) - code = atol(tmp2); - else - lighted = atol(tmp2); - - free(str); - - if (code < lighted) - { - int c; + if (code) + { + if (code == 0) attr = win32_def_attr; + else if (code == 1) attr |= FOREGROUND_INTENSITY; + else if (code == 4) attr |= COMMON_LVB_UNDERSCORE; + else if (code == 7) attr |= COMMON_LVB_REVERSE_VIDEO; + else if ((code >= 30) && (code <= 37)) + { + /* clear foreground */ + attr &= ~(FOREGROUND_RED | + FOREGROUND_GREEN | + FOREGROUND_BLUE); + + if (code == 31) + attr |= FOREGROUND_RED; + else if (code == 32) + attr |= FOREGROUND_GREEN; + else if (code == 33) + attr |= FOREGROUND_RED | FOREGROUND_GREEN; + else if (code == 34) + attr |= FOREGROUND_BLUE; + else if (code == 35) + attr |= FOREGROUND_RED | FOREGROUND_BLUE; + else if (code == 36) + attr |= FOREGROUND_GREEN | FOREGROUND_BLUE; + else if (code == 37) + attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + } + else if ((code >= 40) && (code <= 47)) + { + /* clear background */ + attr &= ~(BACKGROUND_RED | + BACKGROUND_GREEN | + BACKGROUND_BLUE); + + if (code == 41) + attr |= BACKGROUND_RED; + else if (code == 42) + attr |= BACKGROUND_GREEN; + else if (code == 44) + attr |= BACKGROUND_RED | BACKGROUND_GREEN; + else if (code == 44) + attr |= BACKGROUND_BLUE; + else if (code == 45) + attr |= BACKGROUND_RED | BACKGROUND_BLUE; + else if (code == 46) + attr |= BACKGROUND_GREEN | BACKGROUND_BLUE; + else if (code == 47) + attr |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; + } + } - c = code; - code = lighted; - lighted = c; + if (*end == 'm') + { + if (endptr) *endptr = end + 1; + break; + } + else if (*end == ';') + p = end + 1; + else + { + //fprintf(stderr, "unexpected char in color string: %s\n", end); + attr = 0; /* assume it was not color */ + if (endptr) *endptr = end; + break; + } } - if (lighted) - ret = FOREGROUND_INTENSITY; - - if (code == 31) - ret |= FOREGROUND_RED; - else if (code == 32) - ret |= FOREGROUND_GREEN; - else if (code == 33) - ret |= FOREGROUND_RED | FOREGROUND_GREEN; - else if (code == 34) - ret |= FOREGROUND_BLUE; - else if (code == 36) - ret |= FOREGROUND_GREEN | FOREGROUND_BLUE; - else if (code == 37) - ret |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - - return ret; + return attr; +} + +static int +eina_log_win32_color_get(const char *color) +{ + return eina_log_win32_color_convert(color, NULL); } #endif @@ -2027,3 +2062,35 @@ eina_log_vprint(int domain, Eina_Log_Level level, const char *file, #endif } +EAPI void +eina_log_console_color_set(FILE *fp, const char *color) +{ +#ifdef EINA_ENABLE_LOG + + EINA_SAFETY_ON_NULL_RETURN(fp); + EINA_SAFETY_ON_NULL_RETURN(color); + if (_disable_color) return; + +#ifdef _WIN32 + int attr = eina_log_win32_color_convert(color); + HANDLE *handle; + if (fp == stderr) + handle = GetStdHandle(STD_ERROR_HANDLE); + else if (fp == stdout) + handle = GetStdHandle(STD_OUTPUT_HANDLE); + else + { + /* Do we have a way to convert FILE* to HANDLE? + * Should we use it? + */ + return; + } + SetConsoleTextAttribute(handle, attr); +#else + fputs(color, fp); +#endif + +#else + (void)color; +#endif +}