From b2a7f6f662a712ba5282bb49d5f5985415c7ea57 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 10 Jan 2019 17:25:08 -0500
Subject: [PATCH 006/217] FIXME: WIP on emitting URLs (PR 87488)

---
 gcc/common.opt         |  8 +++++++
 gcc/diagnostic-color.c | 18 ++++++++++++++
 gcc/diagnostic-color.h |  1 +
 gcc/diagnostic.c       | 12 ++++++++++
 gcc/diagnostic.h       |  1 +
 gcc/doc/invoke.texi    |  7 ++++++
 gcc/gcc.c              |  5 ++++
 gcc/opts-global.c      |  1 +
 gcc/opts.c             |  4 ++++
 gcc/pretty-print.c     | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-
 gcc/pretty-print.h     |  6 +++++
 11 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index 035f2ba..dc038c9 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1277,6 +1277,14 @@ Enum(diagnostic_color_rule) String(always) Value(DIAGNOSTICS_COLOR_YES)
 EnumValue
 Enum(diagnostic_color_rule) String(auto) Value(DIAGNOSTICS_COLOR_AUTO)
 
+fdiagnostics-urls
+Common Alias(fdiagnostics-urls=,always,never)
+;
+
+fdiagnostics-urls=
+Driver Common Joined RejectNegative Var(flag_diagnostics_show_urls) Enum(diagnostic_color_rule) Init(DIAGNOSTICS_COLOR_NO)
+-fdiagnostics-urls=[never|always|auto]	Embed URLs in diagnostics.
+
 fdiagnostics-format=
 Common Joined RejectNegative Enum(diagnostics_output_format)
 -fdiagnostics-format=[text|json] Select output format
diff --git a/gcc/diagnostic-color.c b/gcc/diagnostic-color.c
index 69e759f..9387d77 100644
--- a/gcc/diagnostic-color.c
+++ b/gcc/diagnostic-color.c
@@ -236,3 +236,21 @@ colorize_init (diagnostic_color_rule_t rule)
       gcc_unreachable ();
     }
 }
+
+/* FIXME.  */
+
+bool
+urls_enabled_p (diagnostic_color_rule_t rule)
+{
+  switch (rule)
+    {
+    case DIAGNOSTICS_COLOR_NO:
+      return false;
+    case DIAGNOSTICS_COLOR_YES:
+      return true;
+    case DIAGNOSTICS_COLOR_AUTO:
+      return should_colorize ();
+    default:
+      gcc_unreachable ();
+    }
+}
diff --git a/gcc/diagnostic-color.h b/gcc/diagnostic-color.h
index 1349d04..5572577 100644
--- a/gcc/diagnostic-color.h
+++ b/gcc/diagnostic-color.h
@@ -55,6 +55,7 @@ typedef enum
 const char *colorize_start (bool, const char *, size_t);
 const char *colorize_stop (bool);
 bool colorize_init (diagnostic_color_rule_t);
+bool urls_enabled_p (diagnostic_color_rule_t);
 
 inline const char *
 colorize_start (bool show_color, const char *name)
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index be6b657..ca2af97 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -238,6 +238,18 @@ diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
     = colorize_init ((diagnostic_color_rule_t) value);
 }
 
+/* FIXME.  */
+
+void
+diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
+{
+  if (value < 0)
+    value = DIAGNOSTICS_COLOR_DEFAULT;
+
+  context->printer->show_urls
+    = urls_enabled_p ((diagnostic_color_rule_t) value);
+}
+
 /* Do any cleaning up required after the last diagnostic is emitted.  */
 
 void
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 46c3b50..5daf4f2 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -328,6 +328,7 @@ diagnostic_override_option_index (diagnostic_info *info, int optidx)
 /* Diagnostic related functions.  */
 extern void diagnostic_initialize (diagnostic_context *, int);
 extern void diagnostic_color_init (diagnostic_context *, int value = -1);
+extern void diagnostic_urls_init (diagnostic_context *, int value = -1);
 extern void diagnostic_finish (diagnostic_context *);
 extern void diagnostic_report_current_module (diagnostic_context *, location_t);
 extern void diagnostic_show_locus (diagnostic_context *,
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 292227a..fadcd09 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -269,6 +269,7 @@ Objective-C and Objective-C++ Dialects}.
 @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
+-fdiagnostics-urls=@r{[}auto@r{|}never@r{|}always@r{]}  @gol
 -fdiagnostics-format=@r{[}text@r{|}json@r{]}  @gol
 -fno-diagnostics-show-option  -fno-diagnostics-show-caret @gol
 -fno-diagnostics-show-labels  -fno-diagnostics-show-line-numbers @gol
@@ -3805,6 +3806,12 @@ SGR substring for highlighting mismatching types within template
 arguments in the C++ frontend.
 @end table
 
+@item -fdiagnostics-urls[=@var{WHEN}]
+@itemx -fno-diagnostics-urls
+@opindex fdiagnostics-urls
+@cindex urls
+FIXME
+
 @item -fno-diagnostics-show-option
 @opindex fno-diagnostics-show-option
 @opindex fdiagnostics-show-option
