pretty-print: support URL escape sequences (PR 87488)

https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
describes an emerging standard for embedding URLs in escape sequences
for marking up text output.  This is supported e.g. by recent releases
of GNOME Terminal.

This patch adds support to our pretty-printing framework for emitting
URLs.

A followup patch uses this to add URLs to the pertinent documentation
for the output of -fdiagnostics-show-option.

gcc/ChangeLog:
	PR 87488
	* common.opt (fdiagnostics-urls=): New option.
	(diagnostic-url.h): Add SourceInclude.
	(diagnostic_url_rule): New enum.
	* diagnostic-color.c: Include "diagnostic-url.h".
	(diagnostic_urls_enabled_p): New function.
	* diagnostic-url.h: New file.
	* diagnostic.c: Include "diagnostic-url.h".
	(diagnostic_urls_init): New function.
	* diagnostic.h (diagnostic_urls_init): New decl.
	* doc/invoke.texi (Diagnostic Message Formatting Options): Add
	-fdiagnostics-urls to the list.
	(-fdiagnostics-urls): New option.
	* gcc.c (driver_handle_option): Handle OPT_fdiagnostics_urls_.
	(driver::global_initializations): Call diagnostic_urls_init.
	* opts-global.c (init_options_once): Likewise.
	* opts.c (common_handle_option): Handle OPT_fdiagnostics_urls_.
	* pretty-print.c (pretty_printer::pretty_printer): Initialize
	show_urls.
	(pp_begin_url): New function.
	(pp_end_url): New function.
	(selftest::test_urls): New selftest.
	(selftest::pretty_print_c_tests): Call it.
	* pretty-print.h (pretty_printer::show_urls): New field.
	(pp_begin_url): New decl.
	(pp_end_url): New decl.

gcc/testsuite/ChangeLog:
	PR 87488
	* lib/prune.exp (TEST_ALWAYS_FLAGS): Add -fdiagnostics-urls=never.

From-SVN: r276841
This commit is contained in:
David Malcolm 2019-10-10 16:57:30 +00:00 committed by David Malcolm
parent 9cfc400f3f
commit d260823576
14 changed files with 218 additions and 2 deletions

View File

@ -1,3 +1,32 @@
2019-10-10 David Malcolm <dmalcolm@redhat.com>
PR 87488
* common.opt (fdiagnostics-urls=): New option.
(diagnostic-url.h): Add SourceInclude.
(diagnostic_url_rule): New enum.
* diagnostic-color.c: Include "diagnostic-url.h".
(diagnostic_urls_enabled_p): New function.
* diagnostic-url.h: New file.
* diagnostic.c: Include "diagnostic-url.h".
(diagnostic_urls_init): New function.
* diagnostic.h (diagnostic_urls_init): New decl.
* doc/invoke.texi (Diagnostic Message Formatting Options): Add
-fdiagnostics-urls to the list.
(-fdiagnostics-urls): New option.
* gcc.c (driver_handle_option): Handle OPT_fdiagnostics_urls_.
(driver::global_initializations): Call diagnostic_urls_init.
* opts-global.c (init_options_once): Likewise.
* opts.c (common_handle_option): Handle OPT_fdiagnostics_urls_.
* pretty-print.c (pretty_printer::pretty_printer): Initialize
show_urls.
(pp_begin_url): New function.
(pp_end_url): New function.
(selftest::test_urls): New selftest.
(selftest::pretty_print_c_tests): Call it.
* pretty-print.h (pretty_printer::show_urls): New field.
(pp_begin_url): New decl.
(pp_end_url): New decl.
2019-10-10 Uroš Bizjak <ubizjak@gmail.com>
PR target/92022

View File

@ -1281,6 +1281,26 @@ Enum(diagnostic_color_rule) String(always) Value(DIAGNOSTICS_COLOR_YES)
EnumValue
Enum(diagnostic_color_rule) String(auto) Value(DIAGNOSTICS_COLOR_AUTO)
fdiagnostics-urls=
Driver Common Joined RejectNegative Var(flag_diagnostics_show_urls) Enum(diagnostic_url_rule) Init(DIAGNOSTICS_URL_AUTO)
-fdiagnostics-urls=[never|always|auto] Embed URLs in diagnostics.
; Required for these enum values.
SourceInclude
diagnostic-url.h
Enum
Name(diagnostic_url_rule) Type(int)
EnumValue
Enum(diagnostic_url_rule) String(never) Value(DIAGNOSTICS_URL_NO)
EnumValue
Enum(diagnostic_url_rule) String(always) Value(DIAGNOSTICS_URL_YES)
EnumValue
Enum(diagnostic_url_rule) String(auto) Value(DIAGNOSTICS_URL_AUTO)
fdiagnostics-format=
Common Joined RejectNegative Enum(diagnostics_output_format)
-fdiagnostics-format=[text|json] Select output format.

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "system.h"
#include "diagnostic-color.h"
#include "diagnostic-url.h"
#ifdef __MINGW32__
# include <windows.h>
@ -236,3 +237,22 @@ colorize_init (diagnostic_color_rule_t rule)
gcc_unreachable ();
}
}
/* Determine if URLs should be enabled, based on RULE.
This reuses the logic for colorization. */
bool
diagnostic_urls_enabled_p (diagnostic_url_rule_t rule)
{
switch (rule)
{
case DIAGNOSTICS_URL_NO:
return false;
case DIAGNOSTICS_URL_YES:
return true;
case DIAGNOSTICS_URL_AUTO:
return should_colorize ();
default:
gcc_unreachable ();
}
}

