Use TinyXML to write XML files
This commit is contained in:
parent
a9a5dc0354
commit
758d68519d
|
@ -1729,11 +1729,11 @@ void XMLDocument::PrintError() const
|
|||
}
|
||||
|
||||
|
||||
XMLPrinter::XMLPrinter( FILE* file, bool compact ) :
|
||||
XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
|
||||
_elementJustOpened( false ),
|
||||
_firstElement( true ),
|
||||
_fp( file ),
|
||||
_depth( 0 ),
|
||||
_depth( depth ),
|
||||
_textDepth( -1 ),
|
||||
_processEntities( true ),
|
||||
_compactMode( compact )
|
||||
|
@ -1840,7 +1840,7 @@ void XMLPrinter::PrintString( const char* p, bool restricted )
|
|||
void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
|
||||
{
|
||||
if ( writeBOM ) {
|
||||
static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
|
||||
static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
|
||||
Print( "%s", bom );
|
||||
}
|
||||
if ( writeDec ) {
|
||||
|
@ -1858,6 +1858,8 @@ void XMLPrinter::OpenElement( const char* name )
|
|||
|
||||
if ( _textDepth < 0 && !_firstElement && !_compactMode ) {
|
||||
Print( "\n" );
|
||||
}
|
||||
if ( !_compactMode ) {
|
||||
PrintSpace( _depth );
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ not claim that you wrote the original software. If you use this
|
|||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
|
@ -125,11 +126,9 @@ class XMLDocument;
|
|||
class XMLElement;
|
||||
class XMLAttribute;
|
||||
class XMLComment;
|
||||
class XMLNode;
|
||||
class XMLText;
|
||||
class XMLDeclaration;
|
||||
class XMLUnknown;
|
||||
|
||||
class XMLPrinter;
|
||||
|
||||
/*
|
||||
|
@ -144,14 +143,14 @@ public:
|
|||
enum {
|
||||
NEEDS_ENTITY_PROCESSING = 0x01,
|
||||
NEEDS_NEWLINE_NORMALIZATION = 0x02,
|
||||
COLLAPSE_WHITESPACE = 0x04,
|
||||
COLLAPSE_WHITESPACE = 0x04,
|
||||
|
||||
TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
|
||||
TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
|
||||
TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
|
||||
ATTRIBUTE_NAME = 0,
|
||||
ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
|
||||
ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
|
||||
COMMENT = NEEDS_NEWLINE_NORMALIZATION
|
||||
ATTRIBUTE_NAME = 0,
|
||||
ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
|
||||
ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
|
||||
COMMENT = NEEDS_NEWLINE_NORMALIZATION
|
||||
};
|
||||
|
||||
StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
|
||||
|
@ -1884,7 +1883,7 @@ public:
|
|||
If 'compact' is set to true, then output is created
|
||||
with only required whitespace and newlines.
|
||||
*/
|
||||
XMLPrinter( FILE* file=0, bool compact = false );
|
||||
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
|
||||
~XMLPrinter() {}
|
||||
|
||||
/** If streaming, write the BOM and declaration. */
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include "tokenlist.h"
|
||||
#include "token.h"
|
||||
|
||||
#include <tinyxml2.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
@ -177,95 +179,73 @@ std::string ErrorLogger::ErrorMessage::getXMLHeader(int xml_version)
|
|||
{
|
||||
// xml_version 1 is the default xml format
|
||||
|
||||
tinyxml2::XMLPrinter printer;
|
||||
|
||||
// standard xml header
|
||||
std::ostringstream ostr;
|
||||
ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
|
||||
// version 1 header
|
||||
if (xml_version <= 1) {
|
||||
ostr << "<results>";
|
||||
}
|
||||
printer.PushDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
|
||||
|
||||
// header
|
||||
printer.OpenElement("results");
|
||||
// version 2 header
|
||||
else {
|
||||
ostr << "<results version=\"" << xml_version << "\">\n";
|
||||
ostr << " <cppcheck version=\"" << CppCheck::version() << "\"/>\n";
|
||||
ostr << " <errors>";
|
||||
if (xml_version == 2) {
|
||||
printer.PushAttribute("version", xml_version);
|
||||
printer.OpenElement("cppcheck");
|
||||
printer.PushAttribute("version", CppCheck::version());
|
||||
printer.CloseElement();
|
||||
printer.OpenElement("errors");
|
||||
}
|
||||
|
||||
return ostr.str();
|
||||
return std::string(printer.CStr()) + '>';
|
||||
}
|
||||
|
||||
std::string ErrorLogger::ErrorMessage::getXMLFooter(int xml_version)
|
||||
{
|
||||
return (xml_version<=1) ? "</results>" : " </errors>\n</results>";
|
||||
}
|
||||
|
||||
static std::string stringToXml(std::string s)
|
||||
{
|
||||
// convert a string so it can be save as xml attribute data
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = s.find_first_of("<>&\"\n", pos)) != std::string::npos) {
|
||||
if (s[pos] == '<')
|
||||
s.insert(pos + 1, "<");
|
||||
else if (s[pos] == '>')
|
||||
s.insert(pos + 1, ">");
|
||||
else if (s[pos] == '&')
|
||||
s.insert(pos + 1, "&");
|
||||
else if (s[pos] == '"')
|
||||
s.insert(pos + 1, """);
|
||||
else if (s[pos] == '\n')
|
||||
s.insert(pos + 1, "
");
|
||||
s.erase(pos, 1);
|
||||
++pos;
|
||||
}
|
||||
return s;
|
||||
return (xml_version<=1) ? "</results>" : " </errors>\n</results>";
|
||||
}
|
||||
|
||||
std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
|
||||
{
|
||||
// Save this ErrorMessage as an XML element
|
||||
std::ostringstream xml;
|
||||
|
||||
// The default xml format
|
||||
if (version == 1) {
|
||||
// No inconclusive messages in the xml version 1
|
||||
if (_inconclusive)
|
||||
return "";
|
||||
|
||||
xml << "<error";
|
||||
tinyxml2::XMLPrinter printer(0, false, 1);
|
||||
printer.OpenElement("error");
|
||||
if (!_callStack.empty()) {
|
||||
xml << " file=\"" << stringToXml(_callStack.back().getfile()) << "\"";
|
||||
xml << " line=\"" << _callStack.back().line << "\"";
|
||||
printer.PushAttribute("file", _callStack.back().getfile().c_str());
|
||||
printer.PushAttribute("line", _callStack.back().line);
|
||||
}
|
||||
xml << " id=\"" << _id << "\"";
|
||||
xml << " severity=\"" << (_severity == Severity::error ? "error" : "style") << "\"";
|
||||
xml << " msg=\"" << stringToXml(verbose ? _verboseMessage : _shortMessage) << "\"";
|
||||
xml << "/>";
|
||||
printer.PushAttribute("id", _id.c_str());
|
||||
printer.PushAttribute("severity", (_severity == Severity::error ? "error" : "style"));
|
||||
printer.PushAttribute("msg", (verbose ? _verboseMessage : _shortMessage).c_str());
|
||||
printer.CloseElement();
|
||||
return printer.CStr();
|
||||
}
|
||||
|
||||
// The xml format you get when you use --xml-version=2
|
||||
else if (version == 2) {
|
||||
xml << " <error";
|
||||
xml << " id=\"" << _id << "\"";
|
||||
xml << " severity=\"" << Severity::toString(_severity) << "\"";
|
||||
xml << " msg=\"" << stringToXml(_shortMessage) << "\"";
|
||||
xml << " verbose=\"" << stringToXml(_verboseMessage) << "\"";
|
||||
tinyxml2::XMLPrinter printer(0, false, 2);
|
||||
printer.OpenElement("error");
|
||||
printer.PushAttribute("id", _id.c_str());
|
||||
printer.PushAttribute("severity", Severity::toString(_severity).c_str());
|
||||
printer.PushAttribute("msg", _shortMessage.c_str());
|
||||
printer.PushAttribute("verbose", _verboseMessage.c_str());
|
||||
if (_inconclusive)
|
||||
xml << " inconclusive=\"true\"";
|
||||
xml << ">" << std::endl;
|
||||
printer.PushAttribute("inconclusive", "true");
|
||||
|
||||
for (std::list<FileLocation>::const_reverse_iterator it = _callStack.rbegin(); it != _callStack.rend(); ++it) {
|
||||
xml << " <location";
|
||||
xml << " file=\"" << stringToXml((*it).getfile()) << "\"";
|
||||
xml << " line=\"" << (*it).line << "\"";
|
||||
xml << "/>" << std::endl;
|
||||
printer.OpenElement("location");
|
||||
printer.PushAttribute("file", (*it).getfile().c_str());
|
||||
printer.PushAttribute("line", (*it).line);
|
||||
printer.CloseElement();
|
||||
}
|
||||
|
||||
xml << " </error>";
|
||||
printer.CloseElement();
|
||||
return printer.CStr();
|
||||
}
|
||||
|
||||
return xml.str();
|
||||
return "";
|
||||
}
|
||||
|
||||
void ErrorLogger::ErrorMessage::findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith)
|
||||
|
|
|
@ -187,7 +187,7 @@ private:
|
|||
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
|
||||
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
|
||||
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
|
||||
ASSERT_EQUALS("<error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
|
||||
ASSERT_EQUALS(" <error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
|
||||
}
|
||||
|
||||
void ToXmlLocations() const {
|
||||
|
@ -203,7 +203,7 @@ private:
|
|||
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
|
||||
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
|
||||
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
|
||||
ASSERT_EQUALS("<error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
|
||||
ASSERT_EQUALS(" <error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Programming error.\"/>", msg.toXML(false,1));
|
||||
}
|
||||
|
||||
void ToVerboseXml() const {
|
||||
|
@ -215,7 +215,7 @@ private:
|
|||
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
|
||||
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
|
||||
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
|
||||
ASSERT_EQUALS("<error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
|
||||
ASSERT_EQUALS(" <error file=\"foo.cpp\" line=\"5\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
|
||||
}
|
||||
|
||||
void ToVerboseXmlLocations() const {
|
||||
|
@ -231,7 +231,7 @@ private:
|
|||
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
|
||||
ASSERT_EQUALS("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results>", ErrorLogger::ErrorMessage::getXMLHeader(1));
|
||||
ASSERT_EQUALS("</results>", ErrorLogger::ErrorMessage::getXMLFooter(1));
|
||||
ASSERT_EQUALS("<error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
|
||||
ASSERT_EQUALS(" <error file=\"bar.cpp\" line=\"8\" id=\"errorId\" severity=\"error\" msg=\"Verbose error\"/>", msg.toXML(true,1));
|
||||
}
|
||||
|
||||
void ToXmlV2() const {
|
||||
|
@ -242,14 +242,14 @@ private:
|
|||
locs.push_back(loc);
|
||||
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
|
||||
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n");
|
||||
header += " <cppcheck version=\"";
|
||||
header += " <cppcheck version=\"";
|
||||
header += CppCheck::version();
|
||||
header += "\"/>\n <errors>";
|
||||
header += "\"/>\n <errors>";
|
||||
ASSERT_EQUALS(header, ErrorLogger::ErrorMessage::getXMLHeader(2));
|
||||
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
|
||||
std::string message(" <error id=\"errorId\" severity=\"error\"");
|
||||
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
|
||||
std::string message(" <error id=\"errorId\" severity=\"error\"");
|
||||
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
|
||||
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
|
||||
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
|
||||
ASSERT_EQUALS(message, msg.toXML(false, 2));
|
||||
}
|
||||
|
||||
|
@ -265,15 +265,15 @@ private:
|
|||
locs.push_back(loc2);
|
||||
ErrorMessage msg(locs, Severity::error, "Programming error.\nVerbose error", "errorId", false);
|
||||
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<results version=\"2\">\n");
|
||||
header += " <cppcheck version=\"";
|
||||
header += " <cppcheck version=\"";
|
||||
header += CppCheck::version();
|
||||
header += "\"/>\n <errors>";
|
||||
header += "\"/>\n <errors>";
|
||||
ASSERT_EQUALS(header, ErrorLogger::ErrorMessage::getXMLHeader(2));
|
||||
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
|
||||
std::string message(" <error id=\"errorId\" severity=\"error\"");
|
||||
ASSERT_EQUALS(" </errors>\n</results>", ErrorLogger::ErrorMessage::getXMLFooter(2));
|
||||
std::string message(" <error id=\"errorId\" severity=\"error\"");
|
||||
message += " msg=\"Programming error.\" verbose=\"Verbose error\">\n";
|
||||
message += " <location file=\"bar.cpp\" line=\"8\"/>\n";
|
||||
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
|
||||
message += " <location file=\"bar.cpp\" line=\"8\"/>\n";
|
||||
message += " <location file=\"foo.cpp\" line=\"5\"/>\n </error>";
|
||||
ASSERT_EQUALS(message, msg.toXML(false, 2));
|
||||
}
|
||||
|
||||
|
@ -292,9 +292,9 @@ private:
|
|||
ASSERT_EQUALS("", msg.toXML(false, 1));
|
||||
|
||||
// xml version 2 error message
|
||||
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error\" verbose=\"Programming error\" inconclusive=\"true\">\n"
|
||||
" <location file=\"foo.cpp\" line=\"5\"/>\n"
|
||||
" </error>",
|
||||
ASSERT_EQUALS(" <error id=\"errorId\" severity=\"error\" msg=\"Programming error\" verbose=\"Programming error\" inconclusive=\"true\">\n"
|
||||
" <location file=\"foo.cpp\" line=\"5\"/>\n"
|
||||
" </error>",
|
||||
msg.toXML(false, 2));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue