Line data Source code
1 : /* Classes for creating XML trees by appending.
2 : Copyright (C) 2025-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along 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 :
24 : namespace xml {
25 :
26 : class 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 :
32 623 : class printer
33 : {
34 : public:
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 742 : size_t get_num_open_tags () const { return m_open_tags.size (); }
58 :
59 : void DEBUG_FUNCTION dump () const;
60 :
61 : private:
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 :
71 : class auto_check_tag_nesting
72 : {
73 : public:
74 1152 : auto_check_tag_nesting (const printer &xp)
75 1152 : : m_xp (xp),
76 1152 : m_initial_insertion_element (xp.get_insertion_point ())
77 : {
78 : }
79 1152 : ~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 1152 : gcc_assert (m_initial_insertion_element == m_xp.get_insertion_point ());
84 1152 : }
85 :
86 : private:
87 : const printer &m_xp;
88 : const element *m_initial_insertion_element;
89 : };
90 :
91 : // RAII for push/pop element on xml::printer
92 :
93 : class auto_print_element
94 : {
95 : public:
96 67 : auto_print_element (printer &printer,
97 : std::string name,
98 : bool preserve_whitespace = false)
99 67 : : m_printer (printer),
100 67 : m_name (std::move (name))
101 : {
102 134 : m_printer.push_tag (m_name, preserve_whitespace);
103 67 : }
104 67 : ~auto_print_element ()
105 : {
106 67 : m_printer.pop_tag (m_name.c_str ());
107 67 : }
108 :
109 : private:
110 : printer &m_printer;
111 : std::string m_name;
112 : };
113 :
114 : } // namespace xml
115 :
116 : #endif /* GCC_XML_PRINTER_H. */
|