Commit b3dca57d authored by Harald Welte's avatar Harald Welte
Browse files

Colorize compiler error/warning messages



If you've been mainly working with gcc during the past decade or so,
it has been outputting compiler warning and errors in colorized form,
if the output was a terminal.  Colorizing greatly helps to differentiate
errors from warnings.

Particularly since the TITAN compiler has (to my knowledge) no way to configure
which warnings to emit an which not, it's very difficult for the human
reader to pick out one 'error:' among potentially hundreds of 'warning:'
lines.  That's even more the case as the 'error' and 'warninig' is
printed after the variable-length location (file/line) and hence not
aligned in some column.

This patch adds output coloring to the TITAN compiler output, using the
same colors as gcc default colors.  This way, error messages are red,
warning messages are purple, and everything else is "default".

Signed-off-by: Harald Welte's avatarHarald Welte <laforge@gnumonks.org>
Change-Id: Ia5e42466ae3f964ce1bbaa159ae4f9f58259c616
parent c7ea7397
......@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#ifndef MINGW
# include <sys/wait.h>
#endif
......@@ -30,6 +31,70 @@ unsigned verb_level=0x0007; /* default value */
const char *argv0; /* the programname :) */
enum stderr_color {
COLOR_ERROR,
COLOR_WARNING,
COLOR_NOTE,
COLOR_NOTIFY,
COLOR_DEBUG,
};
/* might be interesting to provide a way to override these from the environment, similar to GCC_COLORS,
* or even to fall back to GCC_COLORS if it is set? */
static const char *color_error = "01;31";
static const char *color_warning = "01;35";
static const char *color_note = "01;36";
static const char *color_notify = "";
static const char *color_debug = "";
static const char *get_color(enum stderr_color color)
{
switch (color) {
case COLOR_ERROR:
return color_error;
case COLOR_WARNING:
return color_warning;
case COLOR_NOTE:
return color_note;
case COLOR_NOTIFY:
return color_notify;
case COLOR_DEBUG:
return color_debug;
default:
return NULL;
}
}
/* should we colorize the output? */
static bool should_colorize(void)
{
char const *t = getenv("TERM");
if (!t)
return false;
if (!strcmp(t, "dumb"))
return false;
if (isatty(STDERR_FILENO))
return true;
return false;
}
static void begin_colorize(enum stderr_color color)
{
const char *colstr;
if (!should_colorize())
return;
colstr = get_color(color);
if (colstr)
fprintf(stderr, "\033[1;%sm", colstr);
}
static void end_colorize()
{
if (!should_colorize())
return;
fputs("\033]0;m", stderr);
}
void fatal_error(const char *filename, int lineno, const char *fmt, ...)
{
va_list parameters;
......@@ -39,12 +104,14 @@ void fatal_error(const char *filename, int lineno, const char *fmt, ...)
Common::Error_Context::report_error(&loc, fmt, parameters);
va_end(parameters);
#else
begin_colorize(COLOR_ERROR);
fprintf(stderr, "FATAL ERROR: %s: In line %d of %s: ",
argv0, lineno, filename);
va_start(parameters, fmt);
vfprintf(stderr, fmt, parameters);
va_end(parameters);
putc('\n', stderr);
end_colorize();
#endif
fflush(stderr);
abort();
......@@ -52,12 +119,14 @@ void fatal_error(const char *filename, int lineno, const char *fmt, ...)
void ERROR(const char *fmt, ...)
{
begin_colorize(COLOR_ERROR);
fprintf(stderr, "%s: error: ", argv0);
va_list parameters;
va_start(parameters, fmt);
vfprintf(stderr, fmt, parameters);
va_end(parameters);
putc('\n', stderr);
end_colorize();
fflush(stderr);
Common::Error_Context::increment_error_count();
}
......@@ -65,12 +134,14 @@ void ERROR(const char *fmt, ...)
void WARNING(const char *fmt, ...)
{
if(!(verb_level & 2)) return;
begin_colorize(COLOR_WARNING);
fprintf(stderr, "%s: warning: ", argv0);
va_list parameters;
va_start(parameters, fmt);
vfprintf(stderr, fmt, parameters);
va_end(parameters);
putc('\n', stderr);
end_colorize();
fflush(stderr);
Common::Error_Context::increment_warning_count();
}
......@@ -91,24 +162,28 @@ void NOTSUPP(const char *fmt, ...)
void NOTIFY(const char *fmt, ...)
{
if(!(verb_level & 4)) return;
begin_colorize(COLOR_NOTIFY);
fprintf(stderr, "Notify: ");
va_list parameters;
va_start(parameters, fmt);
vfprintf(stderr, fmt, parameters);
va_end(parameters);
putc('\n', stderr);
end_colorize();
fflush(stderr);
}
void DEBUG(unsigned level, const char *fmt, ...)
{
if((level>7?7:level)>((verb_level>>3)&0x07)) return;
begin_colorize(COLOR_DEBUG);
fprintf(stderr, "%*sDebug: ", level, "");
va_list parameters;
va_start(parameters, fmt);
vfprintf(stderr, fmt, parameters);
va_end(parameters);
putc('\n', stderr);
end_colorize();
fflush(stderr);
}
......@@ -260,6 +335,7 @@ namespace Common {
void Error_Context::report_error(const Location *loc, const char *fmt,
va_list args)
{
begin_colorize(COLOR_ERROR);
if (!suppress_context) print_context(stderr);
if (tail != 0 && loc && loc->get_filename() == 0) {
// borrow location information from the innermost context
......@@ -272,6 +348,7 @@ namespace Common {
fputs("error: ", stderr);
vfprintf(stderr, fmt, args);
putc('\n', stderr);
end_colorize();
fflush(stderr);
increment_error_count();
}
......@@ -279,12 +356,14 @@ namespace Common {
void Error_Context::report_warning(const Location *loc, const char *fmt,
va_list args)
{
begin_colorize(COLOR_WARNING);
if(!(verb_level & 2)) return;
if (!suppress_context) print_context(stderr);
if (loc) loc->print_location(stderr);
fputs("warning: ", stderr);
vfprintf(stderr, fmt, args);
putc('\n', stderr);
end_colorize();
fflush(stderr);
increment_warning_count();
}
......@@ -292,11 +371,13 @@ namespace Common {
void Error_Context::report_note(const Location *loc, const char *fmt,
va_list args)
{
begin_colorize(COLOR_NOTE);
if (!suppress_context) print_context(stderr);
if (loc) loc->print_location(stderr);
fputs("note: ", stderr);
vfprintf(stderr, fmt, args);
putc('\n', stderr);
end_colorize();
fflush(stderr);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment