Updated tinyxml
This commit is contained in:
parent
a41a32ba8a
commit
357f5076db
|
@ -422,16 +422,19 @@ void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
|
||||||
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );
|
TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ToStr() of a number is a very tricky topic.
|
||||||
|
https://github.com/leethomason/tinyxml2/issues/106
|
||||||
|
*/
|
||||||
void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
|
void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
|
||||||
{
|
{
|
||||||
TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
|
TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
|
void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
|
||||||
{
|
{
|
||||||
TIXML_SNPRINTF( buffer, bufferSize, "%f", v );
|
TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,12 +500,7 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||||
}
|
}
|
||||||
|
|
||||||
// What is this thing?
|
// What is this thing?
|
||||||
// - Elements start with a letter or underscore, but xml is reserved.
|
// These strings define the matching patters:
|
||||||
// - Comments: <!--
|
|
||||||
// - Declaration: <?
|
|
||||||
// - Everything else is unknown to tinyxml.
|
|
||||||
//
|
|
||||||
|
|
||||||
static const char* xmlHeader = { "<?" };
|
static const char* xmlHeader = { "<?" };
|
||||||
static const char* commentHeader = { "<!--" };
|
static const char* commentHeader = { "<!--" };
|
||||||
static const char* dtdHeader = { "<!" };
|
static const char* dtdHeader = { "<!" };
|
||||||
|
@ -1262,6 +1260,57 @@ const char* XMLElement::GetText() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::SetText( const char* inText )
|
||||||
|
{
|
||||||
|
if ( FirstChild() && FirstChild()->ToText() )
|
||||||
|
FirstChild()->SetValue( inText );
|
||||||
|
else {
|
||||||
|
XMLText* theText = GetDocument()->NewText( inText );
|
||||||
|
InsertFirstChild( theText );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::SetText( int v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||||
|
SetText( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::SetText( unsigned v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||||
|
SetText( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::SetText( bool v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||||
|
SetText( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::SetText( float v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||||
|
SetText( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLElement::SetText( double v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
XMLUtil::ToStr( v, buf, BUF_SIZE );
|
||||||
|
SetText( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLError XMLElement::QueryIntText( int* ival ) const
|
XMLError XMLElement::QueryIntText( int* ival ) const
|
||||||
{
|
{
|
||||||
if ( FirstChild() && FirstChild()->ToText() ) {
|
if ( FirstChild() && FirstChild()->ToText() ) {
|
||||||
|
@ -1639,6 +1688,13 @@ XMLError XMLDocument::LoadFile( FILE* fp )
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
|
fseek( fp, 0, SEEK_SET );
|
||||||
|
fgetc( fp );
|
||||||
|
if ( ferror( fp ) != 0 ) {
|
||||||
|
SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );
|
||||||
|
return _errorID;
|
||||||
|
}
|
||||||
|
|
||||||
fseek( fp, 0, SEEK_END );
|
fseek( fp, 0, SEEK_END );
|
||||||
size_t size = ftell( fp );
|
size_t size = ftell( fp );
|
||||||
fseek( fp, 0, SEEK_SET );
|
fseek( fp, 0, SEEK_SET );
|
||||||
|
@ -1702,7 +1758,7 @@ XMLError XMLDocument::Parse( const char* p, size_t len )
|
||||||
const char* start = p;
|
const char* start = p;
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
if ( !p || !*p ) {
|
if ( len == 0 || !p || !*p ) {
|
||||||
SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
|
SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
|
||||||
return _errorID;
|
return _errorID;
|
||||||
}
|
}
|
||||||
|
@ -1884,17 +1940,17 @@ void XMLPrinter::PushHeader( bool writeBOM, bool writeDec )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLPrinter::OpenElement( const char* name )
|
void XMLPrinter::OpenElement( const char* name, bool compactMode )
|
||||||
{
|
{
|
||||||
if ( _elementJustOpened ) {
|
if ( _elementJustOpened ) {
|
||||||
SealElement();
|
SealElement();
|
||||||
}
|
}
|
||||||
_stack.Push( name );
|
_stack.Push( name );
|
||||||
|
|
||||||
if ( _textDepth < 0 && !_firstElement && !_compactMode ) {
|
if ( _textDepth < 0 && !_firstElement && !compactMode ) {
|
||||||
Print( "\n" );
|
Print( "\n" );
|
||||||
}
|
}
|
||||||
if ( !_compactMode ) {
|
if ( !compactMode ) {
|
||||||
PrintSpace( _depth );
|
PrintSpace( _depth );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1946,7 +2002,7 @@ void XMLPrinter::PushAttribute( const char* name, double v )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLPrinter::CloseElement()
|
void XMLPrinter::CloseElement( bool compactMode )
|
||||||
{
|
{
|
||||||
--_depth;
|
--_depth;
|
||||||
const char* name = _stack.Pop();
|
const char* name = _stack.Pop();
|
||||||
|
@ -1955,7 +2011,7 @@ void XMLPrinter::CloseElement()
|
||||||
Print( "/>" );
|
Print( "/>" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( _textDepth < 0 && !_compactMode) {
|
if ( _textDepth < 0 && !compactMode) {
|
||||||
Print( "\n" );
|
Print( "\n" );
|
||||||
PrintSpace( _depth );
|
PrintSpace( _depth );
|
||||||
}
|
}
|
||||||
|
@ -1965,7 +2021,7 @@ void XMLPrinter::CloseElement()
|
||||||
if ( _textDepth == _depth ) {
|
if ( _textDepth == _depth ) {
|
||||||
_textDepth = -1;
|
_textDepth = -1;
|
||||||
}
|
}
|
||||||
if ( _depth == 0 && !_compactMode) {
|
if ( _depth == 0 && !compactMode) {
|
||||||
Print( "\n" );
|
Print( "\n" );
|
||||||
}
|
}
|
||||||
_elementJustOpened = false;
|
_elementJustOpened = false;
|
||||||
|
@ -2090,7 +2146,9 @@ bool XMLPrinter::VisitEnter( const XMLDocument& doc )
|
||||||
|
|
||||||
bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
|
bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute )
|
||||||
{
|
{
|
||||||
OpenElement( element.Name() );
|
const XMLElement* parentElem = element.Parent()->ToElement();
|
||||||
|
bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode;
|
||||||
|
OpenElement( element.Name(), compactMode );
|
||||||
while ( attribute ) {
|
while ( attribute ) {
|
||||||
PushAttribute( attribute->Name(), attribute->Value() );
|
PushAttribute( attribute->Name(), attribute->Value() );
|
||||||
attribute = attribute->Next();
|
attribute = attribute->Next();
|
||||||
|
@ -2099,9 +2157,9 @@ bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool XMLPrinter::VisitExit( const XMLElement& )
|
bool XMLPrinter::VisitExit( const XMLElement& element )
|
||||||
{
|
{
|
||||||
CloseElement();
|
CloseElement( CompactMode(element) );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,9 +116,12 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
|
||||||
#define TIXML_SSCANF sscanf
|
#define TIXML_SSCANF sscanf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const int TIXML2_MAJOR_VERSION = 1;
|
/* Versioning, past 1.0.14:
|
||||||
|
http://semver.org/
|
||||||
|
*/
|
||||||
|
static const int TIXML2_MAJOR_VERSION = 2;
|
||||||
static const int TIXML2_MINOR_VERSION = 0;
|
static const int TIXML2_MINOR_VERSION = 0;
|
||||||
static const int TIXML2_PATCH_VERSION = 12;
|
static const int TIXML2_PATCH_VERSION = 0;
|
||||||
|
|
||||||
namespace tinyxml2
|
namespace tinyxml2
|
||||||
{
|
{
|
||||||
|
@ -216,6 +219,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Push( T t ) {
|
void Push( T t ) {
|
||||||
EnsureCapacity( _size+1 );
|
EnsureCapacity( _size+1 );
|
||||||
_mem[_size++] = t;
|
_mem[_size++] = t;
|
||||||
|
@ -1317,6 +1324,11 @@ public:
|
||||||
XMLAttribute* a = FindOrCreateAttribute( name );
|
XMLAttribute* a = FindOrCreateAttribute( name );
|
||||||
a->SetAttribute( value );
|
a->SetAttribute( value );
|
||||||
}
|
}
|
||||||
|
/// Sets the named attribute to value.
|
||||||
|
void SetAttribute( const char* name, float value ) {
|
||||||
|
XMLAttribute* a = FindOrCreateAttribute( name );
|
||||||
|
a->SetAttribute( value );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Delete an attribute.
|
Delete an attribute.
|
||||||
|
@ -1360,6 +1372,52 @@ public:
|
||||||
*/
|
*/
|
||||||
const char* GetText() const;
|
const char* GetText() const;
|
||||||
|
|
||||||
|
/** Convenience function for easy access to the text inside an element. Although easy
|
||||||
|
and concise, SetText() is limited compared to creating an XMLText child
|
||||||
|
and mutating it directly.
|
||||||
|
|
||||||
|
If the first child of 'this' is a XMLText, SetText() sets its value to
|
||||||
|
the given string, otherwise it will create a first child that is an XMLText.
|
||||||
|
|
||||||
|
This is a convenient method for setting the text of simple contained text:
|
||||||
|
@verbatim
|
||||||
|
<foo>This is text</foo>
|
||||||
|
fooElement->SetText( "Hullaballoo!" );
|
||||||
|
<foo>Hullaballoo!</foo>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Note that this function can be misleading. If the element foo was created from
|
||||||
|
this XML:
|
||||||
|
@verbatim
|
||||||
|
<foo><b>This is text</b></foo>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
then it will not change "This is text", but rather prefix it with a text element:
|
||||||
|
@verbatim
|
||||||
|
<foo>Hullaballoo!<b>This is text</b></foo>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
For this XML:
|
||||||
|
@verbatim
|
||||||
|
<foo />
|
||||||
|
@endverbatim
|
||||||
|
SetText() will generate
|
||||||
|
@verbatim
|
||||||
|
<foo>Hullaballoo!</foo>
|
||||||
|
@endverbatim
|
||||||
|
*/
|
||||||
|
void SetText( const char* inText );
|
||||||
|
/// Convenience method for setting text inside and element. See SetText() for important limitations.
|
||||||
|
void SetText( int value );
|
||||||
|
/// Convenience method for setting text inside and element. See SetText() for important limitations.
|
||||||
|
void SetText( unsigned value );
|
||||||
|
/// Convenience method for setting text inside and element. See SetText() for important limitations.
|
||||||
|
void SetText( bool value );
|
||||||
|
/// Convenience method for setting text inside and element. See SetText() for important limitations.
|
||||||
|
void SetText( double value );
|
||||||
|
/// Convenience method for setting text inside and element. See SetText() for important limitations.
|
||||||
|
void SetText( float value );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convenience method to query the value of a child text node. This is probably best
|
Convenience method to query the value of a child text node. This is probably best
|
||||||
shown by example. Given you have a document is this form:
|
shown by example. Given you have a document is this form:
|
||||||
|
@ -1420,6 +1478,7 @@ private:
|
||||||
//void LinkAttribute( XMLAttribute* attrib );
|
//void LinkAttribute( XMLAttribute* attrib );
|
||||||
char* ParseAttributes( char* p );
|
char* ParseAttributes( char* p );
|
||||||
|
|
||||||
|
enum { BUF_SIZE = 200 };
|
||||||
int _closingType;
|
int _closingType;
|
||||||
// The attribute list is ordered; there is no 'lastAttribute'
|
// The attribute list is ordered; there is no 'lastAttribute'
|
||||||
// because the list needs to be scanned for dupes before adding
|
// because the list needs to be scanned for dupes before adding
|
||||||
|
@ -1905,7 +1964,7 @@ public:
|
||||||
/** If streaming, start writing an element.
|
/** If streaming, start writing an element.
|
||||||
The element must be closed with CloseElement()
|
The element must be closed with CloseElement()
|
||||||
*/
|
*/
|
||||||
void OpenElement( const char* name );
|
void OpenElement( const char* name, bool compactMode );
|
||||||
/// If streaming, add an attribute to an open element.
|
/// If streaming, add an attribute to an open element.
|
||||||
void PushAttribute( const char* name, const char* value );
|
void PushAttribute( const char* name, const char* value );
|
||||||
void PushAttribute( const char* name, int value );
|
void PushAttribute( const char* name, int value );
|
||||||
|
@ -1913,7 +1972,7 @@ public:
|
||||||
void PushAttribute( const char* name, bool value );
|
void PushAttribute( const char* name, bool value );
|
||||||
void PushAttribute( const char* name, double value );
|
void PushAttribute( const char* name, double value );
|
||||||
/// If streaming, close the Element.
|
/// If streaming, close the Element.
|
||||||
virtual void CloseElement();
|
virtual void CloseElement( bool compactMode );
|
||||||
|
|
||||||
/// Add a text node.
|
/// Add a text node.
|
||||||
void PushText( const char* text, bool cdata=false );
|
void PushText( const char* text, bool cdata=false );
|
||||||
|
@ -1962,23 +2021,37 @@ public:
|
||||||
int CStrSize() const {
|
int CStrSize() const {
|
||||||
return _buffer.Size();
|
return _buffer.Size();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
If in print to memory mode, reset the buffer to the
|
||||||
|
beginning.
|
||||||
|
*/
|
||||||
|
void ClearBuffer() {
|
||||||
|
_buffer.Clear();
|
||||||
|
_buffer.Push(0);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SealElement();
|
virtual bool CompactMode( const XMLElement& ) { return _compactMode; };
|
||||||
|
|
||||||
|
/** Prints out the space before an element. You may override to change
|
||||||
|
the space and tabs used. A PrintSpace() override should call Print().
|
||||||
|
*/
|
||||||
|
virtual void PrintSpace( int depth );
|
||||||
|
void Print( const char* format, ... );
|
||||||
|
|
||||||
|
void SealElement();
|
||||||
bool _elementJustOpened;
|
bool _elementJustOpened;
|
||||||
DynArray< const char*, 10 > _stack;
|
DynArray< const char*, 10 > _stack;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PrintSpace( int depth );
|
|
||||||
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
|
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
|
||||||
void Print( const char* format, ... );
|
|
||||||
|
|
||||||
bool _firstElement;
|
bool _firstElement;
|
||||||
FILE* _fp;
|
FILE* _fp;
|
||||||
int _depth;
|
int _depth;
|
||||||
int _textDepth;
|
int _textDepth;
|
||||||
bool _processEntities;
|
bool _processEntities;
|
||||||
bool _compactMode;
|
bool _compactMode;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ENTITY_RANGE = 64,
|
ENTITY_RANGE = 64,
|
||||||
|
|
|
@ -185,14 +185,14 @@ std::string ErrorLogger::ErrorMessage::getXMLHeader(int xml_version)
|
||||||
printer.PushDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
|
printer.PushDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
|
||||||
|
|
||||||
// header
|
// header
|
||||||
printer.OpenElement("results");
|
printer.OpenElement("results", false);
|
||||||
// version 2 header
|
// version 2 header
|
||||||
if (xml_version == 2) {
|
if (xml_version == 2) {
|
||||||
printer.PushAttribute("version", xml_version);
|
printer.PushAttribute("version", xml_version);
|
||||||
printer.OpenElement("cppcheck");
|
printer.OpenElement("cppcheck", false);
|
||||||
printer.PushAttribute("version", CppCheck::version());
|
printer.PushAttribute("version", CppCheck::version());
|
||||||
printer.CloseElement();
|
printer.CloseElement(false);
|
||||||
printer.OpenElement("errors");
|
printer.OpenElement("errors", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string(printer.CStr()) + '>';
|
return std::string(printer.CStr()) + '>';
|
||||||
|
@ -212,7 +212,7 @@ std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
tinyxml2::XMLPrinter printer(0, false, 1);
|
tinyxml2::XMLPrinter printer(0, false, 1);
|
||||||
printer.OpenElement("error");
|
printer.OpenElement("error", false);
|
||||||
if (!_callStack.empty()) {
|
if (!_callStack.empty()) {
|
||||||
printer.PushAttribute("file", _callStack.back().getfile().c_str());
|
printer.PushAttribute("file", _callStack.back().getfile().c_str());
|
||||||
printer.PushAttribute("line", _callStack.back().line);
|
printer.PushAttribute("line", _callStack.back().line);
|
||||||
|
@ -220,14 +220,14 @@ std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
|
||||||
printer.PushAttribute("id", _id.c_str());
|
printer.PushAttribute("id", _id.c_str());
|
||||||
printer.PushAttribute("severity", (_severity == Severity::error ? "error" : "style"));
|
printer.PushAttribute("severity", (_severity == Severity::error ? "error" : "style"));
|
||||||
printer.PushAttribute("msg", (verbose ? _verboseMessage : _shortMessage).c_str());
|
printer.PushAttribute("msg", (verbose ? _verboseMessage : _shortMessage).c_str());
|
||||||
printer.CloseElement();
|
printer.CloseElement(false);
|
||||||
return printer.CStr();
|
return printer.CStr();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The xml format you get when you use --xml-version=2
|
// The xml format you get when you use --xml-version=2
|
||||||
else if (version == 2) {
|
else if (version == 2) {
|
||||||
tinyxml2::XMLPrinter printer(0, false, 2);
|
tinyxml2::XMLPrinter printer(0, false, 2);
|
||||||
printer.OpenElement("error");
|
printer.OpenElement("error", false);
|
||||||
printer.PushAttribute("id", _id.c_str());
|
printer.PushAttribute("id", _id.c_str());
|
||||||
printer.PushAttribute("severity", Severity::toString(_severity).c_str());
|
printer.PushAttribute("severity", Severity::toString(_severity).c_str());
|
||||||
printer.PushAttribute("msg", _shortMessage.c_str());
|
printer.PushAttribute("msg", _shortMessage.c_str());
|
||||||
|
@ -236,12 +236,12 @@ std::string ErrorLogger::ErrorMessage::toXML(bool verbose, int version) const
|
||||||
printer.PushAttribute("inconclusive", "true");
|
printer.PushAttribute("inconclusive", "true");
|
||||||
|
|
||||||
for (std::list<FileLocation>::const_reverse_iterator it = _callStack.rbegin(); it != _callStack.rend(); ++it) {
|
for (std::list<FileLocation>::const_reverse_iterator it = _callStack.rbegin(); it != _callStack.rend(); ++it) {
|
||||||
printer.OpenElement("location");
|
printer.OpenElement("location", false);
|
||||||
printer.PushAttribute("file", (*it).getfile().c_str());
|
printer.PushAttribute("file", (*it).getfile().c_str());
|
||||||
printer.PushAttribute("line", (*it).line);
|
printer.PushAttribute("line", (*it).line);
|
||||||
printer.CloseElement();
|
printer.CloseElement(false);
|
||||||
}
|
}
|
||||||
printer.CloseElement();
|
printer.CloseElement(false);
|
||||||
return printer.CStr();
|
return printer.CStr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue