Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmXMLWriter.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <chrono>
8
#include <cstddef> // IWYU pragma: keep
9
#include <ctime>
10
#include <ostream>
11
#include <stack>
12
#include <string>
13
#include <vector>
14
15
#include "cmDuration.h"
16
#include "cmXMLSafe.h"
17
18
class cmXMLWriter
19
{
20
public:
21
  cmXMLWriter(std::ostream& output, std::size_t level = 0);
22
  ~cmXMLWriter();
23
24
  cmXMLWriter(cmXMLWriter const&) = delete;
25
  cmXMLWriter& operator=(cmXMLWriter const&) = delete;
26
27
  void StartDocument(char const* encoding = "UTF-8");
28
  void EndDocument();
29
30
  void StartElement(std::string const& name);
31
  void EndElement();
32
33
  void BreakAttributes();
34
35
  template <typename T>
36
  void Attribute(char const* name, T const& value)
37
0
  {
38
0
    this->PreAttribute();
39
0
    this->Output << name << "=\"" << SafeAttribute(value) << '"';
40
0
  }
Unexecuted instantiation: void cmXMLWriter::Attribute<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: void cmXMLWriter::Attribute<char [13]>(char const*, char const (&) [13])
Unexecuted instantiation: void cmXMLWriter::Attribute<int>(char const*, int const&)
Unexecuted instantiation: void cmXMLWriter::Attribute<char [3]>(char const*, char const (&) [3])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [4]>(char const*, char const (&) [4])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [1]>(char const*, char const (&) [1])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [8]>(char const*, char const (&) [8])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [17]>(char const*, char const (&) [17])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [7]>(char const*, char const (&) [7])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [2]>(char const*, char const (&) [2])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [40]>(char const*, char const (&) [40])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [25]>(char const*, char const (&) [25])
Unexecuted instantiation: void cmXMLWriter::Attribute<char const*>(char const*, char const* const&)
Unexecuted instantiation: void cmXMLWriter::Attribute<char [5]>(char const*, char const (&) [5])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [30]>(char const*, char const (&) [30])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [38]>(char const*, char const (&) [38])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [47]>(char const*, char const (&) [47])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [14]>(char const*, char const (&) [14])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [34]>(char const*, char const (&) [34])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [29]>(char const*, char const (&) [29])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [31]>(char const*, char const (&) [31])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [24]>(char const*, char const (&) [24])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [39]>(char const*, char const (&) [39])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [15]>(char const*, char const (&) [15])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [6]>(char const*, char const (&) [6])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [21]>(char const*, char const (&) [21])
Unexecuted instantiation: void cmXMLWriter::Attribute<char [59]>(char const*, char const (&) [59])
41
42
  void Element(char const* name);
43
44
  template <typename T>
45
  void Element(std::string const& name, T const& value)
46
0
  {
47
0
    this->StartElement(name);
48
0
    this->Content(value);
49
0
    this->EndElement();
50
0
  }
Unexecuted instantiation: void cmXMLWriter::Element<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: void cmXMLWriter::Element<char [17]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [17])
Unexecuted instantiation: void cmXMLWriter::Element<char [1]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [1])
Unexecuted instantiation: void cmXMLWriter::Element<char [38]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [38])
Unexecuted instantiation: void cmXMLWriter::Element<char [24]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [24])
Unexecuted instantiation: void cmXMLWriter::Element<char [4]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [4])
Unexecuted instantiation: void cmXMLWriter::Element<char [47]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [47])
Unexecuted instantiation: void cmXMLWriter::Element<char [37]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [37])
Unexecuted instantiation: void cmXMLWriter::Element<char [46]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [46])
Unexecuted instantiation: void cmXMLWriter::Element<char const*>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const* const&)
Unexecuted instantiation: void cmXMLWriter::Element<char [5]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [5])
Unexecuted instantiation: void cmXMLWriter::Element<char [6]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [6])
Unexecuted instantiation: void cmXMLWriter::Element<int>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int const&)
51
52
  template <typename T>
53
  void Content(T const& content)
54
0
  {
55
0
    this->PreContent();
56
0
    this->Output << SafeContent(content);
57
0
  }
Unexecuted instantiation: void cmXMLWriter::Content<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: void cmXMLWriter::Content<char [17]>(char const (&) [17])
Unexecuted instantiation: void cmXMLWriter::Content<char [1]>(char const (&) [1])
Unexecuted instantiation: void cmXMLWriter::Content<char [38]>(char const (&) [38])
Unexecuted instantiation: void cmXMLWriter::Content<char [24]>(char const (&) [24])
Unexecuted instantiation: void cmXMLWriter::Content<char [4]>(char const (&) [4])
Unexecuted instantiation: void cmXMLWriter::Content<char [47]>(char const (&) [47])
Unexecuted instantiation: void cmXMLWriter::Content<char [37]>(char const (&) [37])
Unexecuted instantiation: void cmXMLWriter::Content<char [46]>(char const (&) [46])
Unexecuted instantiation: void cmXMLWriter::Content<char const*>(char const* const&)
Unexecuted instantiation: void cmXMLWriter::Content<char [5]>(char const (&) [5])
Unexecuted instantiation: void cmXMLWriter::Content<char [6]>(char const (&) [6])
Unexecuted instantiation: void cmXMLWriter::Content<int>(int const&)
58
59
  void Comment(char const* comment);
