Skip to content

Commit 758d685

Browse files
committed
Use TinyXML to write XML files
1 parent a9a5dc0 commit 758d685

4 files changed

Lines changed: 69 additions & 88 deletions

File tree

externals/tinyxml/tinyxml2.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,11 +1729,11 @@ void XMLDocument::PrintError() const
17291729
}
17301730

17311731

1732-
XMLPrinter::XMLPrinter( FILE* file, bool compact ) :
1732+
XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
17331733
_elementJustOpened( false ),
17341734
_firstElement( true ),
17351735
_fp( file ),
1736-
_depth( 0 ),
1736+
_depth( depth ),
17371737
_textDepth( -1 ),
17381738
_processEntities( true ),
17391739
_compactMode( compact )
@@ -1840,7 +1840,7 @@ void XMLPrinter::PrintString( const char* p, bool restricted )
18401840
void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
18411841
{
18421842
if ( writeBOM ) {
1843-
static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
1843+
static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
18441844
Print( "%s", bom );
18451845
}
18461846
if ( writeDec ) {
@@ -1858,6 +1858,8 @@ void XMLPrinter::OpenElement( const char* name )
18581858

18591859
if ( _textDepth < 0 && !_firstElement && !_compactMode ) {
18601860
Print( "\n" );
1861+
}
1862+
if ( !_compactMode ) {
18611863
PrintSpace( _depth );
18621864
}
18631865

externals/tinyxml/tinyxml2.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ not claim that you wrote the original software. If you use this
1414
software in a product, an acknowledgment in the product documentation
1515
would be appreciated but is not required.
1616
17+
1718
2. Altered source versions must be plainly marked as such, and
1819
must not be misrepresented as being the original software.
1920
@@ -125,11 +126,9 @@ class XMLDocument;
125126
class XMLElement;
126127
class XMLAttribute;
127128
class XMLComment;
128-
class XMLNode;
129129
class XMLText;
130130
class XMLDeclaration;
131131
class XMLUnknown;
132-
133132
class XMLPrinter;
134133

135134
/*
@@ -144,14 +143,14 @@ class StrPair
144143
enum {
145144
NEEDS_ENTITY_PROCESSING = 0x01,
146145
NEEDS_NEWLINE_NORMALIZATION = 0x02,
147-
COLLAPSE_WHITESPACE = 0x04,
146+
COLLAPSE_WHITESPACE = 0x04,
148147

149-
TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
148+
TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
150149
TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
151-
ATTRIBUTE_NAME = 0,
152-
ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
153-
ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
154-
COMMENT = NEEDS_NEWLINE_NORMALIZATION
150+
ATTRIBUTE_NAME = 0,
151+
ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
152+
ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
153+
COMMENT = NEEDS_NEWLINE_NORMALIZATION
155154
};
156155

157156
StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
@@ -1884,7 +1883,7 @@ class TINYXML2_LIB XMLPrinter : public XMLVisitor
18841883
If 'compact' is set to true, then output is created
18851884
with only required whitespace and newlines.
18861885
*/
1887-
XMLPrinter( FILE* file=0, bool compact = false );
1886+
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
18881887
~XMLPrinter() {}
18891888

18901889
/** If streaming, write the BOM and declaration. */

lib/errorlogger.cpp

Lines changed: 38 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "tokenlist.h"
2323
#include "token.h"
2424

25+
#include <tinyxml2.h>
26+
2527
#include <cassert>
2628
#include <sstream>
2729
#include <vector>
@@ -177,95 +179,73 @@ std::string ErrorLogger::ErrorMessage::getXMLHeader(int xml_version)
177179
{
178180
// xml_version 1 is the default xml format
179181

180-
// standard xml header
181-
std::ostringstream ostr;
182-
ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
182+
tinyxml2::XMLPrinter printer;
183183

184-
// version 1 header
185-
if (xml_version <= 1) {
186-
ostr << "<results>";
187-
}
184+
// standard xml header
185+
printer.PushDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
188186

187+
// header
188+
printer.OpenElement("results");
189189
// version 2 header
190-
else {
191-
ostr << "<results version=\"" << xml_version << "\">\n";
192-
ostr << " <cppcheck version=\"" << CppCheck::version() << "\"/>\n";
193-
ostr << " <errors>";
190+
if (xml_version == 2) {
191+
printer.PushAttribute("version", xml_version);
192+
printer.OpenElement("cppcheck");
193+
printer.PushAttribute("version", CppCheck::version());
194+
printer.CloseElement();
195+
printer.OpenElement("errors");
194196
}
195197

196-
return ostr.str();
198+
return std::string(printer.CStr()) + '>';
197199
}
198200

199201
std::string ErrorLogger::ErrorMessage::getXMLFooter(int xml_version)
200202
{
201-
return (xml_version<=1) ? "</results>" : " </errors>\n</results>";
202-
}
203-
204-
static std::string stringToXml(std::string s)
205-
{
206-
// convert a string so it can be save as xml attribute data
207-
std::string::size_type pos = 0;
208-
while ((pos = s.find_first_of("<>&\"\n", pos)) != std::string::npos) {
209-
if (s[pos] == '<')
210-
s.insert(pos + 1, "&lt;");
211-
else if (s[pos] == '>')
212-
s.insert(pos + 1, "&gt;");
213-
else if (s[pos] == '&')
214-
s.insert(pos + 1, "&amp;");
215-
else if (s[pos] == '"')
216-
s.insert(pos + 1, "&quot;");
217-
else if (s[pos] == '\n')
218-
s.insert(pos + 1, "&#xa;");
219-
s.erase(pos, 1);
220-
++pos;
221-
}
222-
return s;
203+
return (xml_version<=1) ? "</results>" : " </errors>\n</results>";
223204
}
224205

225206
std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
226207
{
227-
// Save this ErrorMessage as an XML element
228-
std::ostringstream xml;
229-
230208
// The default xml format
231209
if (version == 1) {
232210
// No inconclusive messages in the xml version 1
233211
if (_inconclusive)
234212
return "";
235213

236-
xml << "<error";
214+
tinyxml2::XMLPrinter printer(0, false, 1);
215+
printer.OpenElement("error");
237216
if (!_callStack.empty()) {
238-
xml << " file=\"" << stringToXml(_callStack.back().getfile()) << "\"";
239-
xml << " line=\"" << _callStack.back().line << "\"";
217+
printer.PushAttribute("file", _callStack.back().getfile().c_str());
218+
printer.PushAttribute("line", _callStack.back().line);
240219
}
241-
xml << " id=\"" << _id << "\"";
242-
xml << " severity=\"" << (_severity == Severity::error ? "error" : "style") << "\"";
243-
xml << " msg=\"" << stringToXml(verbose ? _verboseMessage : _shortMessage) << "\"";
244-
xml << "/>";
220+
printer.PushAttribute("id", _id.c_str());
221+
printer.PushAttribute("severity", (_severity == Severity::error ? "error" : "style"));
222+
printer.PushAttribute("msg", (verbose ? _verboseMessage : _shortMessage).c_str());
223+
printer.CloseElement();
224+
return printer.CStr();
245225
}
246226

247227
// The xml format you get when you use --xml-version=2
248228
else if (version == 2) {
249-
xml << " <error";
250-
xml << " id=\"" << _id << "\"";
251-
xml << " severity=\"" << Severity::toString(_severity) << "\"";
252-
xml << " msg=\"" << stringToXml(_shortMessage) << "\"";
253-
xml << " verbose=\"" << stringToXml(_verboseMessage) << "\"";
229+
tinyxml2::XMLPrinter printer(0, false, 2);
230+
printer.OpenElement("error");
231+
printer.PushAttribute("id", _id.c_str());
232+
printer.PushAttribute("severity", Severity::toString(_severity).c_str());
233+
printer.PushAttribute("msg", _shortMessage.c_str());
234+
printer.PushAttribute("verbose", _verboseMessage.c_str());
254235
if (_inconclusive)
255-
xml << " inconclusive=\"true\"";
256-
xml << ">" << std::endl;
236+
printer.PushAttribute("inconclusive", "true");
257237

258238
for (std::list<FileLocation>::const_reverse_iterator it = _callStack.rbegin(); it != _callStack.rend(); ++it) {
259-
xml << " <location";
260-
xml << " file=\"" << stringToXml((*it).getfile()) << "\"";
261-
xml << " line=\"" << (*it).line << "\"";
262-
xml << "/>" << std::endl;
239+
printer.OpenElement("location");
240+
printer.PushAttribute("file", (*it).getfile().c_str());
241+
printer.PushAttribute("line", (*it).line);
242+
printer.CloseElement();
263243
}
264-
265-
xml << " </error>";
244+
printer.CloseElement();
245+
return printer.CStr();
266246
}
267247

268-
return xml.str();
248+
return "";
269249
}
270250

271251
void ErrorLogger::ErrorMessage::findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith)

test/testerrorlogger.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class TestErrorLogger : public TestFixture {
187187
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
188188
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
189189
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
190-
ASSERT_EQUALS("<error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
190+
ASSERT_EQUALS(" <error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
191191
}
192192

193193
void ToXmlLocations() const {
@@ -203,7 +203,7 @@ class TestErrorLogger : public TestFixture {
203203
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
204204
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
205205
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
206-
ASSERT_EQUALS("<error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
206+
ASSERT_EQUALS(" <error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
207207
}
208208

209209
void ToVerboseXml() const {
@@ -215,7 +215,7 @@ class TestErrorLogger : public TestFixture {
215215
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
216216
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
217217
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
218-
ASSERT_EQUALS("<error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
218+
ASSERT_EQUALS(" <error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
219219
}
220220

221221
void ToVerboseXmlLocations() const {
@@ -231,7 +231,7 @@ class TestErrorLogger : public TestFixture {
231231
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
232232
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
233233
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
234-
ASSERT_EQUALS("<error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
234+
ASSERT_EQUALS(" <error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
235235
}
236236

237237
void ToXmlV2() const {
@@ -242,14 +242,14 @@ class TestErrorLogger : public TestFixture {
242242
locs.push_back(loc);
243243
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
244244
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n");
245-
header += " <cppcheck version=\"";
245+
header += " <cppcheck version=\"";
246246
header += CppCheck::version();
247-
header += "\"/>\n <errors>";
247+
header += "\"/>\n <errors>";
248248
ASSERT_EQUALS(header, ErrorLogger::ErrorMessage::getXMLHeader(2));
249-
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
250-
std::string message(" <error id=\"errorId\" severity=\"error\"");
249+
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
250+
std::string message(" <error id=\"errorId\" severity=\"error\"");
251251
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
252-
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
252+
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
253253
ASSERT_EQUALS(message, msg.toXML(false, 2));
254254
}
255255

@@ -265,15 +265,15 @@ class TestErrorLogger : public TestFixture {
265265
locs.push_back(loc2);
266266
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
267267
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n");
268-
header += " <cppcheck version=\"";
268+
header += " <cppcheck version=\"";
269269
header += CppCheck::version();
270-
header += "\"/>\n <errors>";
270+
header += "\"/>\n <errors>";
271271
ASSERT_EQUALS(header, ErrorLogger::ErrorMessage::getXMLHeader(2));
272-
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
273-
std::string message(" <error id=\"errorId\" severity=\"error\"");
272+
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
273+
std::string message(" <error id=\"errorId\" severity=\"error\"");
274274
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
275-
message += " <location file=\"bar.cpp\" line=\"8\"/>\n";
276-
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
275+
message += " <location file=\"bar.cpp\" line=\"8\"/>\n";
276+
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
277277
ASSERT_EQUALS(message, msg.toXML(false, 2));
278278
}
279279

@@ -292,9 +292,9 @@ class TestErrorLogger : public TestFixture {
292292
ASSERT_EQUALS("", msg.toXML(false, 1));
293293

294294
// xml version 2 error message
295-
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error\" verbose=\"Programming error\" inconclusive=\"true\">\n"
296-
" <location file=\"foo.cpp\" line=\"5\"/>\n"
297-
" </error>",
295+
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error\" verbose=\"Programming error\" inconclusive=\"true\">\n"
296+
" <location file=\"foo.cpp\" line=\"5\"/>\n"
297+
" </error>",
298298
msg.toXML(false, 2));
299299
}
300300

0 commit comments

Comments
 (0)