Branch data Line data Source code
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 : :
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 : 351 : 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 : 616 : 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 : 51 : auto_print_element (printer &printer,
97 : : std::string name,
98 : : bool preserve_whitespace = false)
99 : 51 : : m_printer (printer),
100 : 51 : m_name (std::move (name))
101 : : {
102 : 102 : m_printer.push_tag (m_name, preserve_whitespace);
103 : 51 : }
104 : 51 : ~auto_print_element ()
105 : : {
106 : 51 : m_printer.pop_tag (m_name.c_str ());
107 : 51 : }
108 : :
109 : : private:
110 : : printer &m_printer;
111 : : std::string m_name;
112 : : };
113 : :
114 : : } // namespace xml
115 : :
116 : : #endif /* GCC_XML_PRINTER_H. */
|