60
61
  void CData(std::string const& data);
62
63
  void Doctype(char const* doctype);
64
65
  void ProcessingInstruction(char const* target, char const* data);
66
67
  void FragmentFile(char const* fname);
68
69
  void SetIndentationElement(std::string const& element);
70
71
private:
72
  void ConditionalLineBreak(bool condition);
73
74
  void PreAttribute();
75
  void PreContent();
76
77
  void CloseStartElement();
78
79
0
  static cmXMLSafe SafeAttribute(char const* value) { return { value }; }
80
81
  static cmXMLSafe SafeAttribute(std::string const& value)
82
0
  {
83
0
    return { value };
84
0
  }
85
86
  template <typename T>
87
  static T SafeAttribute(T value)
88
0
  {
89
0
    return value;
90
0
  }
91
92
  static cmXMLSafe SafeContent(char const* value)
93
0
  {
94
0
    return cmXMLSafe(value).Quotes(false);
95
0
  }
96
97
  static cmXMLSafe SafeContent(std::string const& value)
98
0
  {
99
0
    return cmXMLSafe(value).Quotes(false);
100
0
  }
101
102
  /*
103
   * Convert a std::chrono::system::time_point to the number of seconds since
104
   * the UN*X epoch.
105
   *
106
   * It would be tempting to convert a time_point to number of seconds by
107
   * using time_since_epoch(). Unfortunately the C++11 standard does not
108
   * specify what the epoch of the system_clock must be.
109
   * Therefore we must assume it is an arbitrary point in time. Instead of this
110
   * method, it is recommended to convert it by means of the to_time_t method.
111
   */
112
  static std::time_t SafeContent(std::chrono::system_clock::time_point value)
113
0
  {
114
0
    return std::chrono::system_clock::to_time_t(value);
115
0
  }
116
117
  /* Some code paths use time_since_epoch despite the unspecified epoch.  */
118
0
  static double SafeContent(cmDuration value) { return value.count(); }
119
120
  template <typename T>
121
  static T SafeContent(T value)
122
0
  {
123
0
    return value;
124
0
  }
125
126
  std::ostream& Output;
127
  std::stack<std::string, std::vector<std::string>> Elements;
128
  std::string IndentationElement;
129
  std::size_t Level;
130
  std::size_t Indent = 0;
131
  bool ElementOpen = false;
132
  bool BreakAttrib = false;
133
  bool IsContent = false;
134
};
135
136
class cmXMLElement; // IWYU pragma: keep
137
138
class cmXMLDocument
139
{
140
public:
141
  cmXMLDocument(cmXMLWriter& xml)
142
    : xmlwr(xml)
143
0
  {
144
0
    this->xmlwr.StartDocument();
145
0
  }
146
0
  ~cmXMLDocument() { this->xmlwr.EndDocument(); }
147
  cmXMLDocument(cmXMLDocument const&) = delete;
148
  cmXMLDocument& operator=(cmXMLDocument const&) = delete;
149
150
private:
151
  friend class cmXMLElement;
152
  cmXMLWriter& xmlwr;
153
};
154
155
class cmXMLElement
156
{
157
public:
158
  cmXMLElement(cmXMLWriter& xml, char const* tag)
159
    : xmlwr(xml)
160
0
  {
161
0
    this->xmlwr.StartElement(tag);
162
0
  }
163
  cmXMLElement(cmXMLElement& par, char const* tag)
164
    : xmlwr(par.xmlwr)
165
0
  {
166
0
    this->xmlwr.StartElement(tag);
167
0
  }
168
  cmXMLElement(cmXMLDocument& doc, char const* tag)
169
    : xmlwr(doc.xmlwr)
170
0
  {
171
0
    this->xmlwr.StartElement(tag);
172
0
  }
173
0
  ~cmXMLElement() { this->xmlwr.EndElement(); }
174
175
  cmXMLElement(cmXMLElement const&) = delete;
176
  cmXMLElement& operator=(cmXMLElement const&) = delete;
177
178
  template <typename T>
179
  cmXMLElement& Attribute(char const* name, T const& value)
180
  {
181
    this->xmlwr.Attribute(name, value);
182
    return *this;
183
  }
184
  template <typename T>
185
  void Content(T const& content)
186
  {
187
    this->xmlwr.Content(content);
188
  }
189
  template <typename T>
190
  void Element(std::string const& name, T const& value)
191
  {
192
    this->xmlwr.Element(name, value);
193
  }
194
0
  void Comment(char const* comment) { this->xmlwr.Comment(comment); }
195
196
private:
197
  cmXMLWriter& xmlwr;
198
};