36
gcc/diagnostic-url.h Normal file
View File

@ -0,0 +1,36 @@
/* Copyright (C) 2019 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.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/>. */
#ifndef GCC_DIAGNOSTIC_URL_H
#define GCC_DIAGNOSTIC_URL_H
/* Whether to add URLs to diagnostics:
- DIAGNOSTICS_URL_NO: never
- DIAGNOSTICS_URL_YES: always
- DIAGNOSTICS_URL_AUTO: depending on the output stream. */
typedef enum
{
DIAGNOSTICS_URL_NO = 0,
DIAGNOSTICS_URL_YES = 1,
DIAGNOSTICS_URL_AUTO = 2
} diagnostic_url_rule_t;
extern bool diagnostic_urls_enabled_p (diagnostic_url_rule_t);
#endif /* ! GCC_DIAGNOSTIC_URL_H */

View File

@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "backtrace.h"
#include "diagnostic.h"
#include "diagnostic-color.h"
#include "diagnostic-url.h"
#include "edit-context.h"
#include "selftest.h"
#include "selftest-diagnostic.h"
@ -246,6 +247,18 @@ diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
= colorize_init ((diagnostic_color_rule_t) value);
}
/* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
void
diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
{
if (value < 0)
value = DIAGNOSTICS_COLOR_DEFAULT;
context->printer->show_urls
= diagnostic_urls_enabled_p ((diagnostic_url_rule_t) value);
}
/* Do any cleaning up required after the last diagnostic is emitted. */
void

View File

@ -331,6 +331,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 *,

View File

@ -273,6 +273,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
@ -3908,6 +3909,18 @@ SGR substring for highlighting mismatching types within template
arguments in the C++ frontend.
@end table
@item -fdiagnostics-urls[=@var{WHEN}]
@opindex fdiagnostics-urls
@cindex urls
Use escape sequences to embed URLs in diagnostics. For example, when
@option{-fdiagnostics-show-option} emits text showing the command-line
option controlling a diagnostic, embed a URL for documentation of that
option.
@var{WHEN} is @samp{never}, @samp{always}, or @samp{auto}.
The default is @samp{auto}, which means to use URL escape sequences only
when the standard error is a terminal.
@item -fno-diagnostics-show-option
@opindex fno-diagnostics-show-option
@opindex fdiagnostics-show-option

View File

@ -4041,6 +4041,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);
@ -7443,6 +7447,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. */

View File

@ -255,6 +255,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

View File

@ -2474,6 +2474,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);

View File

@ -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,41 @@ 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 ]. */
/* If URL-printing is enabled, write an "open URL" escape sequence to PP
for the given URL. */
void
pp_begin_url (pretty_printer *pp, const char *url)
{
if (pp->show_urls)
pp_printf (pp, "\33]8;;%s\33\\", url);
}
/* If URL-printing is enabled, write a "close URL" escape sequence to PP. */
void
pp_end_url (pretty_printer *pp)
{
if (pp->show_urls)
pp_string (pp, "\33]8;;\33\\");
}
#if CHECKING_P
namespace selftest {
@ -2312,6 +2348,32 @@ test_prefixes_and_wrapping ()
}
/* Verify that URL-printing works as expected. */
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 +2382,7 @@ pretty_print_c_tests ()
test_basic_printing ();
test_pp_format ();
test_prefixes_and_wrapping ();
test_urls ();
}
} // namespace selftest

View File

@ -273,6 +273,9 @@ public:
/* Nonzero means that text should be colorized. */
bool show_color;
/* Nonzero means that URLs should be emitted. */
bool show_urls;
};
static inline const char *
@ -393,6 +396,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)

View File

@ -1,3 +1,8 @@
2019-10-10 David Malcolm <dmalcolm@redhat.com>
PR 87488
* lib/prune.exp (TEST_ALWAYS_FLAGS): Add -fdiagnostics-urls=never.
2019-10-10 Uroš Bizjak <ubizjak@gmail.com>
PR target/92022

View File

@ -21,7 +21,7 @@ load_lib multiline.exp
if ![info exists TEST_ALWAYS_FLAGS] {
set TEST_ALWAYS_FLAGS ""
}
set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never $TEST_ALWAYS_FLAGS"
set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers -fdiagnostics-color=never -fdiagnostics-urls=never $TEST_ALWAYS_FLAGS"
proc prune_gcc_output { text } {
global srcdir