OSDN Git Service

* opts.c: Include diagnostic-color.h.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Apr 2013 06:20:36 +0000 (06:20 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Apr 2013 06:20:36 +0000 (06:20 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197842 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/diagnostic-color.c [new file with mode: 0644]
gcc/diagnostic-color.h [new file with mode: 0644]

diff --git a/gcc/diagnostic-color.c b/gcc/diagnostic-color.c
new file mode 100644 (file)
index 0000000..8680b50
--- /dev/null
@@ -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
diff --git a/gcc/diagnostic-color.h b/gcc/diagnostic-color.h
new file mode 100644 (file)
index 0000000..e643e51
--- /dev/null
@@ -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 */