From c18bde808b1655f00390f490062c178c63a018b3 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 2 Sep 2015 16:34:34 -0400
Subject: [PATCH 06/41] Move diagnostic_show_locus and friends out into a new
 source file

The function "diagnostic_show_locus" gains new functionality in the
next patch, so this preliminary patch breaks it out into a new source
file, diagnostic-show-locus.c, along with a couple of related functions.

gcc/ChangeLog:
	* Makefile.in (OBJS-libcommon): Add diagnostic-show-locus.o.
	* diagnostic.c (adjust_line): Move to diagnostic-show-locus.c.
	(diagnostic_show_locus): Likewise.
	(diagnostic_print_caret_line): Likewise.
	* diagnostic-show-locus.c: New file.
---
 gcc/Makefile.in             |   3 +-
 gcc/diagnostic-show-locus.c | 166 ++++++++++++++++++++++++++++++++++++++++++++
 gcc/diagnostic.c            | 129 ----------------------------------
 3 files changed, 168 insertions(+), 130 deletions(-)
 create mode 100644 gcc/diagnostic-show-locus.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3d1c1e5..f183b22 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1512,7 +1512,8 @@ OBJS = \
 
 # Objects in libcommon.a, potentially used by all host binaries and with
 # no target dependencies.
-OBJS-libcommon = diagnostic.o diagnostic-color.o pretty-print.o intl.o \
+OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \
+	pretty-print.o intl.o \
 	vec.o input.o version.o hash-table.o ggc-none.o
 
 # Objects in libcommon-target.a, used by drivers and by the core
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
new file mode 100644
index 0000000..147a2b8
--- /dev/null
+++ b/gcc/diagnostic-show-locus.c
@@ -0,0 +1,166 @@
+/* Diagnostic subroutines for printing source-code
+   Copyright (C) 1999-2015 Free Software Foundation, Inc.
+   Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
+
+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/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "version.h"
+#include "demangle.h"
+#include "intl.h"
+#include "backtrace.h"
+#include "diagnostic.h"
+#include "diagnostic-color.h"
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#ifdef GWINSZ_IN_SYS_IOCTL
+# include <sys/ioctl.h>
+#endif
+
+/* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than
+   MAX_WIDTH by some margin, then adjust the start of the line such
+   that the COLUMN is smaller than MAX_WIDTH minus the margin.  The
+   margin is either CARET_LINE_MARGIN characters or the difference
+   between the column and the length of the line, whatever is smaller.
+   The length of LINE is given by LINE_WIDTH.  */
+static const char *
+adjust_line (const char *line, int line_width,
+	     int max_width, int *column_p)
+{
+  int right_margin = CARET_LINE_MARGIN;
+  int column = *column_p;
+
+  gcc_checking_assert (line_width >= column);
+  right_margin = MIN (line_width - column, right_margin);
+  right_margin = max_width - right_margin;
+  if (line_width >= max_width && column > right_margin)
+    {
+      line += column - right_margin;
+      *column_p = right_margin;
+    }
+  return line;
+}
+
+/* Print the physical source line corresponding to the location of
+   this diagnostic, and a caret indicating the precise column.  This
+   function only prints two caret characters if the two locations
+   given by DIAGNOSTIC are on the same line according to
+   diagnostic_same_line().  */
+void
+diagnostic_show_locus (diagnostic_context * context,
+		       const diagnostic_info *diagnostic)
+{
+  if (!context->show_caret
+      || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
+      || diagnostic_location (diagnostic, 0) == context->last_location)
+    return;
+
+  context->last_location = diagnostic_location (diagnostic, 0);
+  expanded_location s0 = diagnostic_expand_location (diagnostic, 0);
+  expanded_location s1 = { };
+  /* Zero-initialized. This is checked later by diagnostic_print_caret_line.  */
+
+  if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION)
+    s1 = diagnostic_expand_location (diagnostic, 1);
+
+  diagnostic_print_caret_line (context, s0, s1,
+			       context->caret_chars[0],
+			       context->caret_chars[1]);
+}
+
+/* Print (part) of the source line given by xloc1 with caret1 pointing
+   at the column.  If xloc2.column != 0 and it fits within the same
+   line as xloc1 according to diagnostic_same_line (), then caret2 is
+   printed at xloc2.colum.  Otherwise, the caller has to set up things
+   to print a second caret line for xloc2.  */
+void
+diagnostic_print_caret_line (diagnostic_context * context,
+			     expanded_location xloc1,
+			     expanded_location xloc2,
+			     char caret1, char caret2)
+{
+  if (!diagnostic_same_line (context, xloc1, xloc2))
+    /* This will mean ignore xloc2.  */
+    xloc2.column = 0;
+  else if (xloc1.column == xloc2.column)
+    xloc2.column++;
+
+  int cmax = MAX (xloc1.column, xloc2.column);
+  int line_width;
+  const char *line = location_get_source_line (xloc1.file, xloc1.line,
+					       &line_width);
+  if (line == NULL || cmax > line_width)
+    return;
+
+  /* Center the interesting part of the source line to fit in
+     max_width, and adjust all columns accordingly.  */
+  int max_width = context->caret_max_width;
+  int offset = (int) cmax;
+  line = adjust_line (line, line_width, max_width, &offset);
+  offset -= cmax;
+  cmax += offset;
+  xloc1.column += offset;
+  if (xloc2.column)
+    xloc2.column += offset;
+
+  /* Print the source line.  */
+  pp_newline (context->printer);
+  const char *saved_prefix = pp_get_prefix (context->printer);
+  pp_set_prefix (context->printer, NULL);
+  pp_space (context->printer);
+  while (max_width > 0 && line_width > 0)
+    {
+      char c = *line == '\t' ? ' ' : *line;
+      if (c == '\0')
+	c = ' ';
+      pp_character (context->printer, c);
+      max_width--;
+      line_width--;
+      line++;
+    }
+  pp_newline (context->printer);
+
+  /* Print the caret under the line.  */
+  const char *caret_cs, *caret_ce;
+  caret_cs = colorize_start (pp_show_color (context->printer), "caret");
+  caret_ce = colorize_stop (pp_show_color (context->printer));
+  int cmin = xloc2.column
+    ? MIN (xloc1.column, xloc2.column) : xloc1.column;
+  int caret_min = cmin == xloc1.column ? caret1 : caret2;
+  int caret_max = cmin == xloc1.column ? caret2 : caret1;
+
+  /* cmin is >= 1, but we indent with an extra space at the start like
+     we did above.  */
+  int i;
+  for (i = 0; i < cmin; i++)
+    pp_space (context->printer);
+  pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce);
+
+  if (xloc2.column)
+    {
+      for (i++; i < cmax; i++)
+	pp_space (context->printer);
+      pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce);
+    }
+  pp_set_prefix (context->printer, saved_prefix);
+  pp_needs_newline (context->printer) = true;
+}
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 74a40bb..f40e469 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -308,135 +308,6 @@ diagnostic_build_prefix (diagnostic_context *context,
 			     locus_ce, text_cs, text, text_ce));
 }
 
