mirror of git://gcc.gnu.org/git/gcc.git
opts.c: Include diagnostic-color.h.
* opts.c: Include diagnostic-color.h. (common_handle_option): Handle OPT_fdiagnostics_color_. * Makefile.in (OBJS-libcommon): Add diagnostic-color.o. (diagnostic.o, opts.o, pretty-print.o): Depend on diagnostic-color.h. (diagnostic-color.o): New. * common.opt (fdiagnostics-color, fdiagnostics-color=): New options. (diagnostic_color_rule): New enum. * dwarf2out.c (gen_producer_string): Don't print -fdiagnostics-color*. * langhooks.c (lhd_print_error_function): Add %r "locus" and %R around the location string. * diagnostic.def: Add 3rd argument to DEFINE_DIAGNOSTIC_KIND macros, either NULL, or color kind. * diagnostic-color.c: New file. * diagnostic-color.h: New file. * diagnostic-core.h (DEFINE_DIAGNOSTIC_KIND): Adjust macro for 3 arguments. * doc/invoke.texi (-fdiagnostics-color): Document. * pretty-print.h (pp_show_color): Define. (struct pretty_print_info): Add show_color field. * diagnostic.c: Include diagnostic-color.h. (diagnostic_build_prefix): Adjust for 3 argument DEFINE_DIAGNOSTIC_KIND macros. Colorize error:, warning: etc. strings and also the location string. (diagnostic_show_locus): Colorize the caret line. * pretty-print.c: Include diagnostic-color.h. (pp_base_format): Handle %r and %R format specifiers. Colorize strings inside of %< %> quotes or quoted through q format modifier. c-family/ * c-format.c (gcc_diag_char_table, gcc_tdiag_char_table, gcc_cdiag_char_table, gcc_cxxdiag_char_table): Add %r and %R format specifiers. cp/ * error.c (cp_print_error_function, print_instantiation_partial_context_line, maybe_print_constexpr_context): Colorize locus strings. From-SVN: r197842
This commit is contained in:
parent
4b84d650e8
commit
f3065bdb6e
|
|
@ -0,0 +1,307 @@
|
||||||
|
/* Output colorization.
|
||||||
|
Copyright 2011-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA. */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "diagnostic-color.h"
|
||||||
|
|
||||||
|
/* Select Graphic Rendition (SGR, "\33[...m") strings. */
|
||||||
|
/* Also Erase in Line (EL) to Right ("\33[K") by default. */
|
||||||
|
/* Why have EL to Right after SGR?
|
||||||
|
-- The behavior of line-wrapping when at the bottom of the
|
||||||
|
terminal screen and at the end of the current line is often
|
||||||
|
such that a new line is introduced, entirely cleared with
|
||||||
|
the current background color which may be different from the
|
||||||
|
default one (see the boolean back_color_erase terminfo(5)
|
||||||
|
capability), thus scrolling the display by one line.
|
||||||
|
The end of this new line will stay in this background color
|
||||||
|
even after reverting to the default background color with
|
||||||
|
"\33[m', unless it is explicitly cleared again with "\33[K"
|
||||||
|
(which is the behavior the user would instinctively expect
|
||||||
|
from the whole thing). There may be some unavoidable
|
||||||
|
background-color flicker at the end of this new line because
|
||||||
|
of this (when timing with the monitor's redraw is just right).
|
||||||
|
-- The behavior of HT (tab, "\t") is usually the same as that of
|
||||||
|
Cursor Forward Tabulation (CHT) with a default parameter
|
||||||
|
of 1 ("\33[I"), i.e., it performs pure movement to the next
|
||||||
|
tab stop, without any clearing of either content or screen
|
||||||
|
attributes (including background color); try
|
||||||
|
printf 'asdfqwerzxcv\rASDF\tZXCV\n'
|
||||||
|
in a bash(1) shell to demonstrate this. This is not what the
|
||||||
|
user would instinctively expect of HT (but is ok for CHT).
|
||||||
|
The instinctive behavior would include clearing the terminal
|
||||||
|
cells that are skipped over by HT with blank cells in the
|
||||||
|
current screen attributes, including background color;
|
||||||
|
the boolean dest_tabs_magic_smso terminfo(5) capability
|
||||||
|
indicates this saner behavior for HT, but only some rare
|
||||||
|
terminals have it (although it also indicates a special
|
||||||
|
glitch with standout mode in the Teleray terminal for which
|
||||||
|
it was initially introduced). The remedy is to add "\33K"
|
||||||
|
after each SGR sequence, be it START (to fix the behavior
|
||||||
|
of any HT after that before another SGR) or END (to fix the
|
||||||
|
behavior of an HT in default background color that would
|
||||||
|
follow a line-wrapping at the bottom of the screen in another
|
||||||
|
background color, and to complement doing it after START).
|
||||||
|
Piping GCC's output through a pager such as less(1) avoids
|
||||||
|
any HT problems since the pager performs tab expansion.
|
||||||
|
|
||||||
|
Generic disadvantages of this remedy are:
|
||||||
|
-- Some very rare terminals might support SGR but not EL (nobody
|
||||||
|
will use "gcc -fdiagnostics-color" on a terminal that does not
|
||||||
|
support SGR in the first place).
|
||||||
|
-- Having these extra control sequences might somewhat complicate
|
||||||
|
the task of any program trying to parse "gcc -fdiagnostics-color"
|
||||||
|
output in order to extract structuring information from it.
|
||||||
|
A specific disadvantage to doing it after SGR START is:
|
||||||
|
-- Even more possible background color flicker (when timing
|
||||||
|
with the monitor's redraw is just right), even when not at the
|
||||||
|
bottom of the screen.
|
||||||
|
There are no additional disadvantages specific to doing it after
|
||||||
|
SGR END.
|
||||||
|
|
||||||
|
It would be impractical for GCC to become a full-fledged
|
||||||
|
terminal program linked against ncurses or the like, so it will
|
||||||
|
not detect terminfo(5) capabilities. */
|
||||||
|
#define COLOR_SEPARATOR ";"
|
||||||
|
#define COLOR_NONE "00"
|
||||||
|
#define COLOR_BOLD "01"
|
||||||
|
#define COLOR_UNDERSCORE "04"
|
||||||
|
#define COLOR_BLINK "05"
|
||||||
|
#define COLOR_REVERSE "07"
|
||||||
|
#define COLOR_FG_BLACK "30"
|
||||||
|
#define COLOR_FG_RED "31"
|
||||||
|
#define COLOR_FG_GREEN "32"
|
||||||
|
#define COLOR_FG_YELLOW "33"
|
||||||
|
#define COLOR_FG_BLUE "34"
|
||||||
|
#define COLOR_FG_MAGENTA "35"
|
||||||
|
#define COLOR_FG_CYAN "36"
|
||||||
|
#define COLOR_FG_WHITE "37"
|
||||||
|
#define COLOR_BG_BLACK "40"
|
||||||
|
#define COLOR_BG_RED "41"
|
||||||
|
#define COLOR_BG_GREEN "42"
|
||||||
|
#define COLOR_BG_YELLOW "43"
|
||||||
|
#define COLOR_BG_BLUE "44"
|
||||||
|
#define COLOR_BG_MAGENTA "45"
|
||||||
|
#define COLOR_BG_CYAN "46"
|
||||||
|
#define COLOR_BG_WHITE "47"
|
||||||
|
#define SGR_START "\33["
|
||||||
|
#define SGR_END "m\33[K"
|
||||||
|
#define SGR_SEQ(str) SGR_START str SGR_END
|
||||||
|
#define SGR_RESET SGR_SEQ("")
|
||||||
|
|
||||||
|
|
||||||
|
/* The context and logic for choosing default --color screen attributes
|
||||||
|
(foreground and background colors, etc.) are the following.
|
||||||
|
-- There are eight basic colors available, each with its own
|
||||||
|
nominal luminosity to the human eye and foreground/background
|
||||||
|
codes (black [0 %, 30/40], blue [11 %, 34/44], red [30 %, 31/41],
|
||||||
|
magenta [41 %, 35/45], green [59 %, 32/42], cyan [70 %, 36/46],
|
||||||
|
yellow [89 %, 33/43], and white [100 %, 37/47]).
|
||||||
|
-- Sometimes, white as a background is actually implemented using
|
||||||
|
a shade of light gray, so that a foreground white can be visible
|
||||||
|
on top of it (but most often not).
|
||||||
|
-- Sometimes, black as a foreground is actually implemented using
|
||||||
|
a shade of dark gray, so that it can be visible on top of a
|
||||||
|
background black (but most often not).
|
||||||
|
-- Sometimes, more colors are available, as extensions.
|
||||||
|
-- Other attributes can be selected/deselected (bold [1/22],
|
||||||
|
underline [4/24], standout/inverse [7/27], blink [5/25], and
|
||||||
|
invisible/hidden [8/28]). They are sometimes implemented by
|
||||||
|
using colors instead of what their names imply; e.g., bold is
|
||||||
|
often achieved by using brighter colors. In practice, only bold
|
||||||
|
is really available to us, underline sometimes being mapped by
|
||||||
|
the terminal to some strange color choice, and standout best
|
||||||
|
being left for use by downstream programs such as less(1).
|
||||||
|
-- We cannot assume that any of the extensions or special features
|
||||||
|
are available for the purpose of choosing defaults for everyone.
|
||||||
|
-- The most prevalent default terminal backgrounds are pure black
|
||||||
|
and pure white, and are not necessarily the same shades of
|
||||||
|
those as if they were selected explicitly with SGR sequences.
|
||||||
|
Some terminals use dark or light pictures as default background,
|
||||||
|
but those are covered over by an explicit selection of background
|
||||||
|
color with an SGR sequence; their users will appreciate their
|
||||||
|
background pictures not be covered like this, if possible.
|
||||||
|
-- Some uses of colors attributes is to make some output items
|
||||||
|
more understated (e.g., context lines); this cannot be achieved
|
||||||
|
by changing the background color.
|
||||||
|
-- For these reasons, the GCC color defaults should strive not
|
||||||
|
to change the background color from its default, unless it's
|
||||||
|
for a short item that should be highlighted, not understated.
|
||||||
|
-- The GCC foreground color defaults (without an explicitly set
|
||||||
|
background) should provide enough contrast to be readable on any
|
||||||
|
terminal with either a black (dark) or white (light) background.
|
||||||
|
This only leaves red, magenta, green, and cyan (and their bold
|
||||||
|
counterparts) and possibly bold blue. */
|
||||||
|
/* Default colors. The user can overwrite them using environment
|
||||||
|
variable GCC_COLORS. */
|
||||||
|
struct color_cap
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *val;
|
||||||
|
unsigned char name_len;
|
||||||
|
bool free_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For GCC_COLORS. */
|
||||||
|
static struct color_cap color_dict[] =
|
||||||
|
{
|
||||||
|
{ "error", SGR_SEQ (COLOR_BOLD COLOR_SEPARATOR COLOR_FG_RED), 5, false },
|
||||||
|
{ "warning", SGR_SEQ (COLOR_BOLD COLOR_SEPARATOR COLOR_FG_MAGENTA),
|
||||||
|
7, false },
|
||||||
|
{ "note", SGR_SEQ (COLOR_BOLD COLOR_SEPARATOR COLOR_FG_CYAN), 4, false },
|
||||||
|
{ "caret", SGR_SEQ (COLOR_BOLD COLOR_SEPARATOR COLOR_FG_GREEN), 5, false },
|
||||||
|
{ "locus", SGR_SEQ (COLOR_BOLD), 5, false },
|
||||||
|
{ "quote", SGR_SEQ (COLOR_BOLD), 5, false },
|
||||||
|
{ NULL, NULL, 0, false }
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *
|
||||||
|
colorize_start (bool show_color, const char *name, size_t name_len)
|
||||||
|
{
|
||||||
|
struct color_cap const *cap;
|
||||||
|
|
||||||
|
if (!show_color)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
for (cap = color_dict; cap->name; cap++)
|
||||||
|
if (cap->name_len == name_len
|
||||||
|
&& memcmp (cap->name, name, name_len) == 0)
|
||||||
|
break;
|
||||||
|
if (cap->name == NULL)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return cap->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
colorize_stop (bool show_color)
|
||||||
|
{
|
||||||
|
return show_color ? SGR_RESET : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse GCC_COLORS. The default would look like:
|
||||||
|
GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
|
||||||
|
No character escaping is needed or supported. */
|
||||||
|
static bool
|
||||||
|
parse_gcc_colors (void)
|
||||||
|
{
|
||||||
|
const char *p, *q, *name, *val;
|
||||||
|
char *b;
|
||||||
|
size_t name_len = 0, val_len = 0;
|
||||||
|
|
||||||
|
p = getenv ("GCC_COLORS"); /* Plural! */
|
||||||
|
if (p == NULL)
|
||||||
|
return true;
|
||||||
|
if (*p == '\0')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
name = q = p;
|
||||||
|
val = NULL;
|
||||||
|
/* From now on, be well-formed or you're gone. */
|
||||||
|
for (;;)
|
||||||
|
if (*q == ':' || *q == '\0')
|
||||||
|
{
|
||||||
|
struct color_cap *cap;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
val_len = q - val;
|
||||||
|
else
|
||||||
|
name_len = q - name;
|
||||||
|
/* Empty name without val (empty cap)
|
||||||
|
won't match and will be ignored. */
|
||||||
|
for (cap = color_dict; cap->name; cap++)
|
||||||
|
if (cap->name_len == name_len
|
||||||
|
&& memcmp (cap->name, name, name_len) == 0)
|
||||||
|
break;
|
||||||
|
/* If name unknown, go on for forward compatibility. */
|
||||||
|
if (cap->val && val)
|
||||||
|
{
|
||||||
|
if (cap->free_val)
|
||||||
|
free (CONST_CAST (char *, cap->val));
|
||||||
|
b = XNEWVEC (char, val_len + sizeof (SGR_SEQ ("")));
|
||||||
|
memcpy (b, SGR_START, strlen (SGR_START));
|
||||||
|
memcpy (b + strlen (SGR_START), val, val_len);
|
||||||
|
memcpy (b + strlen (SGR_START) + val_len, SGR_END,
|
||||||
|
sizeof (SGR_END));
|
||||||
|
cap->val = (const char *) b;
|
||||||
|
cap->free_val = true;
|
||||||
|
}
|
||||||
|
if (*q == '\0')
|
||||||
|
return true;
|
||||||
|
name = ++q;
|
||||||
|
val = NULL;
|
||||||
|
}
|
||||||
|
else if (*q == '=')
|
||||||
|
{
|
||||||
|
if (q == name || val)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
name_len = q - name;
|
||||||
|
val = ++q; /* Can be the empty string. */
|
||||||
|
}
|
||||||
|
else if (val == NULL)
|
||||||
|
q++; /* Accumulate name. */
|
||||||
|
else if (*q == ';' || (*q >= '0' && *q <= '9'))
|
||||||
|
q++; /* Accumulate val. Protect the terminal from being sent
|
||||||
|
garbage. */
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static bool
|
||||||
|
should_colorize (void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
colorize_init (void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Return true if we should use color when in auto mode, false otherwise. */
|
||||||
|
static bool
|
||||||
|
should_colorize (void)
|
||||||
|
{
|
||||||
|
char const *t = getenv ("TERM");
|
||||||
|
return t && strcmp (t, "dumb") != 0 && isatty (STDERR_FILENO);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
colorize_init (diagnostic_color_rule_t rule)
|
||||||
|
{
|
||||||
|
switch (rule)
|
||||||
|
{
|
||||||
|
case DIAGNOSTICS_COLOR_NO:
|
||||||
|
return false;
|
||||||
|
case DIAGNOSTICS_COLOR_YES:
|
||||||
|
return parse_gcc_colors ();
|
||||||
|
case DIAGNOSTICS_COLOR_AUTO:
|
||||||
|
if (should_colorize ())
|
||||||
|
return parse_gcc_colors ();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Based on code from: */
|
||||||
|
/* grep.c - main driver file for grep.
|
||||||
|
Copyright (C) 1992, 1997-2002, 2004-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||||
|
02110-1301, USA.
|
||||||
|
|
||||||
|
Written July 1992 by Mike Haertel. */
|
||||||
|
|
||||||
|
#ifndef GCC_DIAGNOSTIC_COLOR_H
|
||||||
|
#define GCC_DIAGNOSTIC_COLOR_H
|
||||||
|
|
||||||
|
/* How often diagnostics are prefixed by their locations:
|
||||||
|
o DIAGNOSTICS_SHOW_PREFIX_NEVER: never - not yet supported;
|
||||||
|
o DIAGNOSTICS_SHOW_PREFIX_ONCE: emit only once;
|
||||||
|
o DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: emit each time a physical
|
||||||
|
line is started. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIAGNOSTICS_COLOR_NO = 0,
|
||||||
|
DIAGNOSTICS_COLOR_YES = 1,
|
||||||
|
DIAGNOSTICS_COLOR_AUTO = 2
|
||||||
|
} diagnostic_color_rule_t;
|
||||||
|
|
||||||
|
const char *colorize_start (bool, const char *, size_t);
|
||||||
|
const char *colorize_stop (bool);
|
||||||
|
bool colorize_init (diagnostic_color_rule_t);
|
||||||
|
|
||||||
|
inline const char *
|
||||||
|
colorize_start (bool show_color, const char *name)
|
||||||
|
{
|
||||||
|
return colorize_start (show_color, name, strlen (name));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! GCC_DIAGNOSTIC_COLOR_H */
|
||||||
Loading…
Reference in New Issue