Patchwork color diagnostics markers

login
register
mail settings
Submitter Jakub Jelinek
Date April 9, 2013, 1:21 p.m.
Message ID <20130409132143.GV20334@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/235081/
State New
Headers show

Comments

Jakub Jelinek - April 9, 2013, 1:21 p.m.
On Mon, Apr 08, 2013 at 03:23:01PM +0200, Jakub Jelinek wrote:
> Anyway, I've kept the default as never for now.

Here is an updated patch with %r/%R, fully bootstrapped/regtested now
on x86_64-linux and i686-linux, tested on a couple of small testcases
with -fdiagnostics-color{,=never,=auto,=always}, without GCC_COLORS
in environment, with GCC_COLORS= or with
GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01;33:quote=01;34'
and both on my default gnome-terminal settings ("Linux console" colors with
white on black) and on default configured xterm (i.e. xterm colors, black on
white).  The default is still -fdiagnostics-color=never, can be changed
later on.

Ok for trunk?

2013-04-09  Manuel López-Ibáñez  <manu@gcc.gnu.org>
	    Jakub Jelinek  <jakub@redhat.com>

	* 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.



	Jakub
Jason Merrill - April 9, 2013, 3:06 p.m.
Looks good to me if nobody else has comments.

Jason
Manuel López-Ibáñez - April 10, 2013, 6:42 p.m.
On 9 April 2013 15:21, Jakub Jelinek <jakub@redhat.com> wrote:
> white).  The default is still -fdiagnostics-color=never, can be changed
> later on.

Apart from my comments elsewhere
(http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00614.html), the patch
looks fine to me. But perhaps we should change the default to auto, at
least during Stage 1, to find out whether some bug was introduced. If
agreed, I could do this in a follow-up patch that also disables colors
for the testsuite.

Cheers,

Manuel.
Gabriel Dos Reis - April 11, 2013, 1:54 a.m.
On Wed, Apr 10, 2013 at 1:42 PM, Manuel López-Ibáñez
<lopezibanez@gmail.com> wrote:
> On 9 April 2013 15:21, Jakub Jelinek <jakub@redhat.com> wrote:
>> white).  The default is still -fdiagnostics-color=never, can be changed
>> later on.
>
> Apart from my comments elsewhere
> (http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00614.html), the patch
> looks fine to me. But perhaps we should change the default to auto, at
> least during Stage 1, to find out whether some bug was introduced. If
> agreed, I could do this in a follow-up patch that also disables colors
> for the testsuite.
>
> Cheers,
>
> Manuel.

I am still of the opinion that the default should be discussed differently,
and I strongly suggest that it defaults to "never".  I do not believe we do
need to do otherwise now.

As I stated before, our pursuit of enabling everything new thing by default
may have made C++ diagnostics more terrifying.

-- Gaby
Richard Guenther - April 11, 2013, 8:24 a.m.
On Thu, Apr 11, 2013 at 3:54 AM, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:
> On Wed, Apr 10, 2013 at 1:42 PM, Manuel López-Ibáñez
> <lopezibanez@gmail.com> wrote:
>> On 9 April 2013 15:21, Jakub Jelinek <jakub@redhat.com> wrote:
>>> white).  The default is still -fdiagnostics-color=never, can be changed
>>> later on.
>>
>> Apart from my comments elsewhere
>> (http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00614.html), the patch
>> looks fine to me. But perhaps we should change the default to auto, at
>> least during Stage 1, to find out whether some bug was introduced. If
>> agreed, I could do this in a follow-up patch that also disables colors
>> for the testsuite.
>>
>> Cheers,
>>
>> Manuel.
>
> I am still of the opinion that the default should be discussed differently,
> and I strongly suggest that it defaults to "never".  I do not believe we do
> need to do otherwise now.
>
> As I stated before, our pursuit of enabling everything new thing by default
> may have made C++ diagnostics more terrifying.

;)

Eventually add a configure switch to allow vendors to change the default.

Richard.

> -- Gaby
Manuel López-Ibáñez - April 11, 2013, 2:10 p.m.
On 11 April 2013 03:54, Gabriel Dos Reis <gdr@integrable-solutions.net> wrote:
> As I stated before, our pursuit of enabling everything new thing by default
> may have made C++ diagnostics more terrifying.

Do you have examples of C++ diagnostics that are more terrifying now
than in, say, GCC 4.2?

Cheers,

Manuel.
Marc Glisse - April 14, 2013, 9:53 p.m.
On Wed, 10 Apr 2013, Gabriel Dos Reis wrote:

> On Wed, Apr 10, 2013 at 1:42 PM, Manuel López-Ibáñez
> <lopezibanez@gmail.com> wrote:
>> On 9 April 2013 15:21, Jakub Jelinek <jakub@redhat.com> wrote:
>>> white).  The default is still -fdiagnostics-color=never, can be changed
>>> later on.
>>
>> Apart from my comments elsewhere
>> (http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00614.html), the patch
>> looks fine to me. But perhaps we should change the default to auto, at
>> least during Stage 1, to find out whether some bug was introduced. If
>> agreed, I could do this in a follow-up patch that also disables colors
>> for the testsuite.
>>
>> Cheers,
>>
>> Manuel.
>
> I am still of the opinion that the default should be discussed differently,
> and I strongly suggest that it defaults to "never".  I do not believe we do
> need to do otherwise now.
>
> As I stated before, our pursuit of enabling everything new thing by default
> may have made C++ diagnostics more terrifying.

Hello,

I would like to suggest that the default be "auto" when the environment 
variable GCC_COLORS is defined. It can stay "never" otherwise (I would 
prefer "auto" as well, colors don't make the diagnostics any longer, only 
more readable, and an empty GCC_COLORS is an easy way to disable them, but 
I see you have a strong opinion on this so I won't insist).

Defining a variable in my environment counts as a clear intention. And 
without it, if I want to always use colors, I need to either type the 
option every time, or create wrappers for every version of every front-end 
that I use.

For grep, I can have colors by default with GREP_OPTIONS=--color=auto. Any 
alternative mean to enable colors by default would be ok with me.

By the way, I was unlucky enough to try colors by compiling a non-existing 
file, but this message doesn't get any colors:

g++: error: zz.cc: No such file or directory
g++: fatal error: no input files

(not that it needs them, it is short enough)
Gabriel Dos Reis - April 15, 2013, 9:14 a.m.
On Sun, Apr 14, 2013 at 4:53 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Wed, 10 Apr 2013, Gabriel Dos Reis wrote:
>
>> On Wed, Apr 10, 2013 at 1:42 PM, Manuel López-Ibáñez
>> <lopezibanez@gmail.com> wrote:
>>>
>>> On 9 April 2013 15:21, Jakub Jelinek <jakub@redhat.com> wrote:
>>>>
>>>> white).  The default is still -fdiagnostics-color=never, can be changed
>>>> later on.
>>>
>>>
>>> Apart from my comments elsewhere
>>> (http://gcc.gnu.org/ml/gcc-patches/2013-04/msg00614.html), the patch
>>> looks fine to me. But perhaps we should change the default to auto, at
>>> least during Stage 1, to find out whether some bug was introduced. If
>>> agreed, I could do this in a follow-up patch that also disables colors
>>> for the testsuite.
>>>
>>> Cheers,
>>>
>>> Manuel.
>>
>>
>> I am still of the opinion that the default should be discussed
>> differently,
>> and I strongly suggest that it defaults to "never".  I do not believe we
>> do
>> need to do otherwise now.
>>
>> As I stated before, our pursuit of enabling everything new thing by
>> default
>> may have made C++ diagnostics more terrifying.
>
>
> Hello,
>
> I would like to suggest that the default be "auto" when the environment
> variable GCC_COLORS is defined. It can stay "never" otherwise (I would
> prefer "auto" as well, colors don't make the diagnostics any longer, only
> more readable, and an empty GCC_COLORS is an easy way to disable them, but I
> see you have a strong opinion on this so I won't insist).

Everybody has got strong opinions, especially those who are
eager to label others as having one.

> Defining a variable in my environment counts as a clear intention.

If you invoke GCC on command line with explicit option requesting
colors, I don't think there is any doubt that.  However, I dispute the
intent to be so universally clear for most GCC users who happen to have
GCC_COLORS set -- most users inherit whatever their sysadmin or
distros set for them.

That said, I am fine with the idea to GCC_COLORS => detect.

-- Gaby

Patch

--- gcc/opts.c.jj	2013-04-09 08:34:52.577866059 +0200
+++ gcc/opts.c	2013-04-09 08:35:02.879844677 +0200
@@ -30,6 +30,7 @@  along with GCC; see the file COPYING3.
 #include "flags.h"
 #include "params.h"
 #include "diagnostic.h"
+#include "diagnostic-color.h"
 #include "opts-diagnostic.h"
 #include "insn-attr-common.h"
 #include "common/common-target.h"
@@ -1497,6 +1498,11 @@  common_handle_option (struct gcc_options
       dc->show_caret = value;
       break;
 
+    case OPT_fdiagnostics_color_:
+      pp_show_color (dc->printer)
+	= colorize_init ((diagnostic_color_rule_t) value);
+      break;
+
     case OPT_fdiagnostics_show_option:
       dc->show_option_requested = value;
       break;
--- gcc/Makefile.in.jj	2013-04-09 08:34:52.554866101 +0200
+++ gcc/Makefile.in	2013-04-09 08:35:02.881844586 +0200
@@ -1465,7 +1465,7 @@  OBJS = \
 
 # Objects in libcommon.a, potentially used by all host binaries and with
 # no target dependencies.
-OBJS-libcommon = diagnostic.o pretty-print.o intl.o input.o version.o
+OBJS-libcommon = diagnostic.o diagnostic-color.o pretty-print.o intl.o input.o version.o
 
 # Objects in libcommon-target.a, used by drivers and by the core
 # compiler and containing target-dependent code.
@@ -2668,11 +2668,12 @@  fold-const.o : fold-const.c $(CONFIG_H)
    $(GIMPLE_H) realmpfr.h $(TREE_FLOW_H)
 diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    version.h $(DEMANGLE_H) $(INPUT_H) intl.h $(BACKTRACE_H) $(DIAGNOSTIC_H) \
-   diagnostic.def
+   diagnostic.def diagnostic-color.h
+diagnostic-color.o : diagnostic-color.c $(CONFIG_H) $(SYSTEM_H) diagnostic-color.h
 opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(DUMPFILE_H) $(TM_H) \
    $(DIAGNOSTIC_H) insn-attr-common.h intl.h $(COMMON_TARGET_H) \
-   $(FLAGS_H) $(PARAMS_H) opts-diagnostic.h
+   $(FLAGS_H) $(PARAMS_H) opts-diagnostic.h diagnostic-color.h
 opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(DIAGNOSTIC_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TREE_H) langhooks.h \
    $(TM_H) $(RTL_H) $(DBGCNT_H) debug.h $(LTO_STREAMER_H) output.h \
@@ -3434,7 +3435,8 @@  params.o : params.c $(CONFIG_H) $(SYSTEM
    $(PARAMS_H) $(DIAGNOSTIC_CORE_H)
 pointer-set.o: pointer-set.c pointer-set.h $(CONFIG_H) $(SYSTEM_H)
 hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H)
-pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H)
+pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H) \
+   diagnostic-color.h
 errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h
 dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
     $(DIAGNOSTIC_CORE_H) $(DBGCNT_H)
--- gcc/common.opt.jj	2013-04-09 08:34:52.590866035 +0200
+++ gcc/common.opt	2013-04-09 08:35:02.883844504 +0200
@@ -1028,6 +1028,30 @@  fdiagnostics-show-caret
 Common Var(flag_diagnostics_show_caret) Init(1)
 Show the source line with a caret indicating the column
 
+fdiagnostics-color
+Common Alias(fdiagnostics-color=,always,never)
+;
+
+fdiagnostics-color=
+Common Joined RejectNegative Enum(diagnostic_color_rule)
+-fdiagnostics-color=[never|always|auto]	Colorize diagnostics
+
+; Required for these enum values.
+SourceInclude
+diagnostic-color.h
+
+Enum
+Name(diagnostic_color_rule) Type(int)
+
+EnumValue
+Enum(diagnostic_color_rule) String(never) Value(DIAGNOSTICS_COLOR_NO)
+
+EnumValue
+Enum(diagnostic_color_rule) String(always) Value(DIAGNOSTICS_COLOR_YES)
+
+EnumValue
+Enum(diagnostic_color_rule) String(auto) Value(DIAGNOSTICS_COLOR_AUTO)
+
 fdiagnostics-show-option
 Common Var(flag_diagnostics_show_option) Init(1)
 Amend appropriate diagnostic messages with the command line option that controls them
--- gcc/dwarf2out.c.jj	2013-04-09 08:34:52.805865640 +0200
+++ gcc/dwarf2out.c	2013-04-09 08:35:02.890844285 +0200
@@ -18828,6 +18828,7 @@  gen_producer_string (void)
       case OPT_fdiagnostics_show_location_:
       case OPT_fdiagnostics_show_option:
       case OPT_fdiagnostics_show_caret:
+      case OPT_fdiagnostics_color_:
       case OPT_fverbose_asm:
       case OPT____:
       case OPT__sysroot_:
--- gcc/cp/error.c.jj	2013-04-09 08:34:52.565866081 +0200
+++ gcc/cp/error.c	2013-04-09 08:43:59.987970731 +0200
@@ -3022,14 +3022,14 @@  cp_print_error_function (diagnostic_cont
 		    {
 		      if (context->show_column && s.column != 0)
 			pp_printf (context->printer,
-				   _("    inlined from %qs at %s:%d:%d"),
+				   _("    inlined from %qs at %r%s:%d:%d%R"),
 				   cxx_printable_name_translate (fndecl, 2),
-				   s.file, s.line, s.column);
+				   "locus", s.file, s.line, s.column);
 		      else
 			pp_printf (context->printer,
-				   _("    inlined from %qs at %s:%d"),
+				   _("    inlined from %qs at %r%s:%d%R"),
 				   cxx_printable_name_translate (fndecl, 2),
-				   s.file, s.line);
+				   "locus", s.file, s.line);
 
 		    }
 		  else
@@ -3111,11 +3111,11 @@  print_instantiation_partial_context_line
   xloc = expand_location (loc);
 
   if (context->show_column)
-    pp_verbatim (context->printer, _("%s:%d:%d:   "),
-		 xloc.file, xloc.line, xloc.column);
+    pp_verbatim (context->printer, _("%r%s:%d:%d:%R   "),
+		 "locus", xloc.file, xloc.line, xloc.column);
   else
-    pp_verbatim (context->printer, _("%s:%d:   "),
-		 xloc.file, xloc.line);
+    pp_verbatim (context->printer, _("%r%s:%d:%R   "),
+		 "locus", xloc.file, xloc.line);
 
   if (t != NULL)
     {
@@ -3189,14 +3189,16 @@  print_instantiation_partial_context (dia
 	  xloc = expand_location (loc);
 	  if (context->show_column)
 	    pp_verbatim (context->printer,
-			 _("%s:%d:%d:   [ skipping %d instantiation contexts, "
-			   "use -ftemplate-backtrace-limit=0 to disable ]\n"),
-			 xloc.file, xloc.line, xloc.column, skip);
+			 _("%r%s:%d:%d:%R   [ skipping %d instantiation "
+			   "contexts, use -ftemplate-backtrace-limit=0 to "
+			   "disable ]\n"),
+			 "locus", xloc.file, xloc.line, xloc.column, skip);
 	  else
 	    pp_verbatim (context->printer,
-			 _("%s:%d:   [ skipping %d instantiation contexts, "
-			   "use -ftemplate-backtrace-limit=0 to disable ]\n"),
-			 xloc.file, xloc.line, skip);
+			 _("%r%s:%d:%R   [ skipping %d instantiation "
+			   "contexts, use -ftemplate-backtrace-limit=0 to "
+			   "disable ]\n"),
+			 "locus", xloc.file, xloc.line, skip);
 	  
 	  do {
 	    loc = t->locus;
@@ -3258,12 +3260,12 @@  maybe_print_constexpr_context (diagnosti
       const char *s = expr_as_string (t, 0);
       if (context->show_column)
 	pp_verbatim (context->printer,
-		     _("%s:%d:%d:   in constexpr expansion of %qs"),
-		     xloc.file, xloc.line, xloc.column, s);
+		     _("%r%s:%d:%d:%R   in constexpr expansion of %qs"),
+		     "locus", xloc.file, xloc.line, xloc.column, s);
       else
 	pp_verbatim (context->printer,
-		     _("%s:%d:   in constexpr expansion of %qs"),
-		     xloc.file, xloc.line, s);
+		     _("%r%s:%d:%R   in constexpr expansion of %qs"),
+		     "locus", xloc.file, xloc.line, s);
       pp_base_newline (context->printer);
     }
 }
--- gcc/langhooks.c.jj	2013-04-09 08:34:52.810865630 +0200
+++ gcc/langhooks.c	2013-04-09 08:41:39.842774404 +0200
@@ -452,14 +452,14 @@  lhd_print_error_function (diagnostic_con
 		    {
 		      if (context->show_column)
 			pp_printf (context->printer,
-				   _("    inlined from %qs at %s:%d:%d"),
+				   _("    inlined from %qs at %r%s:%d:%d%R"),
 				   identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)),
-				   s.file, s.line, s.column);
+				   "locus", s.file, s.line, s.column);
 		      else
 			pp_printf (context->printer,
-				   _("    inlined from %qs at %s:%d"),
+				   _("    inlined from %qs at %r%s:%d%R"),
 				   identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)),
-				   s.file, s.line);
+				   "locus", s.file, s.line);
 
 		    }
 		  else
--- gcc/diagnostic.def.jj	2013-04-09 08:34:52.786865674 +0200
+++ gcc/diagnostic.def	2013-04-09 08:35:02.894844189 +0200
@@ -22,26 +22,26 @@  along with GCC; see the file COPYING3.
    kind specified.  I.e. they're uninitialized.  Within the diagnostic
    machinery, this kind also means "don't change the existing kind",
    meaning "no change is specified".  */
-DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "")
+DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "", NULL)
 
 /* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
    This is used by the diagnostic machinery when it wants to disable a
    diagnostic without disabling the option which causes it.  */
-DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "")
+DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "", NULL)
 
 /* The remainder are real diagnostic types.  */
-DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ")
-DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ")
-DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ")
-DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")
-DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ")
-DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ")
-DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ")
-DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug: ")
+DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ", "error")
+DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ", "warning")
+DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ", "warning")
+DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ", "note")
+DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug: ", "note")
 /* These two would be re-classified as DK_WARNING or DK_ERROR, so the
 prefix does not matter.  */
-DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn: ")
-DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror: ")
+DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn: ", NULL)
+DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror: ", NULL)
 /* This one is just for counting DK_WARNING promoted to DK_ERROR
    due to -Werror and -Werror=warning.  */
-DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error: ")
+DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error: ", NULL)
--- gcc/diagnostic-color.c.jj	2013-04-09 08:35:02.895844155 +0200
+++ gcc/diagnostic-color.c	2013-04-09 08:35:02.895844155 +0200
@@ -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
--- gcc/diagnostic-color.h.jj	2013-04-09 08:35:02.895844155 +0200
+++ gcc/diagnostic-color.h	2013-04-09 08:35:02.895844155 +0200
@@ -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 */
--- gcc/diagnostic-core.h.jj	2013-04-09 08:34:52.559866092 +0200
+++ gcc/diagnostic-core.h	2013-04-09 08:35:02.895844155 +0200
@@ -28,7 +28,7 @@  along with GCC; see the file COPYING3.
 /* Constants used to discriminate diagnostics.  */
 typedef enum
 {
-#define DEFINE_DIAGNOSTIC_KIND(K, msgid) K,
+#define DEFINE_DIAGNOSTIC_KIND(K, msgid, C) K,
 #include "diagnostic.def"
 #undef DEFINE_DIAGNOSTIC_KIND
   DK_LAST_DIAGNOSTIC_KIND,
--- gcc/doc/invoke.texi.jj	2013-04-09 08:34:52.592866031 +0200
+++ gcc/doc/invoke.texi	2013-04-09 08:35:02.898844073 +0200
@@ -226,6 +226,7 @@  Objective-C and Objective-C++ Dialects}.
 @xref{Language Independent Options,,Options to Control Diagnostic Messages Formatting}.
 @gccoptlist{-fmessage-length=@var{n}  @gol
 -fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]}  @gol
+-fdiagnostics-color=@r{[}auto@r{|}never@r{|}always@r{]}  @gol
 -fno-diagnostics-show-option -fno-diagnostics-show-caret}
 
 @item Warning Options
@@ -2956,6 +2957,76 @@  messages reporter to emit the same sourc
 prefix) for physical lines that result from the process of breaking
 a message which is too long to fit on a single line.
 
+@item -fdiagnostics-color[=@var{WHEN}]
+@itemx -fno-diagnostics-color
+@opindex fdiagnostics-color
+@cindex highlight, color, colour
+@vindex GCC_COLORS @r{environment variable}
+Use color in diagnostics.  @var{WHEN} is @samp{never}, @samp{always},
+or @samp{auto}.  The default is @samp{auto}, which means to use color
+only when the stdandard error is a terminal. The forms
+@option{-fdiagnostics-color} and @option{-fno-diagnostics-color} are
+aliases for @option{-fdiagnostics-color=always} and
+@option{-fdiagnostics-color=never}, respectively.
+
+The colors are defined by the environment variable @env{GCC_COLORS}.
+Its value is a colon-separated list of capabilities and Select Graphic
+Rendition (SGR) substrings. SGR commands are interpreted by the
+terminal or terminal emulator.  (See the section in the documentation
+of your text terminal for permitted values and their meanings as
+character attributes.)  These substring values are integers in decimal
+representation and can be concatenated with semicolons.
+Common values to concatenate include
+@samp{1} for bold,
+@samp{4} for underline,
+@samp{5} for blink,
+@samp{7} for inverse,
+@samp{39} for default foreground color,
+@samp{30} to @samp{37} for foreground colors,
+@samp{90} to @samp{97} for 16-color mode foreground colors,
+@samp{38;5;0} to @samp{38;5;255}
+for 88-color and 256-color modes foreground colors,
+@samp{49} for default background color,
+@samp{40} to @samp{47} for background colors,
+@samp{100} to @samp{107} for 16-color mode background colors,
+and @samp{48;5;0} to @samp{48;5;255}
+for 88-color and 256-color modes background colors.
+
+The default @env{GCC_COLORS} is
+@samp{error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01}
+where @samp{01;31} is bold red, @samp{01;35} is bold magenta,
+@samp{01;36} is bold cyan, @samp{01;32} is bold green and
+@samp{01} is bold. Setting @env{GCC_COLORS} to the empty
+string disables colors.
+Supported capabilities are as follows.
+
+@table @code
+@item error=
+@vindex error GREP_COLORS @r{capability}
+SGR substring for error: markers.
+
+@item warning=
+@vindex warning GREP_COLORS @r{capability}
+SGR substring for warning: markers.
+
+@item note=
+@vindex note GREP_COLORS @r{capability}
+SGR substring for note: markers.
+
+@item caret=
+@vindex caret GREP_COLORS @r{capability}
+SGR substring for caret line.
+
+@item locus=
+@vindex locus GREP_COLORS @r{capability}
+SGR substring for location information, @samp{file:line} or
+@samp{file:line:column} etc.
+
+@item quote=
+@vindex quote GREP_COLORS @r{capability}
+SGR substring for information printed within quotes.
+@end table
+
 @item -fno-diagnostics-show-option
 @opindex fno-diagnostics-show-option
 @opindex fdiagnostics-show-option
--- gcc/pretty-print.h.jj	2013-04-09 08:34:52.850865557 +0200
+++ gcc/pretty-print.h	2013-04-09 08:35:02.901844018 +0200
@@ -151,6 +151,9 @@  typedef bool (*printer_fn) (pretty_print
    output.  */
 #define pp_translate_identifiers(PP) pp_base (PP)->translate_identifiers
 
+/* True if colors should be shown.  */
+#define pp_show_color(PP) pp_base (PP)->show_color
+
 /* The data structure that contains the bare minimum required to do
    proper pretty-printing.  Clients may derived from this structure
    and add additional fields they need.  */
@@ -194,6 +197,9 @@  struct pretty_print_info
   /* Nonzero means identifiers are translated to the locale character
      set on output.  */
   bool translate_identifiers;
+
+  /* Nonzero means that text should be colorized.  */
+  bool show_color;
 };
 
 #define pp_set_line_maximum_length(PP, L) \