-/* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than
-   MAX_WIDTH by some margin, then adjust the start of the line such
-   that the COLUMN is smaller than MAX_WIDTH minus the margin.  The
-   margin is either CARET_LINE_MARGIN characters or the difference
-   between the column and the length of the line, whatever is smaller.
-   The length of LINE is given by LINE_WIDTH.  */
-static const char *
-adjust_line (const char *line, int line_width,
-	     int max_width, int *column_p)
-{
-  int right_margin = CARET_LINE_MARGIN;
-  int column = *column_p;
-
-  gcc_checking_assert (line_width >= column);
-  right_margin = MIN (line_width - column, right_margin);
-  right_margin = max_width - right_margin;
-  if (line_width >= max_width && column > right_margin)
-    {
-      line += column - right_margin;
-      *column_p = right_margin;
-    }
-  return line;
-}
-
-/* Print the physical source line corresponding to the location of
-   this diagnostic, and a caret indicating the precise column.  This
-   function only prints two caret characters if the two locations
-   given by DIAGNOSTIC are on the same line according to
-   diagnostic_same_line().  */
-void
-diagnostic_show_locus (diagnostic_context * context,
-		       const diagnostic_info *diagnostic)
-{
-  if (!context->show_caret
-      || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
-      || diagnostic_location (diagnostic, 0) == context->last_location)
-    return;
-
-  context->last_location = diagnostic_location (diagnostic, 0);
-  expanded_location s0 = diagnostic_expand_location (diagnostic, 0);
-  expanded_location s1 = { }; 
-  /* Zero-initialized. This is checked later by diagnostic_print_caret_line.  */
-
-  if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION)
-    s1 = diagnostic_expand_location (diagnostic, 1);
-
-  diagnostic_print_caret_line (context, s0, s1,
-			       context->caret_chars[0],
-			       context->caret_chars[1]);
-}
-
-/* Print (part) of the source line given by xloc1 with caret1 pointing
-   at the column.  If xloc2.column != 0 and it fits within the same
-   line as xloc1 according to diagnostic_same_line (), then caret2 is
-   printed at xloc2.colum.  Otherwise, the caller has to set up things
-   to print a second caret line for xloc2.  */
-void
-diagnostic_print_caret_line (diagnostic_context * context,
-			     expanded_location xloc1,
-			     expanded_location xloc2,
-			     char caret1, char caret2)
-{
-  if (!diagnostic_same_line (context, xloc1, xloc2))
-    /* This will mean ignore xloc2.  */
-    xloc2.column = 0;
-  else if (xloc1.column == xloc2.column)
-    xloc2.column++;
-  
-  int cmax = MAX (xloc1.column, xloc2.column);
-  int line_width;
-  const char *line = location_get_source_line (xloc1.file, xloc1.line,
-					       &line_width);
-  if (line == NULL || cmax > line_width)
-    return;
-
-  /* Center the interesting part of the source line to fit in
-     max_width, and adjust all columns accordingly.  */
-  int max_width = context->caret_max_width;
-  int offset = (int) cmax;
-  line = adjust_line (line, line_width, max_width, &offset);
-  offset -= cmax;
-  cmax += offset;
-  xloc1.column += offset;
-  if (xloc2.column)
-    xloc2.column += offset;
-
-  /* Print the source line.  */
-  pp_newline (context->printer);
-  const char *saved_prefix = pp_get_prefix (context->printer);
-  pp_set_prefix (context->printer, NULL);
-  pp_space (context->printer);
-  while (max_width > 0 && line_width > 0)
-    {
-      char c = *line == '\t' ? ' ' : *line;
-      if (c == '\0')
-	c = ' ';
-      pp_character (context->printer, c);
-      max_width--;
-      line_width--;
-      line++;
-    }
-  pp_newline (context->printer);
-
-  /* Print the caret under the line.  */
-  const char *caret_cs, *caret_ce;
-  caret_cs = colorize_start (pp_show_color (context->printer), "caret");
-  caret_ce = colorize_stop (pp_show_color (context->printer));
-  int cmin = xloc2.column 
-    ? MIN (xloc1.column, xloc2.column) : xloc1.column;
-  int caret_min = cmin == xloc1.column ? caret1 : caret2;
-  int caret_max = cmin == xloc1.column ? caret2 : caret1;
-
-  /* cmin is >= 1, but we indent with an extra space at the start like
-     we did above.  */
-  int i;
-  for (i = 0; i < cmin; i++)
-    pp_space (context->printer);
-  pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce);
-
-  if (xloc2.column)
-    {
-      for (i++; i < cmax; i++)
-	pp_space (context->printer);
-      pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce);
-    }
-  pp_set_prefix (context->printer, saved_prefix);
-  pp_needs_newline (context->printer) = true;
-}
-
 /* Functions at which to stop the backtrace print.  It's not
    particularly helpful to print the callers of these functions.  */
 
-- 
1.8.5.3

