summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@gmail.com>2012-08-01 15:34:13 +0000
committerGustavo Sverzut Barbieri <barbieri@gmail.com>2012-08-01 15:34:13 +0000
commite31ddb08d0dcce88184e9af3fd2804dfd35224a2 (patch)
tree8dbb309742bcb4279fe752c383a8848842257559
parent6c62ab6df5eafa27cca56c6f15dbbe5926ac053b (diff)
downloadeina-e31ddb08d0dcce88184e9af3fd2804dfd35224a2.tar.gz
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. SVN revision: 74742
-rw-r--r--src/include/eina_log.h14
-rw-r--r--src/lib/eina_log.c185
2 files changed, 140 insertions, 59 deletions
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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
@@ -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
+}