--- gcc/diagnostic.c.jj	2013-04-09 08:34:52.838865579 +0200
+++ gcc/diagnostic.c	2013-04-09 08:35:02.902844004 +0200
@@ -31,6 +31,7 @@  along with GCC; see the file COPYING3.
 #include "intl.h"
 #include "backtrace.h"
 #include "diagnostic.h"
+#include "diagnostic-color.h"
 
 #define pedantic_warning_kind(DC)			\
   ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
@@ -53,7 +54,6 @@  const char *progname;
 /* A diagnostic_context surrogate for stderr.  */
 static diagnostic_context global_diagnostic_context;
 diagnostic_context *global_dc = &global_diagnostic_context;
-
 
 /* Return a malloc'd string containing MSG formatted a la printf.  The
    caller is responsible for freeing the memory.  */
@@ -210,12 +210,31 @@  diagnostic_build_prefix (diagnostic_cont
 			 const diagnostic_info *diagnostic)
 {
   static const char *const diagnostic_kind_text[] = {
-#define DEFINE_DIAGNOSTIC_KIND(K, T) (T),
+#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
 #include "diagnostic.def"
 #undef DEFINE_DIAGNOSTIC_KIND
     "must-not-happen"
   };
+  static const char *const diagnostic_kind_color[] = {
+#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
+#include "diagnostic.def"
+#undef DEFINE_DIAGNOSTIC_KIND
+    NULL
+  };
   const char *text = _(diagnostic_kind_text[diagnostic->kind]);
+  const char *text_cs = "", *text_ce = "";
+  const char *locus_cs, *locus_ce;
+  pretty_printer *pp = context->printer;
+
+  if (diagnostic_kind_color[diagnostic->kind])
+    {
+      text_cs = colorize_start (pp_show_color (pp),
+				diagnostic_kind_color[diagnostic->kind]);
+      text_ce = colorize_stop (pp_show_color (pp));
+    }
+  locus_cs = colorize_start (pp_show_color (pp), "locus");
+  locus_ce = colorize_stop (pp_show_color (pp));
+
   expanded_location s = expand_location_to_spelling_point (diagnostic->location);
   if (diagnostic->override_column)
     s.column = diagnostic->override_column;
@@ -223,10 +242,13 @@  diagnostic_build_prefix (diagnostic_cont
 
   return
     (s.file == NULL
-     ? build_message_string ("%s: %s", progname, text)
+     ? build_message_string ("%s%s:%s %s%s%s", locus_cs, progname, locus_ce,
+			     text_cs, text, text_ce)
      : context->show_column
-     ? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text)
-     : build_message_string ("%s:%d: %s", s.file, s.line, text));
+     ? build_message_string ("%s%s:%d:%d:%s %s%s%s", locus_cs, s.file, s.line,
+			     s.column, locus_ce, text_cs, text, text_ce)
+     : build_message_string ("%s%s:%d:%s %s%s%s", locus_cs, s.file, s.line, locus_ce,
+			     text_cs, text, text_ce));
 }
 
 /* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than
@@ -262,7 +284,7 @@  diagnostic_show_locus (diagnostic_contex
   expanded_location s;
   int max_width;
   const char *saved_prefix;
-
+  const char *caret_cs, *caret_ce;
 
   if (!context->show_caret
       || diagnostic->location <= BUILTINS_LOCATION
@@ -290,9 +312,13 @@  diagnostic_show_locus (diagnostic_contex
       line++;
     }
   pp_newline (context->printer);
+  caret_cs = colorize_start (pp_show_color (context->printer), "caret");
+  caret_ce = colorize_stop (pp_show_color (context->printer));
+
   /* pp_printf does not implement %*c.  */
-  buffer = XALLOCAVEC (char, s.column + 3);
-  snprintf (buffer, s.column + 3, " %*c", s.column, '^');
+  size_t len = s.column + 3 + strlen (caret_cs) + strlen (caret_ce);
+  buffer = XALLOCAVEC (char, len);
+  snprintf (buffer, len, "%s %*c%s", caret_cs, s.column, '^', caret_ce);
   pp_string (context->printer, buffer);
   pp_set_prefix (context->printer, saved_prefix);
 }
--- gcc/c-family/c-format.c.jj	2013-04-08 15:38:20.000000000 +0200
+++ gcc/c-family/c-format.c	2013-04-09 08:54:21.787406190 +0200
@@ -654,9 +654,10 @@  static const format_char_info gcc_diag_c
   /* Custom conversion specifiers.  */
 
   /* These will require a "tree" at runtime.  */
