Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmXMLWriter.cxx
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
#include "cmXMLWriter.h"
4
5
#include <cassert>
6
7
#include "cmsys/FStream.hxx"
8
9
cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level)
10
0
  : Output(output)
11
0
  , IndentationElement(1, '\t')
12
0
  , Level(level)
13
0
{
14
0
}
15
16
cmXMLWriter::~cmXMLWriter()
17
0
{
18
0
  assert(this->Indent == 0);
19
0
}
20
21
void cmXMLWriter::StartDocument(char const* encoding)
22
0
{
23
0
  this->Output << R"(<?xml version="1.0" encoding=")" << encoding << "\"?>";
24
0
}
25
26
void cmXMLWriter::EndDocument()
27
0
{
28
0
  assert(this->Indent == 0);
29
0
  this->Output << '\n';
30
0
}
31
32
void cmXMLWriter::StartElement(std::string const& name)
33
0
{
34
0
  this->CloseStartElement();
35
0
  this->ConditionalLineBreak(!this->IsContent);
36
0
  this->Output << '<' << name;
37
0
  this->Elements.push(name);
38
0
  ++this->Indent;
39
0
  this->ElementOpen = true;
40
0
  this->BreakAttrib = false;
41
0
}
42
43
void cmXMLWriter::EndElement()
44
0
{
45
0
  assert(this->Indent > 0);
46
0
  --this->Indent;
47
0
  if (this->ElementOpen) {
48
0
    this->Output << "/>";
49
0
  } else {
50
0
    this->ConditionalLineBreak(!this->IsContent);
51
0
    this->IsContent = false;
52
0
    this->Output << "</" << this->Elements.top() << '>';
53
0
  }
54
0
  this->Elements.pop();
55
0
  this->ElementOpen = false;
56
0
}
57
58
void cmXMLWriter::Element(char const* name)
59
0
{
60
0
  this->CloseStartElement();
61
0
  this->ConditionalLineBreak(!this->IsContent);
62
0
  this->Output << '<' << name << "/>";
63
0
}
64
65
void cmXMLWriter::BreakAttributes()
66
0
{
67
0
  this->BreakAttrib = true;
68
0
}
69
70
void cmXMLWriter::Comment(char const* comment)
71
0
{
72
0
  this->CloseStartElement();
73
0
  this->ConditionalLineBreak(!this->IsContent);
74
0
  this->Output << "<!-- " << comment << " -->";
75
0
}
76
77
void cmXMLWriter::CData(std::string const& data)
78
0
{
79
0
  this->PreContent();
80
0
  this->Output << "<![CDATA[" << data << "]]>";
81
0
}
82
83
void cmXMLWriter::Doctype(char const* doctype)
84
0
{
85
0
  this->CloseStartElement();
86
0
  this->ConditionalLineBreak(!this->IsContent);
87
0
  this->Output << "<!DOCTYPE " << doctype << ">";
88
0
}
89
90
void cmXMLWriter::ProcessingInstruction(char const* target, char const* data)
91
0
{
92
0
  this->CloseStartElement();
93
0
  this->ConditionalLineBreak(!this->IsContent);
94
0
  this->Output << "<?" << target << ' ' << data << "?>";
95
0
}
96
97
void cmXMLWriter::FragmentFile(char const* fname)
98
0
{
99
0
  this->CloseStartElement();
100
0
  cmsys::ifstream fin(fname, std::ios::in | std::ios::binary);
101
0
  this->Output << fin.rdbuf();
102
0
}
103
104
void cmXMLWriter::SetIndentationElement(std::string const& element)
105
0
{
106
0
  this->IndentationElement = element;
107
0
}
108
109
void cmXMLWriter::ConditionalLineBreak(bool condition)
110
0
{
111
0
  if (condition) {
112
0
    this->Output << '\n';
113
0
    for (std::size_t i = 0; i < this->Indent + this->Level; ++i) {
114
0
      this->Output << this->IndentationElement;
115
0
    }
116
0
  }
117
0
}
118
119
void cmXMLWriter::PreAttribute()
120
0
{
121
0
  assert(this->ElementOpen);
122
0
  this->ConditionalLineBreak(this->BreakAttrib);
123
0
  if (!this->BreakAttrib) {
124
0
    this->Output << ' ';
125
0
  }
126
0
}
127
128
void cmXMLWriter::PreContent()
129
0
{
130
0
  this->CloseStartElement();
131
0
  this->IsContent = true;
132
0
}
133
134
void cmXMLWriter::CloseStartElement()
135
0
{
136
0
  if (this->ElementOpen) {
137
0
    this->ConditionalLineBreak(this->BreakAttrib);
138
0
    this->Output << '>';
139
0
    this->ElementOpen = false;
140
0
  }
141
0
}