2 Commits

7 changed files with 109 additions and 327 deletions

View File

@@ -6,7 +6,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ windows-2019, macos-latest, ubuntu-20.04 ] os: [ windows-2019, macos-10.15, ubuntu-20.04 ]
cmake: [ 3.15, 3.x ] cmake: [ 3.15, 3.x ]
include: include:
- os: windows-2019 - os: windows-2019
@@ -17,7 +17,7 @@ jobs:
- os: ubuntu-20.04 - os: ubuntu-20.04
tree: tree tree: tree
- os: macos-latest - os: macos-10.15
tree: find tree: find
- cmake: 3.15 - cmake: 3.15

View File

@@ -62,6 +62,26 @@ if meson.version().version_compare('>= 0.54.0')
endif endif
if get_option('tests') if get_option('tests')
# Try to find a copy command. If this is windows we probably don't have cp,
# but if this is msys then we do, so make cp not required in that case, and
# try Xcopy if cp isn't found
prog_cp = find_program('cp', required : build_machine.system() != 'windows')
command = ['-r']
if not prog_cp.found()
prog_cp = find_program('Xcopy')
command = ['/E', '/I']
endif
# Copy the test resources into the build dir
run_command(
prog_cp,
[
command,
meson.current_source_dir() / 'resources',
meson.current_build_dir(),
],
)
test( test(
'xmltest', 'xmltest',
executable( executable(
@@ -69,7 +89,7 @@ if get_option('tests')
['xmltest.cpp'], ['xmltest.cpp'],
link_with : [lib_tinyxml2], link_with : [lib_tinyxml2],
), ),
workdir : meson.current_source_dir(), workdir : meson.current_build_dir(),
) )
endif endif

View File

@@ -1,7 +1,9 @@
TinyXML-2 TinyXML-2
========= =========
[![Test](https://github.com/leethomason/tinyxml2/actions/workflows/test.yml/badge.svg)](https://github.com/leethomason/tinyxml2/actions/workflows/test.yml) ![Build](https://github.com/leethomason/tinyxml2/actions/workflows/test.yml/badge.svg)
![TinyXML-2 Logo](http://www.grinninglizard.com/tinyxml2/TinyXML2_small.png)
TinyXML-2 is a simple, small, efficient, C++ XML parser that can be TinyXML-2 is a simple, small, efficient, C++ XML parser that can be
easily integrated into other programs. easily integrated into other programs.
@@ -91,7 +93,7 @@ by the Document. When the Document is deleted, so are all the nodes it contains.
### White Space ### White Space
#### Whitespace Preservation (default, PRESERVE_WHITESPACE) #### Whitespace Preservation (default)
Microsoft has an excellent article on white space: http://msdn.microsoft.com/en-us/library/ms256097.aspx Microsoft has an excellent article on white space: http://msdn.microsoft.com/en-us/library/ms256097.aspx
@@ -123,7 +125,7 @@ valuable. TinyXML-2 sees these as the same XML:
<document><data>1</data><data>2</data><data>3</data></document> <document><data>1</data><data>2</data><data>3</data></document>
#### Whitespace Collapse (COLLAPSE_WHITESPACE) #### Whitespace Collapse
For some applications, it is preferable to collapse whitespace. Collapsing For some applications, it is preferable to collapse whitespace. Collapsing
whitespace gives you "HTML-like" behavior, which is sometimes more suitable whitespace gives you "HTML-like" behavior, which is sometimes more suitable
@@ -141,15 +143,7 @@ However, you may also use COLLAPSE_WHITESPACE, which will:
Note that (currently) there is a performance impact for using COLLAPSE_WHITESPACE. Note that (currently) there is a performance impact for using COLLAPSE_WHITESPACE.
It essentially causes the XML to be parsed twice. It essentially causes the XML to be parsed twice.
#### Pedantic Whitespace (PEDANTIC_WHITESPACE) #### Error Reporting
For applications that need to know about text nodes that are composed entirely of
whitespace, PEDANTIC_WHITESPACE is available. PEDANTIC_WHITESPACE maintains all the
whilespace between elements.
PEDANTIC_WHITESPACE is a new mode and not as tested as the other whitespace modes.
### Error Reporting
TinyXML-2 reports the line number of any errors in an XML document that TinyXML-2 reports the line number of any errors in an XML document that
cannot be parsed correctly. In addition, all nodes (elements, declarations, cannot be parsed correctly. In addition, all nodes (elements, declarations,

View File

@@ -103,17 +103,10 @@ distribution.
#if defined(_WIN64) #if defined(_WIN64)
#define TIXML_FSEEK _fseeki64 #define TIXML_FSEEK _fseeki64
#define TIXML_FTELL _ftelli64 #define TIXML_FTELL _ftelli64
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || (__CYGWIN__) #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
|| defined(__NetBSD__) || defined(__DragonFly__) || defined(__ANDROID__)
#define TIXML_FSEEK fseeko #define TIXML_FSEEK fseeko
#define TIXML_FTELL ftello #define TIXML_FTELL ftello
#elif defined(__ANDROID__)
#if __ANDROID_API__ > 24
#define TIXML_FSEEK fseeko64
#define TIXML_FTELL ftello64
#else
#define TIXML_FSEEK fseeko
#define TIXML_FTELL ftello
#endif
#elif defined(__unix__) && defined(__x86_64__) #elif defined(__unix__) && defined(__x86_64__)
#define TIXML_FSEEK fseeko64 #define TIXML_FSEEK fseeko64
#define TIXML_FTELL ftello64 #define TIXML_FTELL ftello64
@@ -715,7 +708,7 @@ bool XMLUtil::ToUnsigned64(const char* str, uint64_t* value) {
} }
char* XMLDocument::Identify( char* p, XMLNode** node, bool first ) char* XMLDocument::Identify( char* p, XMLNode** node )
{ {
TIXMLASSERT( node ); TIXMLASSERT( node );
TIXMLASSERT( p ); TIXMLASSERT( p );
@@ -767,19 +760,9 @@ char* XMLDocument::Identify( char* p, XMLNode** node, bool first )
p += dtdHeaderLen; p += dtdHeaderLen;
} }
else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
returnNode = CreateUnlinkedNode<XMLElement>( _elementPool );
// Preserve whitespace pedantically before closing tag, when it's immediately after opening tag returnNode->_parseLineNum = _parseCurLineNum;
if (WhitespaceMode() == PEDANTIC_WHITESPACE && first && p != start && *(p + elementHeaderLen) == '/') { p += elementHeaderLen;
returnNode = CreateUnlinkedNode<XMLText>(_textPool);
returnNode->_parseLineNum = startLine;
p = start; // Back it up, all the text counts.
_parseCurLineNum = startLine;
}
else {
returnNode = CreateUnlinkedNode<XMLElement>(_elementPool);
returnNode->_parseLineNum = _parseCurLineNum;
p += elementHeaderLen;
}
} }
else { else {
returnNode = CreateUnlinkedNode<XMLText>( _textPool ); returnNode = CreateUnlinkedNode<XMLText>( _textPool );
@@ -832,34 +815,6 @@ XMLNode::~XMLNode()
} }
} }
// ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
int XMLNode::ChildElementCount(const char *value) const {
int count = 0;
const XMLElement *e = FirstChildElement(value);
while (e) {
e = e->NextSiblingElement(value);
count++;
}
return count;
}
int XMLNode::ChildElementCount() const {
int count = 0;
const XMLElement *e = FirstChildElement();
while (e) {
e = e->NextSiblingElement();
count++;
}
return count;
}
const char* XMLNode::Value() const const char* XMLNode::Value() const
{ {
// Edge case: XMLDocuments don't have a Value. Return null. // Edge case: XMLDocuments don't have a Value. Return null.
@@ -1108,23 +1063,21 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
if (_document->Error()) if (_document->Error())
return 0; return 0;
bool first = true;
while( p && *p ) { while( p && *p ) {
XMLNode* node = 0; XMLNode* node = 0;
p = _document->Identify( p, &node, first ); p = _document->Identify( p, &node );
TIXMLASSERT( p ); TIXMLASSERT( p );
if ( node == 0 ) { if ( node == 0 ) {
break; break;
} }
first = false;
const int initialLineNum = node->_parseLineNum; const int initialLineNum = node->_parseLineNum;
StrPair endTag; StrPair endTag;
p = node->ParseDeep( p, &endTag, curLineNumPtr ); p = node->ParseDeep( p, &endTag, curLineNumPtr );
if ( !p ) { if ( !p ) {
_document->DeleteNode( node ); DeleteNode( node );
if ( !_document->Error() ) { if ( !_document->Error() ) {
_document->SetError( XML_ERROR_PARSING, initialLineNum, 0); _document->SetError( XML_ERROR_PARSING, initialLineNum, 0);
} }
@@ -1157,7 +1110,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
} }
if ( !wellLocated ) { if ( !wellLocated ) {
_document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value());
_document->DeleteNode( node ); DeleteNode( node );
break; break;
} }
} }
@@ -1192,7 +1145,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
} }
if ( mismatch ) { if ( mismatch ) {
_document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name());
_document->DeleteNode( node ); DeleteNode( node );
break; break;
} }
} }
@@ -1824,11 +1777,11 @@ XMLError XMLElement::QueryInt64Text(int64_t* ival) const
} }
XMLError XMLElement::QueryUnsigned64Text(uint64_t* uval) const XMLError XMLElement::QueryUnsigned64Text(uint64_t* ival) const
{ {
if(FirstChild() && FirstChild()->ToText()) { if(FirstChild() && FirstChild()->ToText()) {
const char* t = FirstChild()->Value(); const char* t = FirstChild()->Value();
if(XMLUtil::ToUnsigned64(t, uval)) { if(XMLUtil::ToUnsigned64(t, ival)) {
return XML_SUCCESS; return XML_SUCCESS;
} }
return XML_CAN_NOT_CONVERT_TEXT; return XML_CAN_NOT_CONVERT_TEXT;
@@ -2460,21 +2413,21 @@ XMLError XMLDocument::SaveFile( FILE* fp, bool compact )
} }
XMLError XMLDocument::Parse( const char* xml, size_t nBytes ) XMLError XMLDocument::Parse( const char* p, size_t len )
{ {
Clear(); Clear();
if ( nBytes == 0 || !xml || !*xml ) { if ( len == 0 || !p || !*p ) {
SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
return _errorID; return _errorID;
} }
if ( nBytes == static_cast<size_t>(-1) ) { if ( len == static_cast<size_t>(-1) ) {
nBytes = strlen( xml ); len = strlen( p );
} }
TIXMLASSERT( _charBuffer == 0 ); TIXMLASSERT( _charBuffer == 0 );
_charBuffer = new char[ nBytes+1 ]; _charBuffer = new char[ len+1 ];
memcpy( _charBuffer, xml, nBytes ); memcpy( _charBuffer, p, len );
_charBuffer[nBytes] = 0; _charBuffer[len] = 0;
Parse(); Parse();
if ( Error() ) { if ( Error() ) {

View File

@@ -64,7 +64,7 @@ distribution.
# pragma warning(disable: 4251) # pragma warning(disable: 4251)
#endif #endif
#ifdef _MSC_VER #ifdef _WIN32
# ifdef TINYXML2_EXPORT # ifdef TINYXML2_EXPORT
# define TINYXML2_LIB __declspec(dllexport) # define TINYXML2_LIB __declspec(dllexport)
# elif defined(TINYXML2_IMPORT) # elif defined(TINYXML2_IMPORT)
@@ -112,7 +112,7 @@ static const int TIXML2_PATCH_VERSION = 0;
// system, and the capacity of the stack. On the other hand, it's a trivial // system, and the capacity of the stack. On the other hand, it's a trivial
// attack that can result from ill, malicious, or even correctly formed XML, // attack that can result from ill, malicious, or even correctly formed XML,
// so there needs to be a limit in place. // so there needs to be a limit in place.
static const int TINYXML2_MAX_ELEMENT_DEPTH = 500; static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
namespace tinyxml2 namespace tinyxml2
{ {
@@ -305,9 +305,9 @@ private:
if ( cap > _allocated ) { if ( cap > _allocated ) {
TIXMLASSERT( cap <= INT_MAX / 2 ); TIXMLASSERT( cap <= INT_MAX / 2 );
const int newAllocated = cap * 2; const int newAllocated = cap * 2;
T* newMem = new T[static_cast<unsigned int>(newAllocated)]; T* newMem = new T[newAllocated];
TIXMLASSERT( newAllocated >= _size ); TIXMLASSERT( newAllocated >= _size );
memcpy( newMem, _mem, sizeof(T)*static_cast<size_t>(_size) ); // warning: not using constructors, only works for PODs memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
if ( _mem != _pool ) { if ( _mem != _pool ) {
delete [] _mem; delete [] _mem;
} }
@@ -317,7 +317,7 @@ private:
} }
T* _mem; T* _mem;
T _pool[static_cast<size_t>(INITIAL_SIZE)]; T _pool[INITIAL_SIZE];
int _allocated; // objects allocated int _allocated; // objects allocated
int _size; // number objects in use int _size; // number objects in use
}; };
@@ -365,17 +365,17 @@ public:
_nUntracked = 0; _nUntracked = 0;
} }
virtual int ItemSize() const override{ virtual int ItemSize() const {
return ITEM_SIZE; return ITEM_SIZE;
} }
int CurrentAllocs() const { int CurrentAllocs() const {
return _currentAllocs; return _currentAllocs;
} }
virtual void* Alloc() override{ virtual void* Alloc() {
if ( !_root ) { if ( !_root ) {
// Need a new block. // Need a new block.
Block* block = new Block; Block* block = new Block();
_blockPtrs.Push( block ); _blockPtrs.Push( block );
Item* blockItems = block->items; Item* blockItems = block->items;
@@ -398,7 +398,7 @@ public:
return result; return result;
} }
virtual void Free( void* mem ) override { virtual void Free( void* mem ) {
if ( !mem ) { if ( !mem ) {
return; return;
} }
@@ -416,7 +416,7 @@ public:
ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
} }
void SetTracked() override { void SetTracked() {
--_nUntracked; --_nUntracked;
} }
@@ -443,7 +443,7 @@ private:
union Item { union Item {
Item* next; Item* next;
char itemData[static_cast<size_t>(ITEM_SIZE)]; char itemData[ITEM_SIZE];
}; };
struct Block { struct Block {
Item items[ITEMS_PER_BLOCK]; Item items[ITEMS_PER_BLOCK];
@@ -603,7 +603,7 @@ public:
TIXMLASSERT( p ); TIXMLASSERT( p );
TIXMLASSERT( q ); TIXMLASSERT( q );
TIXMLASSERT( nChar >= 0 ); TIXMLASSERT( nChar >= 0 );
return strncmp( p, q, static_cast<size_t>(nChar) ) == 0; return strncmp( p, q, nChar ) == 0;
} }
inline static bool IsUTF8Continuation( const char p ) { inline static bool IsUTF8Continuation( const char p ) {
@@ -732,12 +732,6 @@ public:
return 0; return 0;
} }
// ChildElementCount was originally suggested by msteiger on the sourceforge page for TinyXML and modified by KB1SPH for TinyXML-2.
int ChildElementCount(const char *value) const;
int ChildElementCount() const;
/** The meaning of 'value' changes for the specific type. /** The meaning of 'value' changes for the specific type.
@verbatim @verbatim
Document: empty (NULL is returned, not an empty string) Document: empty (NULL is returned, not an empty string)
@@ -998,12 +992,12 @@ class TINYXML2_LIB XMLText : public XMLNode
{ {
friend class XMLDocument; friend class XMLDocument;
public: public:
virtual bool Accept( XMLVisitor* visitor ) const override; virtual bool Accept( XMLVisitor* visitor ) const;
virtual XMLText* ToText() override { virtual XMLText* ToText() {
return this; return this;
} }
virtual const XMLText* ToText() const override { virtual const XMLText* ToText() const {
return this; return this;
} }
@@ -1016,14 +1010,14 @@ public:
return _isCData; return _isCData;
} }
virtual XMLNode* ShallowClone( XMLDocument* document ) const override; virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const override; virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
virtual ~XMLText() {} virtual ~XMLText() {}
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override; char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private: private:
bool _isCData; bool _isCData;
@@ -1038,23 +1032,23 @@ class TINYXML2_LIB XMLComment : public XMLNode
{ {
friend class XMLDocument; friend class XMLDocument;
public: public:
virtual XMLComment* ToComment() override { virtual XMLComment* ToComment() {
return this; return this;
} }
virtual const XMLComment* ToComment() const override { virtual const XMLComment* ToComment() const {
return this; return this;
} }
virtual bool Accept( XMLVisitor* visitor ) const override; virtual bool Accept( XMLVisitor* visitor ) const;
virtual XMLNode* ShallowClone( XMLDocument* document ) const override; virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const override; virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
explicit XMLComment( XMLDocument* doc ); explicit XMLComment( XMLDocument* doc );
virtual ~XMLComment(); virtual ~XMLComment();
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr) override; char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
private: private:
XMLComment( const XMLComment& ); // not supported XMLComment( const XMLComment& ); // not supported
@@ -1077,23 +1071,23 @@ class TINYXML2_LIB XMLDeclaration : public XMLNode
{ {
friend class XMLDocument; friend class XMLDocument;
public: public:
virtual XMLDeclaration* ToDeclaration() override { virtual XMLDeclaration* ToDeclaration() {
return this; return this;
} }
virtual const XMLDeclaration* ToDeclaration() const override { virtual const XMLDeclaration* ToDeclaration() const {
return this; return this;
} }
virtual bool Accept( XMLVisitor* visitor ) const override; virtual bool Accept( XMLVisitor* visitor ) const;
virtual XMLNode* ShallowClone( XMLDocument* document ) const override; virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const override; virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
explicit XMLDeclaration( XMLDocument* doc ); explicit XMLDeclaration( XMLDocument* doc );
virtual ~XMLDeclaration(); virtual ~XMLDeclaration();
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override; char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private: private:
XMLDeclaration( const XMLDeclaration& ); // not supported XMLDeclaration( const XMLDeclaration& ); // not supported
@@ -1112,23 +1106,23 @@ class TINYXML2_LIB XMLUnknown : public XMLNode
{ {
friend class XMLDocument; friend class XMLDocument;
public: public:
virtual XMLUnknown* ToUnknown() override { virtual XMLUnknown* ToUnknown() {
return this; return this;
} }
virtual const XMLUnknown* ToUnknown() const override { virtual const XMLUnknown* ToUnknown() const {
return this; return this;
} }
virtual bool Accept( XMLVisitor* visitor ) const override; virtual bool Accept( XMLVisitor* visitor ) const;
virtual XMLNode* ShallowClone( XMLDocument* document ) const override; virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const override; virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
explicit XMLUnknown( XMLDocument* doc ); explicit XMLUnknown( XMLDocument* doc );
virtual ~XMLUnknown(); virtual ~XMLUnknown();
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override; char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private: private:
XMLUnknown( const XMLUnknown& ); // not supported XMLUnknown( const XMLUnknown& ); // not supported
@@ -1280,13 +1274,13 @@ public:
SetValue( str, staticMem ); SetValue( str, staticMem );
} }
virtual XMLElement* ToElement() override { virtual XMLElement* ToElement() {
return this; return this;
} }
virtual const XMLElement* ToElement() const override { virtual const XMLElement* ToElement() const {
return this; return this;
} }
virtual bool Accept( XMLVisitor* visitor ) const override; virtual bool Accept( XMLVisitor* visitor ) const;
/** Given an attribute name, Attribute() returns the value /** Given an attribute name, Attribute() returns the value
for the attribute of that name, or null if none for the attribute of that name, or null if none
@@ -1682,11 +1676,11 @@ public:
ElementClosingType ClosingType() const { ElementClosingType ClosingType() const {
return _closingType; return _closingType;
} }
virtual XMLNode* ShallowClone( XMLDocument* document ) const override; virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const override; virtual bool ShallowEqual( const XMLNode* compare ) const;
protected: protected:
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) override; char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private: private:
XMLElement( XMLDocument* doc ); XMLElement( XMLDocument* doc );
@@ -1710,8 +1704,7 @@ private:
enum Whitespace { enum Whitespace {
PRESERVE_WHITESPACE, PRESERVE_WHITESPACE,
COLLAPSE_WHITESPACE, COLLAPSE_WHITESPACE
PEDANTIC_WHITESPACE
}; };
@@ -1735,11 +1728,11 @@ public:
XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
~XMLDocument(); ~XMLDocument();
virtual XMLDocument* ToDocument() override { virtual XMLDocument* ToDocument() {
TIXMLASSERT( this == _document ); TIXMLASSERT( this == _document );
return this; return this;
} }
virtual const XMLDocument* ToDocument() const override { virtual const XMLDocument* ToDocument() const {
TIXMLASSERT( this == _document ); TIXMLASSERT( this == _document );
return this; return this;
} }
@@ -1836,7 +1829,7 @@ public:
@endverbatim @endverbatim
*/ */
void Print( XMLPrinter* streamer=0 ) const; void Print( XMLPrinter* streamer=0 ) const;
virtual bool Accept( XMLVisitor* visitor ) const override; virtual bool Accept( XMLVisitor* visitor ) const;
/** /**
Create a new Element associated with Create a new Element associated with
@@ -1922,15 +1915,15 @@ public:
void DeepCopy(XMLDocument* target) const; void DeepCopy(XMLDocument* target) const;
// internal // internal
char* Identify( char* p, XMLNode** node, bool first ); char* Identify( char* p, XMLNode** node );
// internal // internal
void MarkInUse(const XMLNode* const); void MarkInUse(const XMLNode* const);
virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const override{ virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
return 0; return 0;
} }
virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const override{ virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const {
return false; return false;
} }
@@ -2293,18 +2286,18 @@ public:
void PushDeclaration( const char* value ); void PushDeclaration( const char* value );
void PushUnknown( const char* value ); void PushUnknown( const char* value );
virtual bool VisitEnter( const XMLDocument& /*doc*/ ) override; virtual bool VisitEnter( const XMLDocument& /*doc*/ );
virtual bool VisitExit( const XMLDocument& /*doc*/ ) override { virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
return true; return true;
} }
virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) override; virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
virtual bool VisitExit( const XMLElement& element ) override; virtual bool VisitExit( const XMLElement& element );
virtual bool Visit( const XMLText& text ) override; virtual bool Visit( const XMLText& text );
virtual bool Visit( const XMLComment& comment ) override; virtual bool Visit( const XMLComment& comment );
virtual bool Visit( const XMLDeclaration& declaration ) override; virtual bool Visit( const XMLDeclaration& declaration );
virtual bool Visit( const XMLUnknown& unknown ) override; virtual bool Visit( const XMLUnknown& unknown );
/** /**
If in print to memory mode, return a pointer to If in print to memory mode, return a pointer to

View File

@@ -29,26 +29,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

View File

@@ -1869,178 +1869,6 @@ int main( int argc, const char ** argv )
XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() ); XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() );
} }
// ----------- Preserve Whitespace ------------
{
const char* xml = "<element>This is &apos; \n\n text &apos;</element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", "This is ' \n\n text '", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> This \nis &apos; text &apos; </element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", " This \nis ' text ' ", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> \n This is &apos; text &apos; \n</element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", " \n This is ' text ' \n", doc.FirstChildElement()->GetText());
}
// Following cases are for text that is all whitespace which are not preserved intentionally
{
const char* xml = "<element> </element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", true, 0 == doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> </element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", true, 0 == doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element>\n\n</element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", true, 0 == doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> \n</element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", true, 0 == doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> \n \n </element>";
XMLDocument doc(true, PRESERVE_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with whitespace preserved", false, doc.Error());
XMLTest("Whitespace preserved", true, 0 == doc.FirstChildElement()->GetText());
}
// ----------- Pedantic Whitespace ------------
{
const char* xml = "<element>This is &apos; \n\n text &apos;</element>";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", "This is ' \n\n text '", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> This \nis &apos; text &apos; </element>";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " This \nis ' text ' ", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> \n This is &apos; text &apos; \n</element>";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " \n This is ' text ' \n", doc.FirstChildElement()->GetText());
}
// Following cases are for text that is all whitespace which is preserved with pedantic mode
{
const char* xml = "<element> </element>";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " ", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> </element>";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " ", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element>\n\n</element>\n";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", "\n\n", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> \n</element> \n ";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " \n", doc.FirstChildElement()->GetText());
}
{
const char* xml = "<element> \n \n </element> ";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " \n \n ", doc.FirstChildElement()->GetText());
}
// Following cases are for checking nested elements are still parsed with pedantic whitespace
{
const char* xml = "<element>\n\t<a> This is nested text </a>\n</element> ";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " This is nested text ", doc.RootElement()->FirstChildElement()->GetText());
}
{
const char* xml = "<element> <b> </b> </element>\n";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", " ", doc.RootElement()->FirstChildElement()->GetText());
}
{
const char* xml = "<element> <c attribute=\"test\"/> </element>\n ";
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.Parse(xml);
XMLTest("Parse nested elements with pedantic whitespace", false, doc.Error());
XMLTest("Pedantic whitespace", true, 0 == doc.RootElement()->FirstChildElement()->GetText());
}
// Check sample xml can be parsed with pedantic mode
{
XMLDocument doc(true, PEDANTIC_WHITESPACE);
doc.LoadFile("resources/dream.xml");
XMLTest("Load dream.xml with pedantic whitespace mode", false, doc.Error());
XMLTest("Dream", "xml version=\"1.0\"",
doc.FirstChild()->ToDeclaration()->Value());
XMLTest("Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() != 0);
XMLTest("Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
doc.FirstChild()->NextSibling()->ToUnknown()->Value());
XMLTest("Dream", "And Robin shall restore amends.",
doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText());
}
{ {
// An assert should not fire. // An assert should not fire.
const char* xml = "<element/>"; const char* xml = "<element/>";
@@ -2321,12 +2149,6 @@ int main( int argc, const char ** argv )
XMLTest( "Should be no error initially", false, doc.Error() ); XMLTest( "Should be no error initially", false, doc.Error() );
doc.LoadFile( "resources/no-such-file.xml" ); doc.LoadFile( "resources/no-such-file.xml" );
XMLTest( "No such file - should fail", true, doc.Error() ); XMLTest( "No such file - should fail", true, doc.Error() );
doc.LoadFile("resources/dream.xml");
XMLTest("Error should be cleared", false, doc.Error());
doc.LoadFile( "resources/xmltest-5330.xml" );
XMLTest( "parse errors occur - should fail", true, doc.Error() );
doc.LoadFile( "resources/dream.xml" ); doc.LoadFile( "resources/dream.xml" );
XMLTest( "Error should be cleared", false, doc.Error() ); XMLTest( "Error should be cleared", false, doc.Error() );