-  { "K", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",    "",   NULL },
+  { "K",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",    "",   NULL },
 
-  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
+  { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "cR",   NULL },
+  { "<>'R",0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
@@ -676,9 +677,10 @@  static const format_char_info gcc_tdiag_
   /* These will require a "tree" at runtime.  */
   { "DFKTEV", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
 
-  { "v", 0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
+  { "v",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
-  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
+  { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "cR",   NULL },
+  { "<>'R",0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
@@ -698,9 +700,10 @@  static const format_char_info gcc_cdiag_
   /* These will require a "tree" at runtime.  */
   { "DEFKTV", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
 
-  { "v", 0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
+  { "v",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
-  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
+  { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "cR",   NULL },
+  { "<>'R",0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
@@ -725,7 +728,8 @@  static const format_char_info gcc_cxxdia
   /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.)  */
   { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
 
-  { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
+  { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "cR",   NULL },
+  { "<>'R",0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
   { NULL,  0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
 };
--- gcc/pretty-print.c.jj	2013-04-09 08:34:52.832865590 +0200
+++ gcc/pretty-print.c	2013-04-09 08:40:52.936044461 +0200
@@ -23,6 +23,7 @@  along with GCC; see the file COPYING3.
 #include "coretypes.h"
 #include "intl.h"
 #include "pretty-print.h"
+#include "diagnostic-color.h"
 
 #if HAVE_ICONV
 #include <iconv.h>
@@ -226,6 +227,8 @@  pp_base_indent (pretty_printer *pp)
    %c: character.
    %s: string.
    %p: pointer.
+   %r: if pp_show_color(pp), switch to color identified by const char *.
+   %R: if pp_show_color(pp), reset color.
    %m: strerror(text->err_no) - does not consume a value from args_ptr.
    %%: '%'.
    %<: opening quote.
@@ -300,18 +303,37 @@  pp_base_format (pretty_printer *pp, text
 	  continue;
 
 	case '<':
-	  obstack_grow (&buffer->chunk_obstack,
-			open_quote, strlen (open_quote));
-	  p++;
-	  continue;
+	  {
+	    obstack_grow (&buffer->chunk_obstack,
+			  open_quote, strlen (open_quote));
+	    const char *colorstr
+	      = colorize_start (pp_show_color (pp), "quote");
+	    obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
+	    p++;
+	    continue;
+	  }
 
 	case '>':
+	  {
+	    const char *colorstr = colorize_stop (pp_show_color (pp));
+	    obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
+	  }
+	  /* FALLTHRU */
 	case '\'':
 	  obstack_grow (&buffer->chunk_obstack,
 			close_quote, strlen (close_quote));
 	  p++;
 	  continue;
 
+	case 'R':
+	  {
+	    const char *colorstr = colorize_stop (pp_show_color (pp));
+	    obstack_grow (&buffer->chunk_obstack, colorstr,
+			  strlen (colorstr));
+	    p++;
+	    continue;
+	  }
+
 	case 'm':
 	  {
 	    const char *errstr = xstrerror (text->err_no);
@@ -466,10 +488,19 @@  pp_base_format (pretty_printer *pp, text
       gcc_assert (!wide || precision == 0);
 
       if (quote)
-	pp_string (pp, open_quote);
+	{
+	  pp_string (pp, open_quote);
+	  pp_string (pp, colorize_start (pp_show_color (pp), "quote"));
+	}
 
       switch (*p)
 	{
+	case 'r':
+	  pp_string (pp, colorize_start (pp_show_color (pp),
+					 va_arg (*text->args_ptr,
+						 const char *)));
+	  break;
+
 	case 'c':
 	  pp_character (pp, va_arg (*text->args_ptr, int));
 	  break;
@@ -563,7 +594,10 @@  pp_base_format (pretty_printer *pp, text
 	}
 
       if (quote)
-	pp_string (pp, close_quote);
+	{
+	  pp_string (pp, colorize_stop (pp_show_color (pp)));
+	  pp_string (pp, close_quote);
+	}
 
       obstack_1grow (&buffer->chunk_obstack, '\0');
       *formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);