diff --git a/gcc/gcc.c b/gcc/gcc.c
index bcd04df..cc294d7 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -4003,6 +4003,10 @@ driver_handle_option (struct gcc_options *opts,
       diagnostic_color_init (dc, value);
       break;
 
+    case OPT_fdiagnostics_urls_:
+      diagnostic_urls_init (dc, value);
+      break;
+
     case OPT_fdiagnostics_format_:
       diagnostic_output_format_init (dc,
 				     (enum diagnostics_output_format)value);
@@ -7400,6 +7404,7 @@ driver::global_initializations ()
 
   diagnostic_initialize (global_dc, 0);
   diagnostic_color_init (global_dc);
+  diagnostic_urls_init (global_dc);
 
 #ifdef GCC_DRIVER_HOST_INITIALIZATION
   /* Perform host dependent initialization when needed.  */
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 1c24c85..761fd21 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -251,6 +251,7 @@ init_options_once (void)
      construct their pretty-printers means that all previous settings
      are overriden.  */
   diagnostic_color_init (global_dc);
+  diagnostic_urls_init (global_dc);
 }
 
 /* Decode command-line options to an array, like
diff --git a/gcc/opts.c b/gcc/opts.c
index a4be6ae..d7c5c8e 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2387,6 +2387,10 @@ common_handle_option (struct gcc_options *opts,
       diagnostic_color_init (dc, value);
       break;
 
+    case OPT_fdiagnostics_urls_:
+      diagnostic_urls_init (dc, value);
+      break;
+
     case OPT_fdiagnostics_format_:
       diagnostic_output_format_init (dc,
 				     (enum diagnostics_output_format)value);
diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c
index 6948971..a2d6f04 100644
--- a/gcc/pretty-print.c
+++ b/gcc/pretty-print.c
@@ -1579,7 +1579,8 @@ pretty_printer::pretty_printer (int maximum_length)
     emitted_prefix (),
     need_newline (),
     translate_identifiers (true),
-    show_color ()
+    show_color (),
+    show_urls (false)
 {
   pp_line_cutoff (this) = maximum_length;
   /* By default, we emit prefixes once per message.  */
@@ -2028,6 +2029,40 @@ identifier_to_locale (const char *ident)
   }
 }
 
+/* Support for encoding URLs.
+   See egmontkob/Hyperlinks_in_Terminal_Emulators.md
+   ( https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda ).
+
+   > A hyperlink is opened upon encountering an OSC 8 escape sequence with
+   > the target URI. The syntax is
+   >
+   >  OSC 8 ; params ; URI ST
+   >
+   > A hyperlink is closed with the same escape sequence, omitting the
+   > parameters and the URI but keeping the separators:
+   >
+   > OSC 8 ; ; ST
+   >
+   > OSC (operating system command) is typically ESC ].  */
+
+/* FIXME.  */
+
+void
+pp_begin_url (pretty_printer *pp, const char *url)
+{
+  if (pp->show_urls)
+    pp_printf (pp, "\33]8;;%s\33\\", url);
+}
+
+/* FIXME.  */
+
+void
+pp_end_url (pretty_printer *pp)
+{
+  if (pp->show_urls)
+    pp_string (pp, "\33]8;;\33\\");
+}
+
 #if CHECKING_P
 
 namespace selftest {
@@ -2312,6 +2347,32 @@ test_prefixes_and_wrapping ()
 
 }
 
+/* FIXME.  */
+
+void
+test_urls ()
+{
+  {
+    pretty_printer pp;
+    pp.show_urls = false;
+    pp_begin_url (&pp, "http://example.com");
+    pp_string (&pp, "This is a link");
+    pp_end_url (&pp);
+    ASSERT_STREQ ("This is a link",
+		  pp_formatted_text (&pp));
+  }
+
+  {
+    pretty_printer pp;
+    pp.show_urls = true;
+    pp_begin_url (&pp, "http://example.com");
+    pp_string (&pp, "This is a link");
+    pp_end_url (&pp);
+    ASSERT_STREQ ("\33]8;;http://example.com\33\\This is a link\33]8;;\33\\",
+		  pp_formatted_text (&pp));
+  }
+}
+
 /* Run all of the selftests within this file.  */
 
 void
@@ -2320,6 +2381,7 @@ pretty_print_c_tests ()
   test_basic_printing ();
   test_pp_format ();
   test_prefixes_and_wrapping ();
+  test_urls ();
 }
 
 } // namespace selftest
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index e4df659..07cd391 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -271,6 +271,9 @@ struct pretty_printer
 
   /* Nonzero means that text should be colorized.  */
   bool show_color;
+
+  /* Nonzero means that URLs should be emitted.  */
+  bool show_urls;
 };
 
 static inline const char *
@@ -391,6 +394,9 @@ extern void pp_maybe_space (pretty_printer *);
 extern void pp_begin_quote (pretty_printer *, bool);
 extern void pp_end_quote (pretty_printer *, bool);
 
+extern void pp_begin_url (pretty_printer *pp, const char *url);
+extern void pp_end_url (pretty_printer *pp);
+
 /* Switch into verbatim mode and return the old mode.  */
 static inline pp_wrapping_mode_t
 pp_set_verbatim_wrapping_ (pretty_printer *pp)
-- 
1.8.5.3

