Merge remote-tracking branch 'origin/master'

This commit is contained in:
Lee Thomason 2014-11-15 17:56:08 -08:00
commit f5d1d9ead2
5 changed files with 103 additions and 65 deletions

View File

@ -46,33 +46,24 @@ endif(MSVC)
################################ ################################
# Add targets # Add targets
set(BUILD_STATIC_LIBS ON CACHE BOOL "Set to ON to build static libraries") option(BUILD_SHARED_LIBS "build shared or static libraries" ON)
if(BUILD_STATIC_LIBS) add_library(tinyxml2 tinyxml2.cpp tinyxml2.h)
add_library(tinyxml2static STATIC tinyxml2.cpp tinyxml2.h)
set_target_properties(tinyxml2static PROPERTIES OUTPUT_NAME tinyxml2)
endif(BUILD_STATIC_LIBS)
add_library(tinyxml2 SHARED tinyxml2.cpp tinyxml2.h)
set_target_properties(tinyxml2 PROPERTIES set_target_properties(tinyxml2 PROPERTIES
COMPILE_DEFINITIONS "TINYXML2_EXPORT" COMPILE_DEFINITIONS "TINYXML2_EXPORT"
VERSION "${GENERIC_LIB_VERSION}" VERSION "${GENERIC_LIB_VERSION}"
SOVERSION "${GENERIC_LIB_SOVERSION}") SOVERSION "${GENERIC_LIB_SOVERSION}")
add_executable(test xmltest.cpp) add_executable(xmltest xmltest.cpp)
add_dependencies(test tinyxml2) add_dependencies(xmltest tinyxml2)
add_dependencies(test ${TARGET_DATA_COPY}) add_dependencies(xmltest ${TARGET_DATA_COPY})
target_link_libraries(test tinyxml2) target_link_libraries(xmltest tinyxml2)
if(BUILD_STATIC_LIBS) install(TARGETS tinyxml2
install(TARGETS tinyxml2 tinyxml2static RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
else(BUILD_STATIC_LIBS)
install(TARGETS tinyxml2
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(BUILD_STATIC_LIBS)
install(FILES tinyxml2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES tinyxml2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
foreach(p LIB INCLUDE) foreach(p LIB INCLUDE)
@ -85,4 +76,4 @@ endforeach()
configure_file(tinyxml2.pc.in tinyxml2.pc @ONLY) configure_file(tinyxml2.pc.in tinyxml2.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
#add_test(test ${SAMPLE_NAME} COMMAND $<TARGET_FILE:${SAMPLE_NAME}>) #add_test(xmltest ${SAMPLE_NAME} COMMAND $<TARGET_FILE:${SAMPLE_NAME}>)

View File

@ -212,12 +212,13 @@ const char* StrPair::GetStr()
else { else {
int i=0; int i=0;
for(; i<NUM_ENTITIES; ++i ) { for(; i<NUM_ENTITIES; ++i ) {
if ( strncmp( p+1, entities[i].pattern, entities[i].length ) == 0 const Entity& entity = entities[i];
&& *(p+entities[i].length+1) == ';' ) { if ( strncmp( p + 1, entity.pattern, entity.length ) == 0
// Found an entity convert; && *( p + entity.length + 1 ) == ';' ) {
*q = entities[i].value; // Found an entity - convert.
*q = entity.value;
++q; ++q;
p += entities[i].length + 2; p += entity.length + 2;
break; break;
} }
} }
@ -1257,7 +1258,7 @@ const char* XMLElement::Attribute( const char* name, const char* value ) const
const char* XMLElement::GetText() const const char* XMLElement::GetText() const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
return FirstChild()->ToText()->Value(); return FirstChild()->Value();
} }
return 0; return 0;
} }
@ -1317,7 +1318,7 @@ void XMLElement::SetText( double v )
XMLError XMLElement::QueryIntText( int* ival ) const XMLError XMLElement::QueryIntText( int* ival ) const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
const char* t = FirstChild()->ToText()->Value(); const char* t = FirstChild()->Value();
if ( XMLUtil::ToInt( t, ival ) ) { if ( XMLUtil::ToInt( t, ival ) ) {
return XML_SUCCESS; return XML_SUCCESS;
} }
@ -1330,7 +1331,7 @@ XMLError XMLElement::QueryIntText( int* ival ) const
XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
const char* t = FirstChild()->ToText()->Value(); const char* t = FirstChild()->Value();
if ( XMLUtil::ToUnsigned( t, uval ) ) { if ( XMLUtil::ToUnsigned( t, uval ) ) {
return XML_SUCCESS; return XML_SUCCESS;
} }
@ -1343,7 +1344,7 @@ XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const
XMLError XMLElement::QueryBoolText( bool* bval ) const XMLError XMLElement::QueryBoolText( bool* bval ) const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
const char* t = FirstChild()->ToText()->Value(); const char* t = FirstChild()->Value();
if ( XMLUtil::ToBool( t, bval ) ) { if ( XMLUtil::ToBool( t, bval ) ) {
return XML_SUCCESS; return XML_SUCCESS;
} }
@ -1356,7 +1357,7 @@ XMLError XMLElement::QueryBoolText( bool* bval ) const
XMLError XMLElement::QueryDoubleText( double* dval ) const XMLError XMLElement::QueryDoubleText( double* dval ) const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
const char* t = FirstChild()->ToText()->Value(); const char* t = FirstChild()->Value();
if ( XMLUtil::ToDouble( t, dval ) ) { if ( XMLUtil::ToDouble( t, dval ) ) {
return XML_SUCCESS; return XML_SUCCESS;
} }
@ -1369,7 +1370,7 @@ XMLError XMLElement::QueryDoubleText( double* dval ) const
XMLError XMLElement::QueryFloatText( float* fval ) const XMLError XMLElement::QueryFloatText( float* fval ) const
{ {
if ( FirstChild() && FirstChild()->ToText() ) { if ( FirstChild() && FirstChild()->ToText() ) {
const char* t = FirstChild()->ToText()->Value(); const char* t = FirstChild()->Value();
if ( XMLUtil::ToFloat( t, fval ) ) { if ( XMLUtil::ToFloat( t, fval ) ) {
return XML_SUCCESS; return XML_SUCCESS;
} }
@ -1622,24 +1623,7 @@ XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :
XMLDocument::~XMLDocument() XMLDocument::~XMLDocument()
{ {
DeleteChildren(); Clear();
delete [] _charBuffer;
#if 0
_textPool.Trace( "text" );
_elementPool.Trace( "element" );
_commentPool.Trace( "comment" );
_attributePool.Trace( "attribute" );
#endif
#ifdef DEBUG
if ( Error() == false ) {
TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() );
TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );
TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() );
TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() );
}
#endif
} }
@ -1653,6 +1637,22 @@ void XMLDocument::Clear()
delete [] _charBuffer; delete [] _charBuffer;
_charBuffer = 0; _charBuffer = 0;
#if 0
_textPool.Trace( "text" );
_elementPool.Trace( "element" );
_commentPool.Trace( "comment" );
_attributePool.Trace( "attribute" );
#endif
#ifdef DEBUG
if ( Error() == false ) {
TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() );
TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );
TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() );
TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() );
}
#endif
} }
@ -1820,6 +1820,16 @@ XMLError XMLDocument::Parse( const char* p, size_t len )
ptrdiff_t delta = p - start; // skip initial whitespace, BOM, etc. ptrdiff_t delta = p - start; // skip initial whitespace, BOM, etc.
ParseDeep( _charBuffer+delta, 0 ); ParseDeep( _charBuffer+delta, 0 );
if (_errorID) {
// clean up now essentially dangling memory.
// and the parse fail can put objects in the
// pools that are dead and inaccessible.
DeleteChildren();
_elementPool.Clear();
_attributePool.Clear();
_textPool.Clear();
_commentPool.Clear();
}
return _errorID; return _errorID;
} }
@ -1836,6 +1846,7 @@ void XMLDocument::Print( XMLPrinter* streamer ) const
void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 )
{ {
TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT );
_errorID = error; _errorID = error;
_errorStr1 = str1; _errorStr1 = str1;
_errorStr2 = str2; _errorStr2 = str2;
@ -1843,7 +1854,7 @@ void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 )
const char* XMLDocument::ErrorName() const const char* XMLDocument::ErrorName() const
{ {
TIXMLASSERT(_errorID >= 0 && _errorID < XML_ERROR_COUNT ); TIXMLASSERT( _errorID >= 0 && _errorID < XML_ERROR_COUNT );
return _errorNames[_errorID]; return _errorNames[_errorID];
} }

View File

@ -14,7 +14,6 @@ not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation software in a product, an acknowledgment in the product documentation
would be appreciated but is not required. would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and 2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software. must not be misrepresented as being the original software.
@ -263,7 +262,7 @@ public:
return _mem[i]; return _mem[i];
} }
const T& PeekTop() const { const T& PeekTop() const {
TIXMLASSERT( _size > 0 ); TIXMLASSERT( _size > 0 );
return _mem[ _size - 1]; return _mem[ _size - 1];
} }
@ -319,6 +318,7 @@ public:
virtual void* Alloc() = 0; virtual void* Alloc() = 0;
virtual void Free( void* ) = 0; virtual void Free( void* ) = 0;
virtual void SetTracked() = 0; virtual void SetTracked() = 0;
virtual void Clear() = 0;
}; };
@ -331,10 +331,20 @@ class MemPoolT : public MemPool
public: public:
MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
~MemPoolT() { ~MemPoolT() {
Clear();
}
void Clear() {
// Delete the blocks. // Delete the blocks.
for( int i=0; i<_blockPtrs.Size(); ++i ) { while( !_blockPtrs.Empty()) {
delete _blockPtrs[i]; Block* b = _blockPtrs.Pop();
delete b;
} }
_root = 0;
_currentAllocs = 0;
_nAllocs = 0;
_maxAllocs = 0;
_nUntracked = 0;
} }
virtual int ItemSize() const { virtual int ItemSize() const {
@ -367,6 +377,7 @@ public:
_nUntracked++; _nUntracked++;
return result; return result;
} }
virtual void Free( void* mem ) { virtual void Free( void* mem ) {
if ( !mem ) { if ( !mem ) {
return; return;
@ -482,7 +493,7 @@ public:
} }
}; };
// WARNING: must match XMLErrorNames[] // WARNING: must match XMLDocument::_errorNames[]
enum XMLError { enum XMLError {
XML_SUCCESS = 0, XML_SUCCESS = 0,
XML_NO_ERROR = 0, XML_NO_ERROR = 0,
@ -516,10 +527,8 @@ enum XMLError {
class XMLUtil class XMLUtil
{ {
public: public:
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
// correct, but simple, and usually works.
static const char* SkipWhiteSpace( const char* p ) { static const char* SkipWhiteSpace( const char* p ) {
while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) { while( IsWhiteSpace(*p) ) {
++p; ++p;
} }
return p; return p;
@ -527,6 +536,9 @@ public:
static char* SkipWhiteSpace( char* p ) { static char* SkipWhiteSpace( char* p ) {
return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) ); return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
} }
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
// correct, but simple, and usually works.
static bool IsWhiteSpace( char p ) { static bool IsWhiteSpace( char p ) {
return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) ); return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
} }

View File

@ -96,6 +96,9 @@
/* Begin PBXProject section */ /* Begin PBXProject section */
037AE058151CCC5200E0F29F /* Project object */ = { 037AE058151CCC5200E0F29F /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
};
buildConfigurationList = 037AE05B151CCC5200E0F29F /* Build configuration list for PBXProject "tinyxml2" */; buildConfigurationList = 037AE05B151CCC5200E0F29F /* Build configuration list for PBXProject "tinyxml2" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English; developmentRegion = English;
@ -134,6 +137,8 @@
buildSettings = { buildSettings = {
CONFIGURATION_BUILD_DIR = "$(SYMROOT)/Debug"; CONFIGURATION_BUILD_DIR = "$(SYMROOT)/Debug";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = DEBUG;
ONLY_ACTIVE_ARCH = YES;
SYMROOT = build; SYMROOT = build;
}; };
name = Debug; name = Debug;
@ -156,6 +161,7 @@
GCC_MODEL_TUNING = G5; GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
INSTALL_PATH = /usr/local/bin; INSTALL_PATH = /usr/local/bin;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO; PREBINDING = NO;
PRODUCT_NAME = xmltest; PRODUCT_NAME = xmltest;
}; };
@ -171,6 +177,7 @@
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_MODEL_TUNING = G5; GCC_MODEL_TUNING = G5;
INSTALL_PATH = /usr/local/bin; INSTALL_PATH = /usr/local/bin;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO; PREBINDING = NO;
PRODUCT_NAME = tinyxml2; PRODUCT_NAME = tinyxml2;
ZERO_LINK = NO; ZERO_LINK = NO;

View File

@ -279,6 +279,8 @@ int main( int argc, const char ** argv )
{ {
#if defined( _MSC_VER ) && defined( DEBUG ) #if defined( _MSC_VER ) && defined( DEBUG )
_CrtMemCheckpoint( &startMemState ); _CrtMemCheckpoint( &startMemState );
// Enable MS Visual C++ debug heap memory leaks dump on exit
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
#endif #endif
#if defined(_MSC_VER) || defined(MINGW32) || defined(__MINGW32__) #if defined(_MSC_VER) || defined(MINGW32) || defined(__MINGW32__)
@ -1372,6 +1374,21 @@ int main( int argc, const char ** argv )
} }
#endif #endif
{
// Issue #184
// If it doesn't assert, it passes. Caused by objects
// getting created during parsing which are then
// inaccessible in the memory pools.
{
XMLDocument doc;
doc.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>");
}
{
XMLDocument doc;
doc.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>");
doc.Clear();
}
}
// ----------- Performance tracking -------------- // ----------- Performance tracking --------------