forked from enlightenment/efl
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
This commit is contained in:
parent
3fc5ceadd7
commit
73ab74bd09
|
@ -19,6 +19,7 @@
|
||||||
#ifndef EINA_LOG_H_
|
#ifndef EINA_LOG_H_
|
||||||
#define EINA_LOG_H_
|
#define EINA_LOG_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -890,6 +891,19 @@ EAPI void eina_log_print_cb_file(const Eina_Log_Domain *d,
|
||||||
void *data,
|
void *data,
|
||||||
va_list args);
|
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"
|
#include "eina_inline_log.x"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -252,75 +252,110 @@ static const char *_names[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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
|
static int
|
||||||
eina_log_win32_color_get(const char *domain_str)
|
eina_log_win32_color_convert(const char *color, const char **endptr)
|
||||||
{
|
{
|
||||||
char *str;
|
const char *p;
|
||||||
char *tmp;
|
int attr = 0;
|
||||||
char *tmp2;
|
|
||||||
int code = -1;
|
|
||||||
int lighted = 0;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
str = strdup(domain_str);
|
if (endptr) *endptr = color;
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* this should not append */
|
if (color[0] != '\033') return 0;
|
||||||
if (str[0] != '\033')
|
if (color[1] != '[') return 0;
|
||||||
|
|
||||||
|
p = color + 2;
|
||||||
|
while (1)
|
||||||
{
|
{
|
||||||
free(str);
|
char *end;
|
||||||
return 0;
|
int code = strtol(p, &end, 10);
|
||||||
}
|
|
||||||
|
|
||||||
/* we skip the first char and the [ */
|
if (p == end)
|
||||||
tmp = tmp2 = str + 2;
|
|
||||||
while (*tmp != 'm')
|
|
||||||
{
|
|
||||||
if (*tmp == ';')
|
|
||||||
{
|
{
|
||||||
*tmp = '\0';
|
//fputs("empty color string\n", stderr);
|
||||||
code = atol(tmp2);
|
if (endptr) *endptr = end;
|
||||||
tmp++;
|
attr = 0; /* assume it was not color, must end with 'm' */
|
||||||
tmp2 = tmp;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp++;
|
if (code)
|
||||||
}
|
{
|
||||||
*tmp = '\0';
|
if (code == 0) attr = win32_def_attr;
|
||||||
if (code < 0)
|
else if (code == 1) attr |= FOREGROUND_INTENSITY;
|
||||||
code = atol(tmp2);
|
else if (code == 4) attr |= COMMON_LVB_UNDERSCORE;
|
||||||
else
|
else if (code == 7) attr |= COMMON_LVB_REVERSE_VIDEO;
|
||||||
lighted = atol(tmp2);
|
else if ((code >= 30) && (code <= 37))
|
||||||
|
{
|
||||||
|
/* clear foreground */
|
||||||
|
attr &= ~(FOREGROUND_RED |
|
||||||
|
FOREGROUND_GREEN |
|
||||||
|
FOREGROUND_BLUE);
|
||||||
|
|
||||||
free(str);
|
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 < lighted)
|
if (code == 41)
|
||||||
{
|
attr |= BACKGROUND_RED;
|
||||||
int c;
|
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;
|
if (*end == 'm')
|
||||||
code = lighted;
|
{
|
||||||
lighted = c;
|
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)
|
return attr;
|
||||||
ret = FOREGROUND_INTENSITY;
|
}
|
||||||
|
|
||||||
if (code == 31)
|
static int
|
||||||
ret |= FOREGROUND_RED;
|
eina_log_win32_color_get(const char *color)
|
||||||
else if (code == 32)
|
{
|
||||||
ret |= FOREGROUND_GREEN;
|
return eina_log_win32_color_convert(color, NULL);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2027,3 +2062,35 @@ eina_log_vprint(int domain, Eina_Log_Level level, const char *file,
|
||||||
#endif
|
#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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue