From: David Malcolm Date: Wed, 11 Jun 2025 18:21:41 +0000 (-0400) Subject: diagnostics: add selftests for html_token_printer [PR116792] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f867196566c8aa51fd8b18dc5956daeea49e7518;p=thirdparty%2Fgcc.git diagnostics: add selftests for html_token_printer [PR116792] No functional change intended. gcc/ChangeLog: PR other/116792 * diagnostic-format-html.cc: Include "selftest-xml.h". (html_builder::make_element_for_diagnostic): Move... (class html_token_printer): ...from local to the function to the global namespace. (struct selftest::token_printer_test): New. (selftest::test_token_printer): New. (selftest::test_simple_log): Simplify using ASSERT_XML_PRINT_EQ. (selftest::test_metadata): Likewise. (selftest::diagnostic_format_html_cc_tests): Run the new test. * selftest-xml.h: New file. * xml.cc: Include "selftest-xml.h". (selftest::assert_xml_print_eq): New. (selftest::test_no_dtd): Simplify using ASSERT_XML_PRINT_EQ. (selftest::test_printer): Likewise. (selftest::test_attribute_ordering): Likewise. Signed-off-by: David Malcolm --- diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index 22bf6b965df..45d088150dd 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "xml.h" #include "xml-printer.h" #include "json.h" +#include "selftest-xml.h" // struct html_generation_options @@ -729,6 +730,82 @@ add_labelled_value (xml::printer &xp, xp.pop_tag ("div"); } +class html_token_printer : public token_printer +{ +public: + html_token_printer (xml::element &parent_element) + /* Ideally pp_token_lists that reach a token_printer should be + "balanced", but for now they can have mismatching pp_tokens + e.g. a begin_color without an end_color (PR other/120610). + Give html_token_printer its own xml::printer as a firewall to + limit the scope of the mismatches in the HTML. */ + : m_xp (parent_element, + /* Similarly we don't check that the popped tags match. */ + false) + { + } + void print_tokens (pretty_printer */*pp*/, + const pp_token_list &tokens) final override + { + /* Implement print_tokens by adding child elements to + m_parent_element. */ + for (auto iter = tokens.m_first; iter; iter = iter->m_next) + switch (iter->m_kind) + { + default: + gcc_unreachable (); + + case pp_token::kind::text: + { + pp_token_text *sub = as_a (iter); + /* The value might be in the obstack, so we may need to + copy it. */ + m_xp.add_text (sub->m_value.get ()); + } + break; + + case pp_token::kind::begin_color: + { + pp_token_begin_color *sub = as_a (iter); + gcc_assert (sub->m_value.get ()); + m_xp.push_tag_with_class ("span", sub->m_value.get ()); + } + break; + + case pp_token::kind::end_color: + m_xp.pop_tag ("span"); + break; + + case pp_token::kind::begin_quote: + { + m_xp.add_text (open_quote); + m_xp.push_tag_with_class ("span", "gcc-quoted-text"); + } + break; + case pp_token::kind::end_quote: + { + m_xp.pop_tag ("span"); + m_xp.add_text (close_quote); + } + break; + + case pp_token::kind::begin_url: + { + pp_token_begin_url *sub = as_a (iter); + m_xp.push_tag ("a", true); + m_xp.set_attr ("href", sub->m_value.get ()); + } + break; + case pp_token::kind::end_url: + m_xp.pop_tag ("a"); + break; + } + } + +private: + xml::printer m_xp; +}; + /* Make a
for DIAGNOSTIC. If ALERT is true, make it be a PatternFly alert (see @@ -744,82 +821,6 @@ html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, bool alert) { - class html_token_printer : public token_printer - { - public: - html_token_printer (xml::element &parent_element) - /* Ideally pp_token_lists that reach a token_printer should be - "balanced", but for now they can have mismatching pp_tokens - e.g. a begin_color without an end_color (PR other/120610). - Give html_token_printer its own xml::printer as a firewall to - limit the scope of the mismatches in the HTML. */ - : m_xp (parent_element, - /* Similarly we don't check that the popped tags match. */ - false) - { - } - void print_tokens (pretty_printer */*pp*/, - const pp_token_list &tokens) final override - { - /* Implement print_tokens by adding child elements to - m_parent_element. */ - for (auto iter = tokens.m_first; iter; iter = iter->m_next) - switch (iter->m_kind) - { - default: - gcc_unreachable (); - - case pp_token::kind::text: - { - pp_token_text *sub = as_a (iter); - /* The value might be in the obstack, so we may need to - copy it. */ - m_xp.add_text (sub->m_value.get ()); - } - break; - - case pp_token::kind::begin_color: - { - pp_token_begin_color *sub = as_a (iter); - gcc_assert (sub->m_value.get ()); - m_xp.push_tag_with_class ("span", sub->m_value.get ()); - } - break; - - case pp_token::kind::end_color: - m_xp.pop_tag ("span"); - break; - - case pp_token::kind::begin_quote: - { - m_xp.add_text (open_quote); - m_xp.push_tag_with_class ("span", "gcc-quoted-text"); - } - break; - case pp_token::kind::end_quote: - { - m_xp.pop_tag ("span"); - m_xp.add_text (close_quote); - } - break; - - case pp_token::kind::begin_url: - { - pp_token_begin_url *sub = as_a (iter); - m_xp.push_tag ("a", true); - m_xp.set_attr ("href", sub->m_value.get ()); - } - break; - case pp_token::kind::end_url: - m_xp.pop_tag ("a"); - break; - } - } - - private: - xml::printer m_xp; - }; - const int diag_idx = m_next_diag_id++; std::string diag_id; { @@ -1329,6 +1330,53 @@ make_html_sink (diagnostic_context &context, namespace selftest { +/* Helper for writing tests of html_token_printer. + Printing to m_pp will appear as HTML within m_top_element, a
. */ + +struct token_printer_test +{ + token_printer_test () + : m_top_element ("div", true), + m_tok_printer (m_top_element) + { + m_pp.set_token_printer (&m_tok_printer); + } + + xml::element m_top_element; + html_token_printer m_tok_printer; + pretty_printer m_pp; +}; + +static void +test_token_printer () +{ + { + token_printer_test t; + pp_printf (&t.m_pp, "hello world"); + ASSERT_XML_PRINT_EQ + (t.m_top_element, + "
hello world
\n"); + } + + { + token_printer_test t; + pp_printf (&t.m_pp, "%qs: %qs", "foo", "bar"); + ASSERT_XML_PRINT_EQ + (t.m_top_element, + "
" + "`" + "" + "foo" + "" + "': `" + "" + "bar" + "" + "'" + "
\n"); + } +} + /* A subclass of html_output_format for writing selftests. The XML output is cached internally, rather than written out to a file. */ @@ -1394,10 +1442,8 @@ test_simple_log () const xml::document &doc = dc.get_document (); - pretty_printer pp; - doc.write_as_xml (&pp, 0, true); - ASSERT_STREQ - (pp_formatted_text (&pp), + ASSERT_XML_PRINT_EQ + (doc, ("\n" "write_as_xml (&pp, 0, true); - ASSERT_STREQ - (pp_formatted_text (&pp), + ASSERT_XML_PRINT_EQ + (*element, "" "