diff options
Diffstat (limited to 'gcc/diagnostic-format-html.cc')
-rw-r--r-- | gcc/diagnostic-format-html.cc | 332 |
1 files changed, 19 insertions, 313 deletions
diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index 05d4273..ea2dbbb 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -49,256 +49,6 @@ html_generation_options::html_generation_options () { } -namespace xml { - -/* Disable warnings about quoting issues in the pp_xxx calls below - that (intentionally) don't follow GCC diagnostic conventions. */ -#if __GNUC__ >= 10 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-diag" -#endif - - -/* Implementation. */ - -static void -write_escaped_text (pretty_printer *pp, const char *text) -{ - gcc_assert (text); - - for (const char *p = text; *p; ++p) - { - char ch = *p; - switch (ch) - { - default: - pp_character (pp, ch); - break; - case '\'': - pp_string (pp, "'"); - break; - case '"': - pp_string (pp, """); - break; - case '&': - pp_string (pp, "&"); - break; - case '<': - pp_string (pp, "<"); - break; - case '>': - pp_string (pp, ">"); - break; - } - } -} - -/* struct node. */ - -void -node::dump (FILE *out) const -{ - pretty_printer pp; - pp.set_output_stream (out); - write_as_xml (&pp, 0, true); - pp_flush (&pp); -} - -/* struct text : public node. */ - -void -text::write_as_xml (pretty_printer *pp, int depth, bool indent) const -{ - if (indent) - { - for (int i = 0; i < depth; ++i) - pp_string (pp, " "); - } - write_escaped_text (pp, m_str.c_str ()); - if (indent) - pp_newline (pp); -} - -/* struct node_with_children : public node. */ - -void -node_with_children::add_child (std::unique_ptr<node> node) -{ - gcc_assert (node.get ()); - m_children.push_back (std::move (node)); -} - -void -node_with_children::add_text (std::string str) -{ - // Consolidate runs of text - if (!m_children.empty ()) - if (text *t = m_children.back ()->dyn_cast_text ()) - { - t->m_str += std::move (str); - return; - } - add_child (std::make_unique <text> (std::move (str))); -} - - -/* struct document : public node_with_children. */ - -void -document::write_as_xml (pretty_printer *pp, int depth, bool indent) const -{ - pp_string (pp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - pp_string (pp, "<!DOCTYPE html\n" - " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" - " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"); - if (indent) - pp_newline (pp); - for (auto &iter : m_children) - iter->write_as_xml (pp, depth, indent); -} - -/* struct element : public node_with_children. */ - -void -element::write_as_xml (pretty_printer *pp, int depth, bool indent) const -{ - if (indent) - { - for (int i = 0; i < depth; ++i) - pp_string (pp, " "); - } - - pp_printf (pp, "<%s", m_kind.c_str ()); - for (auto &key : m_key_insertion_order) - { - auto iter = m_attributes.find (key); - if (iter != m_attributes.end ()) - { - pp_printf (pp, " %s=\"", key.c_str ()); - write_escaped_text (pp, iter->second.c_str ()); - pp_string (pp, "\""); - } - } - if (m_children.empty ()) - pp_string (pp, "/>"); - else - { - const bool indent_children = m_preserve_whitespace ? false : indent; - pp_string (pp, ">"); - if (indent_children) - pp_newline (pp); - for (auto &child : m_children) - child->write_as_xml (pp, depth + 1, indent_children); - if (indent_children) - { - for (int i = 0; i < depth; ++i) - pp_string (pp, " "); - } - pp_printf (pp, "</%s>", m_kind.c_str ()); - } - - if (indent) - pp_newline (pp); -} - -void -element::set_attr (const char *name, std::string value) -{ - auto iter = m_attributes.find (name); - if (iter == m_attributes.end ()) - m_key_insertion_order.push_back (name); - m_attributes[name] = std::move (value); -} - -// struct raw : public node - -void -raw::write_as_xml (pretty_printer *pp, - int /*depth*/, bool /*indent*/) const -{ - pp_string (pp, m_xml_src.c_str ()); -} - -#if __GNUC__ >= 10 -# pragma GCC diagnostic pop -#endif - -// class printer - -printer::printer (element &insertion_point) -{ - m_open_tags.push_back (&insertion_point); -} - -void -printer::push_tag (std::string name, - bool preserve_whitespace) -{ - push_element - (std::make_unique<element> (std::move (name), - preserve_whitespace)); -} - -void -printer::push_tag_with_class (std::string name, std::string class_, - bool preserve_whitespace) -{ - auto new_element - = std::make_unique<element> (std::move (name), - preserve_whitespace); - new_element->set_attr ("class", class_); - push_element (std::move (new_element)); -} - -void -printer::pop_tag () -{ - m_open_tags.pop_back (); -} - -void -printer::set_attr (const char *name, std::string value) -{ - m_open_tags.back ()->set_attr (name, value); -} - -void -printer::add_text (std::string text) -{ - element *parent = m_open_tags.back (); - parent->add_text (std::move (text)); -} - -void -printer::add_raw (std::string text) -{ - element *parent = m_open_tags.back (); - parent->add_child (std::make_unique<xml::raw> (std::move (text))); -} - -void -printer::push_element (std::unique_ptr<element> new_element) -{ - element *parent = m_open_tags.back (); - m_open_tags.push_back (new_element.get ()); - parent->add_child (std::move (new_element)); -} - -void -printer::append (std::unique_ptr<node> new_node) -{ - element *parent = m_open_tags.back (); - parent->add_child (std::move (new_node)); -} - -element * -printer::get_insertion_point () const -{ - return m_open_tags.back (); -} - -} // namespace xml - class html_builder; /* Concrete buffering implementation subclass for HTML output. */ @@ -569,6 +319,24 @@ const char * const HTML_SCRIPT " });\n" " highlight_current_focus_idx ();\n"); +struct html_doctypedecl : public xml::doctypedecl +{ + void write_as_xml (pretty_printer *pp, + int depth, bool indent) const final override + { + if (indent) + { + for (int i = 0; i < depth; ++i) + pp_string (pp, " "); + } + pp_string (pp, "<!DOCTYPE html\n" + " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"); + if (indent) + pp_newline (pp); + } +}; + /* html_builder's ctor. */ html_builder::html_builder (diagnostic_context &context, @@ -586,6 +354,7 @@ html_builder::html_builder (diagnostic_context &context, gcc_assert (m_line_maps); m_document = std::make_unique<xml::document> (); + m_document->m_doctypedecl = std::make_unique<html_doctypedecl> (); { auto html_element = std::make_unique<xml::element> ("html", false); html_element->set_attr ("xmlns", @@ -1288,67 +1057,6 @@ test_metadata () } } -static void -test_printer () -{ - xml::element top ("top", false); - xml::printer xp (top); - xp.push_tag ("foo"); - xp.add_text ("hello"); - xp.push_tag ("bar"); - xp.set_attr ("size", "3"); - xp.set_attr ("color", "red"); - xp.add_text ("world"); - xp.push_tag ("baz"); - xp.pop_tag (); - xp.pop_tag (); - xp.pop_tag (); - - pretty_printer pp; - top.write_as_xml (&pp, 0, true); - ASSERT_STREQ - (pp_formatted_text (&pp), - "<top>\n" - " <foo>\n" - " hello\n" - " <bar size=\"3\" color=\"red\">\n" - " world\n" - " <baz/>\n" - " </bar>\n" - " </foo>\n" - "</top>\n"); -} - -// Verify that element attributes preserve insertion order. - -static void -test_attribute_ordering () -{ - xml::element top ("top", false); - xml::printer xp (top); - xp.push_tag ("chronological"); - xp.set_attr ("maldon", "991"); - xp.set_attr ("hastings", "1066"); - xp.set_attr ("edgehill", "1642"); - xp.set_attr ("naseby", "1645"); - xp.pop_tag (); - xp.push_tag ("alphabetical"); - xp.set_attr ("edgehill", "1642"); - xp.set_attr ("hastings", "1066"); - xp.set_attr ("maldon", "991"); - xp.set_attr ("naseby", "1645"); - xp.pop_tag (); - - pretty_printer pp; - top.write_as_xml (&pp, 0, true); - ASSERT_STREQ - (pp_formatted_text (&pp), - "<top>\n" - " <chronological maldon=\"991\" hastings=\"1066\" edgehill=\"1642\" naseby=\"1645\"/>\n" - " <alphabetical edgehill=\"1642\" hastings=\"1066\" maldon=\"991\" naseby=\"1645\"/>\n" - "</top>\n"); -} - /* Run all of the selftests within this file. */ void @@ -1357,8 +1065,6 @@ diagnostic_format_html_cc_tests () auto_fix_quotes fix_quotes; test_simple_log (); test_metadata (); - test_printer (); - test_attribute_ordering (); } } // namespace selftest |