From 221d5daa7c88d1776a8ea1dc7bd5b4b1bb460ce5 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Sat, 31 Oct 2015 04:38:15 -0400
Subject: [PATCH 11/48] Split layout::print_line into two methods.

gcc/ChangeLog:
	* diagnostic-show-locus.c (class colorizer): Update comment to
	reflect split of layout::print_line into layout::print_source_line
	and layout::print_annotation_line.
	(struct line_bounds): New.
	(class layout): Update comment to reflect split of
	layout::print_line.
	(layout::print_line): Delete, in favor of...
	(layout::print_source_line): ...this new method and...
	(layout::print_annotation_line): ...this new method.
	(diagnostic_show_locus): Update for split of layout::print_line
	into layout::print_source_line and layout::print_annotation_line.
---
 gcc/diagnostic-show-locus.c | 78 ++++++++++++++++++++++++++++++---------------
 1 file changed, 52 insertions(+), 26 deletions(-)

diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 6865209..97f2853 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -67,9 +67,10 @@ struct point_state
    The class caches the lookup of the color codes for the above.
 
    The class also has responsibility for tracking which of the above is
-   active, filtering out unnecessary changes.  This allows layout::print_line
-   to simply request a colorization code for *every* character it prints
-   through this class, and have the filtering be done for it here.  */
+   active, filtering out unnecessary changes.  This allows
+   layout::print_source_line and layout::print_annotation_line
+   to simply request a colorization code for *every* character they print,
+   via this class, and have the filtering be done for them here.  */
 
 class colorizer
 {
@@ -128,12 +129,21 @@ class layout_range
   layout_point m_caret;
 };
 
+/* A struct for use by layout::print_source_line for telling
+   layout::print_annotation_line the extents of the source line that
+   it printed, so that underlines can be clipped appropriately.  */
+
+struct line_bounds
+{
+  int m_first_non_ws;
+  int m_last_non_ws;
+};
+
 /* A class to control the overall layout when printing a diagnostic.
 
    The layout is determined within the constructor.
-   It is then printed by repeatedly calling the "print_line" method.
-   Each such call can print two lines: one for the source line itself,
-   and potentially an "annotation" line, containing carets/underlines.
+   It is then printed by repeatedly calling the "print_source_line"
+   and "print_annotation_line" methods.
 
    We assume we have disjoint ranges.  */
 
@@ -146,7 +156,8 @@ class layout
   int get_first_line () const { return m_first_line; }
   int get_last_line () const { return m_last_line; }
 
-  void print_line (int row);
+  bool print_source_line (int row, line_bounds *lbounds_out);
+  void print_annotation_line (int row, const line_bounds lbounds);
 
  private:
   bool
@@ -477,32 +488,30 @@ layout::layout (diagnostic_context * context,
     show_ruler (context, line_width, m_x_offset);
 }
 
-/* Print text describing a line of source code.
-   This typically prints two lines:
+/* Attempt to print line ROW of source code, potentially colorized at any
+   ranges.
+   Return true if the line was printed, populating *LBOUNDS_OUT.
+   Return false if the source line could not be read, leaving *LBOUNDS_OUT
+   untouched.  */
 
-   (1) the source code itself, potentially colorized at any ranges, and
-   (2) an annotation line containing any carets/underlines
-   describing the ranges.  */
-
-void
-layout::print_line (int row)
+bool
+layout::print_source_line (int row, line_bounds *lbounds_out)
 {
   int line_width;
   const char *line = location_get_source_line (m_exploc.file, row,
 					       &line_width);
   if (!line)
-    return;
+    return false;
 
   line += m_x_offset;
 
   m_colorizer.set_normal_text ();
 
-  /* Step 1: print the source code line.  */
+  /* We will stop printing the source line at any trailing
+     whitespace.  */
+  line_width = get_line_width_without_trailing_whitespace (line,
+							   line_width);
 
-  /* We will stop printing at any trailing whitespace.  */
-  line_width
-    = get_line_width_without_trailing_whitespace (line,
-						  line_width);
   pp_space (m_pp);
   int first_non_ws = INT_MAX;
   int last_non_ws = 0;
@@ -547,10 +556,19 @@ layout::print_line (int row)
     }
   pp_newline (m_pp);
 
-  /* Step 2: print a line consisting of the caret/underlines for the
-     given source line.  */
+  lbounds_out->m_first_non_ws = first_non_ws;
+  lbounds_out->m_last_non_ws = last_non_ws;
+  return true;
+}
+
+/* Print a line consisting of the caret/underlines for the given
+   source line.  */
+
+void
+layout::print_annotation_line (int row, const line_bounds lbounds)
+{
   int x_bound = get_x_bound_for_row (row, m_exploc.column,
-				     last_non_ws);
+				     lbounds.m_last_non_ws);
 
   pp_space (m_pp);
   for (int column = 1 + m_x_offset; column < x_bound; column++)
@@ -558,7 +576,8 @@ layout::print_line (int row)
       bool in_range_p;
       point_state state;
       in_range_p = get_state_at_point (row, column,
-				       first_non_ws, last_non_ws,
+				       lbounds.m_first_non_ws,
+				       lbounds.m_last_non_ws,
 				       &state);
       if (in_range_p)
 	{
@@ -734,7 +753,14 @@ diagnostic_show_locus (diagnostic_context * context,
     for (int row = layout.get_first_line ();
 	 row <= last_line;
 	 row++)
-      layout.print_line (row);
+      {
+	/* Print the source line, followed by an annotation line
+	   consisting of any caret/underlines.  If the source line can't
+	   be read, print nothing.  */
+	line_bounds lbounds;
+	if (layout.print_source_line (row, &lbounds))
+	  layout.print_annotation_line (row, lbounds);
+      }
 
     /* The closing scope here leads to the dtor for layout and thus
        colorizer being called here, which affects the precise
-- 
1.8.5.3

