1/* Classes for creating XML trees by appending.
2 Copyright (C) 2025 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_XML_PRINTER_H
22#define GCC_XML_PRINTER_H
23
24namespace xml {
25
26class node;
27 class element;
28
29/* A class for creating XML trees by appending to an insertion
30 point, with a stack of open tags. */
31
32class printer
33{
34public:
35 printer (element &insertion_point, bool check_popped_tags = true);
36
37 void push_tag (std::string name,
38 bool preserve_whitespace = false);
39 void push_tag_with_class (std::string name,
40 std::string class_,
41 bool preserve_whitespace = false);
42 void pop_tag (const char *expected_name);
43
44 void set_attr (const char *name, std::string value);
45
46 void add_text (std::string text);
47 void add_text_from_pp (pretty_printer &pp);
48
49 void add_raw (std::string text);
50
51 void push_element (std::unique_ptr<element> new_element);
52
53 void append (std::unique_ptr<node> new_node);
54
55 element *get_insertion_point () const;
56
57 size_t get_num_open_tags () const { return m_open_tags.size (); }
58
59 void DEBUG_FUNCTION dump () const;
60
61private:
62 // borrowed ptrs:
63 std::vector<element *> m_open_tags;
64 bool m_check_popped_tags;
65};
66
67/* RAII class for ensuring that the tags nested correctly.
68 Verify that within an instance's lifetime that any pushes
69 to the printer's insertion point have been popped by the end. */
70
71class auto_check_tag_nesting
72{
73public:
74 auto_check_tag_nesting (const printer &xp)
75 : m_xp (xp),
76 m_initial_insertion_element (xp.get_insertion_point ())
77 {
78 }
79 ~auto_check_tag_nesting ()
80 {
81 /* Verify that we didn't pop too many tags within the printer,
82 or leave any tags open. */
83 gcc_assert (m_initial_insertion_element == m_xp.get_insertion_point ());
84 }
85
86private:
87 const printer &m_xp;
88 const element *m_initial_insertion_element;
89};
90
91// RAII for push/pop element on xml::printer
92
93class auto_print_element
94{
95public:
96 auto_print_element (printer &printer,
97 std::string name,
98 bool preserve_whitespace = false)
99 : m_printer (printer),
100 m_name (std::move (name))
101 {
102 m_printer.push_tag (name: m_name, preserve_whitespace);
103 }
104 ~auto_print_element ()
105 {
106 m_printer.pop_tag (expected_name: m_name.c_str ());
107 }
108
109private:
110 printer &m_printer;
111 std::string m_name;
112};
113
114} // namespace xml
115
116#endif /* GCC_XML_PRINTER_H. */
117

source code of gcc/xml-printer.h