https://gcc.gnu.org/g:82de4cada8669639a8474808db48d63ffade2bcb
commit r16-1344-g82de4cada8669639a8474808db48d63ffade2bcb Author: David Malcolm <dmalc...@redhat.com> Date: Mon Jun 9 09:40:06 2025 -0400 diagnostics: fix <title> of experimental-html output [PR116792] Add a new vfunc diagnostic_output_format::set_main_input_filename so that we can separate setting the <title> of HTML output and the diagnostic_artifact_role::analysis_target of SARIF output from creation of the sinks. Calling it is done by the various creators of the sinks. gcc/ChangeLog: PR other/116792 * diagnostic-format-html.cc (html_builder::m_title_element): New field. (html_builder::html_builder): Initialize it. Don't add placeholder text. (html_builder::set_main_input_filename): New. (html_output_format::set_main_input_filename): New. (test_html_diagnostic_context::test_html_diagnostic_context): Call set_main_input_filename on the new sink. (seldtest::test_simple_log): Update expected <title> text. * diagnostic-format-json.cc (diagnostic_output_format_init_json): Return a reference to the new sink. (diagnostic_output_format_init_json_stderr): Likewise. (diagnostic_output_format_init_json_file): Likewise. * diagnostic-format-sarif.cc (sarif_builder::sarif_builder): Drop "main_input_filename_" param, and move adding an artifact for it with diagnostic_artifact_role::analysis_target to... (sarif_builder::set_main_input_filename): ...this new function. (sarif_output_format::set_main_input_filename): New. (sarif_output_format::sarif_output_format): Drop "main_input_filename_" param. (sarif_stream_output_format::sarif_stream_output_format): Likewise. (sarif_file_output_format::sarif_file_output_format): Likewise. (diagnostic_output_format_init_sarif): Return a reference to *FMT. (diagnostic_output_format_init_sarif_stderr): Return a refererence to the new sink. Drop "main_input_filename_" param. (diagnostic_output_format_init_sarif_file): Likewise. (diagnostic_output_format_init_sarif_stream): Likewise. (make_sarif_sink): Drop "main_input_filename_" param. (selftest::test_sarif_diagnostic_context::test_sarif_diagnostic_context): Likewise. Call set_main_input_filename on the new format. (selftest::test_sarif_diagnostic_context::buffered_output_format::buffered_output_format): Drop "main_input_filename_" param. (selftest::test_make_location_object): Likewise. * diagnostic-format-sarif.h (diagnostic_output_format_init_sarif_stderr): Return a refererence to the new sink. Drop "main_input_filename_" param. (diagnostic_output_format_init_sarif_file): Likewise. (diagnostic_output_format_init_sarif_stream): Likewise. (make_sarif_sink): Drop "main_input_filename_" param. * diagnostic-format.h (diagnostic_output_format::set_main_input_filename): New vfunc. (diagnostic_output_format_init_json_stderr): Return a refererence to the new sink. (diagnostic_output_format_init_json_file): Likewise. * diagnostic.cc (diagnostic_output_format_init): Likewise. Call set_main_input_filename on the new sink. * libgdiagnostics.cc (sarif_sink::sarif_sink): Update for above changes. * opts-diagnostic.cc (sarif_scheme_handler::make_sink): Likewise. (handle_OPT_fdiagnostics_add_output_): Likewise. (handle_OPT_fdiagnostics_set_output_): Likewise. gcc/testsuite/ChangeLog: PR other/116792 * gcc.dg/html-output/missing-semicolon.py: Update expected <title> text. Drop out-of-date comment. Signed-off-by: David Malcolm <dmalc...@redhat.com> Diff: --- gcc/diagnostic-format-html.cc | 27 ++++++- gcc/diagnostic-format-json.cc | 23 ++++-- gcc/diagnostic-format-sarif.cc | 91 ++++++++++++---------- gcc/diagnostic-format-sarif.h | 10 +-- gcc/diagnostic-format.h | 9 ++- gcc/diagnostic.cc | 29 +++---- gcc/libgdiagnostics.cc | 2 +- gcc/opts-diagnostic.cc | 3 +- .../gcc.dg/html-output/missing-semicolon.py | 25 +----- 9 files changed, 118 insertions(+), 101 deletions(-) diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index ea2dbbba9293..ddf6ba0f4cfc 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -104,6 +104,9 @@ public: const line_maps *line_maps, const html_generation_options &html_gen_opts); + void + set_main_input_filename (const char *name); + void on_report_diagnostic (const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, diagnostic_html_format_buffer *buffer); @@ -151,6 +154,7 @@ private: std::unique_ptr<xml::document> m_document; xml::element *m_head_element; + xml::element *m_title_element; xml::element *m_diagnostics_element; std::unique_ptr<xml::element> m_cur_diagnostic_element; int m_next_diag_id; // for handing out unique IDs @@ -348,6 +352,7 @@ html_builder::html_builder (diagnostic_context &context, m_line_maps (line_maps), m_html_gen_opts (html_gen_opts), m_head_element (nullptr), + m_title_element (nullptr), m_diagnostics_element (nullptr), m_next_diag_id (0) { @@ -367,7 +372,7 @@ html_builder::html_builder (diagnostic_context &context, m_head_element = xp.get_insertion_point (); { xml::auto_print_element title (xp, "title", true); - xp.add_text ("Title goes here"); + m_title_element = xp.get_insertion_point (); } if (m_html_gen_opts.m_css) xp.add_raw (HTML_STYLE); @@ -392,6 +397,17 @@ html_builder::html_builder (diagnostic_context &context, } } +void +html_builder::set_main_input_filename (const char *name) +{ + gcc_assert (m_title_element); + if (name) + { + m_title_element->m_children.clear (); + m_title_element->add_text (name); + } +} + /* Implementation of "on_report_diagnostic" for HTML output. */ void @@ -765,6 +781,12 @@ public: diagnostic_output_format::dump (out, indent); } + void + set_main_input_filename (const char *name) final override + { + m_builder.set_main_input_filename (name); + } + std::unique_ptr<diagnostic_per_format_buffer> make_per_format_buffer () final override { @@ -940,6 +962,7 @@ public: line_table, html_gen_opts); sink->update_printer (); + sink->set_main_input_filename ("(main input filename)"); m_format = sink.get (); // borrowed set_output_format (std::move (sink)); @@ -998,7 +1021,7 @@ test_simple_log () " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" " <head>\n" - " <title>Title goes here</title>\n" + " <title>(main input filename)</title>\n" " </head>\n" " <body>\n" " <div class=\"gcc-diagnostic-list\">\n" diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc index 205678dbe041..fb5489778358 100644 --- a/gcc/diagnostic-format-json.cc +++ b/gcc/diagnostic-format-json.cc @@ -505,40 +505,47 @@ private: }; /* Populate CONTEXT in preparation for JSON output (either to stderr, or - to a file). */ + to a file) using FMT. Return a reference to *FMT. */ -static void +static diagnostic_output_format & diagnostic_output_format_init_json (diagnostic_context &context, std::unique_ptr<json_output_format> fmt) { + gcc_assert (fmt); + diagnostic_output_format &out = *fmt; + /* Don't colorize the text. */ pp_show_color (fmt->get_printer ()) = false; context.set_show_highlight_colors (false); context.set_output_format (std::move (fmt)); + + return out; } -/* Populate CONTEXT in preparation for JSON output to stderr. */ +/* Populate CONTEXT in preparation for JSON output to stderr. + Return a reference to the context's new sink. */ -void +diagnostic_output_format & diagnostic_output_format_init_json_stderr (diagnostic_context &context, bool formatted) { - diagnostic_output_format_init_json + return diagnostic_output_format_init_json (context, std::make_unique<json_stderr_output_format> (context, formatted)); } /* Populate CONTEXT in preparation for JSON output to a file named - BASE_FILE_NAME.gcc.json. */ + BASE_FILE_NAME.gcc.json. + Return a reference to the context's new sink. */ -void +diagnostic_output_format & diagnostic_output_format_init_json_file (diagnostic_context &context, bool formatted, const char *base_file_name) { - diagnostic_output_format_init_json + return diagnostic_output_format_init_json (context, std::make_unique<json_file_output_format> (context, formatted, diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 454eaae4d905..7dcd126aeb23 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -751,7 +751,6 @@ public: sarif_builder (diagnostic_context &context, pretty_printer &printer, const line_maps *line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization_format, const sarif_generation_options &sarif_gen_opts); ~sarif_builder (); @@ -767,6 +766,9 @@ public: return m_logical_loc_mgr; } + void + set_main_input_filename (const char *name); + void on_report_diagnostic (const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, diagnostic_sarif_format_buffer *buffer); @@ -1643,7 +1645,6 @@ sarif_thread_flow::add_location () sarif_builder::sarif_builder (diagnostic_context &context, pretty_printer &printer, const line_maps *line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization_format, const sarif_generation_options &sarif_gen_opts) : m_context (context), @@ -1672,17 +1673,6 @@ sarif_builder::sarif_builder (diagnostic_context &context, if (auto client_data_hooks = context.get_client_data_hooks ()) m_logical_loc_mgr = client_data_hooks->get_logical_location_manager (); - - /* Mark MAIN_INPUT_FILENAME_ as the artifact that the tool was - instructed to scan. - Only quote the contents if it gets referenced by physical locations, - since otherwise the "no diagnostics" case would quote the main input - file, and doing so noticeably bloated the output seen in analyzer - integration testing (build directory went from 20G -> 21G). */ - if (main_input_filename_) - get_or_create_artifact (main_input_filename_, - diagnostic_artifact_role::analysis_target, - false); } sarif_builder::~sarif_builder () @@ -1820,6 +1810,20 @@ sarif_builder::make_stack_from_backtrace () return stack; } +void +sarif_builder::set_main_input_filename (const char *name) +{ + /* Mark NAME as the artifact that the tool was instructed to scan. + Only quote the contents if it gets referenced by physical locations, + since otherwise the "no diagnostics" case would quote the main input + file, and doing so noticeably bloated the output seen in analyzer + integration testing (build directory went from 20G -> 21G). */ + if (name) + get_or_create_artifact (name, + diagnostic_artifact_role::analysis_target, + false); +} + /* Implementation of "on_report_diagnostic" for SARIF output. */ void @@ -3657,6 +3661,12 @@ public: diagnostic_output_format::dump (out, indent); } + void + set_main_input_filename (const char *name) final override + { + m_builder.set_main_input_filename (name); + } + std::unique_ptr<diagnostic_per_format_buffer> make_per_format_buffer () final override { @@ -3722,11 +3732,10 @@ public: protected: sarif_output_format (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization_format, const sarif_generation_options &sarif_gen_opts) : diagnostic_output_format (context), - m_builder (context, *get_printer (), line_maps, main_input_filename_, + m_builder (context, *get_printer (), line_maps, std::move (serialization_format), sarif_gen_opts), m_buffer (nullptr) {} @@ -3740,11 +3749,10 @@ class sarif_stream_output_format : public sarif_output_format public: sarif_stream_output_format (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization_format, const sarif_generation_options &sarif_gen_opts, FILE *stream) - : sarif_output_format (context, line_maps, main_input_filename_, + : sarif_output_format (context, line_maps, std::move (serialization_format), sarif_gen_opts), m_stream (stream) { @@ -3766,11 +3774,10 @@ class sarif_file_output_format : public sarif_output_format public: sarif_file_output_format (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization_format, const sarif_generation_options &sarif_gen_opts, diagnostic_output_file output_file) - : sarif_output_format (context, line_maps, main_input_filename_, + : sarif_output_format (context, line_maps, std::move (serialization_format), sarif_gen_opts), m_output_file (std::move (output_file)) { @@ -3914,34 +3921,39 @@ sarif_builder::sarif_token_printer::print_tokens (pretty_printer *pp, } /* Populate CONTEXT in preparation for SARIF output (either to stderr, or - to a file). */ + to a file). + Return a reference to *FMT. */ -static void +static diagnostic_output_format & diagnostic_output_format_init_sarif (diagnostic_context &context, std::unique_ptr<sarif_output_format> fmt) { + gcc_assert (fmt); + diagnostic_output_format &out = *fmt; + fmt->update_printer (); context.set_output_format (std::move (fmt)); + + return out; } -/* Populate CONTEXT in preparation for SARIF output to stderr. */ +/* Populate CONTEXT in preparation for SARIF output to stderr. + Return a reference to the new sink. */ -void +diagnostic_output_format & diagnostic_output_format_init_sarif_stderr (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, bool formatted) { gcc_assert (line_maps); const sarif_generation_options sarif_gen_opts; auto serialization = std::make_unique<sarif_serialization_format_json> (formatted); - diagnostic_output_format_init_sarif + return diagnostic_output_format_init_sarif (context, std::make_unique<sarif_stream_output_format> (context, line_maps, - main_input_filename_, std::move (serialization), sarif_gen_opts, stderr)); @@ -4018,12 +4030,12 @@ diagnostic_output_format_open_sarif_file (diagnostic_context &context, } /* Populate CONTEXT in preparation for SARIF output to a file named - BASE_FILE_NAME.sarif. */ + BASE_FILE_NAME.sarif. + Return a reference to the new sink. */ -void +diagnostic_output_format & diagnostic_output_format_init_sarif_file (diagnostic_context &context, line_maps *line_maps, - const char *main_input_filename_, bool formatted, const char *base_file_name) { @@ -4038,22 +4050,21 @@ diagnostic_output_format_init_sarif_file (diagnostic_context &context, = std::make_unique<sarif_serialization_format_json> (formatted); const sarif_generation_options sarif_gen_opts; - diagnostic_output_format_init_sarif + return diagnostic_output_format_init_sarif (context, std::make_unique<sarif_file_output_format> (context, line_maps, - main_input_filename_, std::move (serialization), sarif_gen_opts, std::move (output_file))); } -/* Populate CONTEXT in preparation for SARIF output to STREAM. */ +/* Populate CONTEXT in preparation for SARIF output to STREAM. + Return a reference to the new sink. */ -void +diagnostic_output_format & diagnostic_output_format_init_sarif_stream (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, bool formatted, FILE *stream) { @@ -4061,11 +4072,10 @@ diagnostic_output_format_init_sarif_stream (diagnostic_context &context, const sarif_generation_options sarif_gen_opts; auto serialization = std::make_unique<sarif_serialization_format_json> (formatted); - diagnostic_output_format_init_sarif + return diagnostic_output_format_init_sarif (context, std::make_unique<sarif_stream_output_format> (context, line_maps, - main_input_filename_, std::move (serialization), sarif_gen_opts, stream)); @@ -4074,7 +4084,6 @@ diagnostic_output_format_init_sarif_stream (diagnostic_context &context, std::unique_ptr<diagnostic_output_format> make_sarif_sink (diagnostic_context &context, const line_maps &line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization, const sarif_generation_options &sarif_gen_opts, diagnostic_output_file output_file) @@ -4082,7 +4091,6 @@ make_sarif_sink (diagnostic_context &context, auto sink = std::make_unique<sarif_file_output_format> (context, &line_maps, - main_input_filename_, std::move (serialization), sarif_gen_opts, std::move (output_file)); @@ -4183,11 +4191,11 @@ public: { auto format = std::make_unique<buffered_output_format> (*this, line_table, - main_input_filename, true, sarif_gen_opts); m_format = format.get (); // borrowed diagnostic_output_format_init_sarif (*this, std::move (format)); + m_format->set_main_input_filename (main_input_filename); } std::unique_ptr<sarif_log> flush_to_object () @@ -4204,10 +4212,9 @@ private: public: buffered_output_format (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, bool formatted, const sarif_generation_options &sarif_gen_opts) - : sarif_output_format (context, line_maps, main_input_filename_, + : sarif_output_format (context, line_maps, std::make_unique<sarif_serialization_format_json> (formatted), sarif_gen_opts) @@ -4243,7 +4250,7 @@ test_make_location_object (const sarif_generation_options &sarif_gen_opts, test_diagnostic_context dc; pretty_printer pp; sarif_builder builder - (dc, pp, line_table, "MAIN_INPUT_FILENAME", + (dc, pp, line_table, std::make_unique<sarif_serialization_format_json> (true), sarif_gen_opts); diff --git a/gcc/diagnostic-format-sarif.h b/gcc/diagnostic-format-sarif.h index 4e6a525d64c1..763dc25f39e8 100644 --- a/gcc/diagnostic-format-sarif.h +++ b/gcc/diagnostic-format-sarif.h @@ -41,21 +41,18 @@ diagnostic_output_format_open_sarif_file (diagnostic_context &context, const char *base_file_name, enum sarif_serialization_kind serialization_kind); -extern void +extern diagnostic_output_format & diagnostic_output_format_init_sarif_stderr (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, bool formatted); -extern void +extern diagnostic_output_format & diagnostic_output_format_init_sarif_file (diagnostic_context &context, line_maps *line_maps, - const char *main_input_filename_, bool formatted, const char *base_file_name); -extern void +extern diagnostic_output_format & diagnostic_output_format_init_sarif_stream (diagnostic_context &context, const line_maps *line_maps, - const char *main_input_filename_, bool formatted, FILE *stream); @@ -109,7 +106,6 @@ struct sarif_generation_options extern std::unique_ptr<diagnostic_output_format> make_sarif_sink (diagnostic_context &context, const line_maps &line_maps, - const char *main_input_filename_, std::unique_ptr<sarif_serialization_format> serialization_format, const sarif_generation_options &sarif_gen_opts, diagnostic_output_file output_file); diff --git a/gcc/diagnostic-format.h b/gcc/diagnostic-format.h index f274a00f6e0d..4de5842ad2c2 100644 --- a/gcc/diagnostic-format.h +++ b/gcc/diagnostic-format.h @@ -36,6 +36,10 @@ public: virtual void dump (FILE *out, int indent) const; + /* Vfunc for notifying this format what the primary input file is, + e.g. for titles of HTML, for SARIF's artifact metadata. */ + virtual void set_main_input_filename (const char *) {} + /* Vfunc for making an appropriate diagnostic_per_format_buffer subclass for this format. */ virtual std::unique_ptr<diagnostic_per_format_buffer> @@ -95,10 +99,11 @@ diagnostic_output_format_init (diagnostic_context &, const char *base_file_name, enum diagnostics_output_format, bool json_formatting); -extern void + +extern diagnostic_output_format & diagnostic_output_format_init_json_stderr (diagnostic_context &context, bool formatted); -extern void +extern diagnostic_output_format & diagnostic_output_format_init_json_file (diagnostic_context &context, bool formatted, const char *base_file_name); diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 20582b1fd5ee..5b8eb7d14042 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -1865,6 +1865,7 @@ diagnostic_output_format_init (diagnostic_context &context, enum diagnostics_output_format format, bool json_formatting) { + diagnostic_output_format *new_sink = nullptr; switch (format) { default: @@ -1874,31 +1875,31 @@ diagnostic_output_format_init (diagnostic_context &context, break; case DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR: - diagnostic_output_format_init_json_stderr (context, - json_formatting); + new_sink = &diagnostic_output_format_init_json_stderr (context, + json_formatting); break; case DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE: - diagnostic_output_format_init_json_file (context, - json_formatting, - base_file_name); + new_sink = &diagnostic_output_format_init_json_file (context, + json_formatting, + base_file_name); break; case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR: - diagnostic_output_format_init_sarif_stderr (context, - line_table, - main_input_filename_, - json_formatting); + new_sink = &diagnostic_output_format_init_sarif_stderr (context, + line_table, + json_formatting); break; case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE: - diagnostic_output_format_init_sarif_file (context, - line_table, - main_input_filename_, - json_formatting, - base_file_name); + new_sink = &diagnostic_output_format_init_sarif_file (context, + line_table, + json_formatting, + base_file_name); break; } + if (new_sink) + new_sink->set_main_input_filename (main_input_filename_); } /* Initialize this context's m_diagrams based on CHARSET. diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc index 70b0f36e0438..0040db463dc1 100644 --- a/gcc/libgdiagnostics.cc +++ b/gcc/libgdiagnostics.cc @@ -1191,10 +1191,10 @@ sarif_sink::sarif_sink (diagnostic_manager &mgr, auto serialization = std::make_unique<sarif_serialization_format_json> (true); auto inner_sink = make_sarif_sink (mgr.get_dc (), *mgr.get_line_table (), - main_input_file->get_name (), std::move (serialization), sarif_gen_opts, std::move (output_file)); + inner_sink->set_main_input_filename (main_input_file->get_name ()); mgr.get_dc ().add_sink (std::move (inner_sink)); } diff --git a/gcc/opts-diagnostic.cc b/gcc/opts-diagnostic.cc index 3a1dc528ac56..3629f17f0cee 100644 --- a/gcc/opts-diagnostic.cc +++ b/gcc/opts-diagnostic.cc @@ -531,7 +531,6 @@ sarif_scheme_handler::make_sink (const context &ctxt, auto sink = make_sarif_sink (ctxt.m_dc, *line_table, - ctxt.m_opts.x_main_input_filename, std::move (serialization_obj), sarif_gen_opts, std::move (output_file)); @@ -633,6 +632,7 @@ handle_OPT_fdiagnostics_add_output_ (const gcc_options &opts, if (!sink) return; + sink->set_main_input_filename (opts.x_main_input_filename); dc.add_sink (std::move (sink)); } @@ -657,6 +657,7 @@ handle_OPT_fdiagnostics_set_output_ (const gcc_options &opts, if (!sink) return; + sink->set_main_input_filename (opts.x_main_input_filename); dc.set_output_format (std::move (sink)); } diff --git a/gcc/testsuite/gcc.dg/html-output/missing-semicolon.py b/gcc/testsuite/gcc.dg/html-output/missing-semicolon.py index 02ff84c14bb6..880fcc0231bc 100644 --- a/gcc/testsuite/gcc.dg/html-output/missing-semicolon.py +++ b/gcc/testsuite/gcc.dg/html-output/missing-semicolon.py @@ -26,7 +26,7 @@ def test_basics(html_tree): assert head is not None title = head.find('xhtml:title', ns) - assert title.text == 'Title goes here' + assert title.text.endswith('gcc/testsuite/gcc.dg/html-output/missing-semicolon.c') body = root.find('xhtml:body', ns) assert body is not None @@ -56,26 +56,3 @@ def test_basics(html_tree): assert pre is not None assert pre.attrib['class'] == 'gcc-generated-patch' assert pre.text.startswith('--- ') - -# For reference, here's the generated HTML: -""" -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html - PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>Title goes here</title> - </head> - <body> - <div class="gcc-diagnostic-list"> - <div class="gcc-diagnostic"> - <span class="gcc-message">expected '<span class="gcc-quoted-text">;</span>' before '<span class="gcc-quoted-text">}</span>' token</span> - <pre class="gcc-generated-patch"> - [...snip...] - </pre> - </div> - </div> - </body> -</html> -"""