mirror of https://github.com/AxioDL/tinyxml2.git
Merge branch 'master' into clone
This commit is contained in:
commit
1bbc66b193
|
@ -23,19 +23,9 @@ include(GNUInstallDirs)
|
||||||
set(GENERIC_LIB_VERSION "4.0.1")
|
set(GENERIC_LIB_VERSION "4.0.1")
|
||||||
set(GENERIC_LIB_SOVERSION "4")
|
set(GENERIC_LIB_SOVERSION "4")
|
||||||
|
|
||||||
|
|
||||||
################################
|
|
||||||
# Add common source
|
|
||||||
|
|
||||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.")
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# Add definitions
|
# Add definitions
|
||||||
|
|
||||||
if(MSVC)
|
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
endif(MSVC)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
@ -65,11 +55,29 @@ set_target_properties(tinyxml2 PROPERTIES
|
||||||
VERSION "${GENERIC_LIB_VERSION}"
|
VERSION "${GENERIC_LIB_VERSION}"
|
||||||
SOVERSION "${GENERIC_LIB_SOVERSION}")
|
SOVERSION "${GENERIC_LIB_SOVERSION}")
|
||||||
|
|
||||||
|
|
||||||
if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||||
target_include_directories(tinyxml2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/.")
|
target_include_directories(tinyxml2 PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_definitions(tinyxml2 PUBLIC -D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif(MSVC)
|
||||||
|
else()
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR})
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif(MSVC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# export targets for find_package config mode
|
||||||
|
export(TARGETS tinyxml2
|
||||||
|
FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
|
||||||
|
|
||||||
install(TARGETS tinyxml2
|
install(TARGETS tinyxml2
|
||||||
|
EXPORT ${CMAKE_PROJECT_NAME}Targets
|
||||||
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})
|
||||||
|
@ -83,11 +91,30 @@ set_target_properties(tinyxml2_static PROPERTIES
|
||||||
SOVERSION "${GENERIC_LIB_SOVERSION}")
|
SOVERSION "${GENERIC_LIB_SOVERSION}")
|
||||||
set_target_properties( tinyxml2_static PROPERTIES OUTPUT_NAME tinyxml2 )
|
set_target_properties( tinyxml2_static PROPERTIES OUTPUT_NAME tinyxml2 )
|
||||||
|
|
||||||
|
target_compile_definitions(tinyxml2 PUBLIC -D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
|
||||||
if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
|
||||||
target_include_directories(tinyxml2_static INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/.")
|
target_include_directories(tinyxml2_static PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_definitions(tinyxml2 PUBLIC -D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif(MSVC)
|
||||||
|
else()
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR})
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif(MSVC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# export targets for find_package config mode
|
||||||
|
export(TARGETS tinyxml2_static
|
||||||
|
FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
|
||||||
|
|
||||||
install(TARGETS tinyxml2_static
|
install(TARGETS tinyxml2_static
|
||||||
|
EXPORT ${CMAKE_PROJECT_NAME}Targets
|
||||||
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})
|
||||||
|
@ -131,3 +158,14 @@ configure_file(
|
||||||
|
|
||||||
add_custom_target(uninstall
|
add_custom_target(uninstall
|
||||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||||
|
|
||||||
|
file(WRITE
|
||||||
|
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
|
||||||
|
"include(\${CMAKE_CURRENT_LIST_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)\n")
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
|
||||||
|
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
|
||||||
|
|
||||||
|
install(EXPORT ${CMAKE_PROJECT_NAME}Targets
|
||||||
|
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
|
34
tinyxml2.cpp
34
tinyxml2.cpp
|
@ -809,9 +809,11 @@ void XMLNode::Unlink( XMLNode* child )
|
||||||
|
|
||||||
if ( child->_prev ) {
|
if ( child->_prev ) {
|
||||||
child->_prev->_next = child->_next;
|
child->_prev->_next = child->_next;
|
||||||
|
child->_prev = 0;
|
||||||
}
|
}
|
||||||
if ( child->_next ) {
|
if ( child->_next ) {
|
||||||
child->_next->_prev = child->_prev;
|
child->_next->_prev = child->_prev;
|
||||||
|
child->_next = 0;
|
||||||
}
|
}
|
||||||
child->_parent = 0;
|
child->_parent = 0;
|
||||||
}
|
}
|
||||||
|
@ -823,6 +825,9 @@ void XMLNode::DeleteChild( XMLNode* node )
|
||||||
TIXMLASSERT( node->_document == _document );
|
TIXMLASSERT( node->_document == _document );
|
||||||
TIXMLASSERT( node->_parent == this );
|
TIXMLASSERT( node->_parent == this );
|
||||||
Unlink( node );
|
Unlink( node );
|
||||||
|
TIXMLASSERT(node->_prev == 0);
|
||||||
|
TIXMLASSERT(node->_next == 0);
|
||||||
|
TIXMLASSERT(node->_parent == 0);
|
||||||
DeleteNode( node );
|
DeleteNode( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,11 +1072,16 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLNode::DeleteNode( XMLNode* node )
|
/*static*/ void XMLNode::DeleteNode( XMLNode* node )
|
||||||
{
|
{
|
||||||
if ( node == 0 ) {
|
if ( node == 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TIXMLASSERT(node->_document);
|
||||||
|
if (!node->ToDocument()) {
|
||||||
|
node->_document->MarkInUse(node);
|
||||||
|
}
|
||||||
|
|
||||||
MemPool* pool = node->_memPool;
|
MemPool* pool = node->_memPool;
|
||||||
node->~XMLNode();
|
node->~XMLNode();
|
||||||
pool->Free( node );
|
pool->Free( node );
|
||||||
|
@ -1082,11 +1092,14 @@ void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const
|
||||||
TIXMLASSERT( insertThis );
|
TIXMLASSERT( insertThis );
|
||||||
TIXMLASSERT( insertThis->_document == _document );
|
TIXMLASSERT( insertThis->_document == _document );
|
||||||
|
|
||||||
if ( insertThis->_parent )
|
if (insertThis->_parent) {
|
||||||
insertThis->_parent->Unlink( insertThis );
|
insertThis->_parent->Unlink( insertThis );
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
insertThis->_document->MarkInUse(insertThis);
|
||||||
insertThis->_memPool->SetTracked();
|
insertThis->_memPool->SetTracked();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const XMLElement* XMLNode::ToElementWithName( const char* name ) const
|
const XMLElement* XMLNode::ToElementWithName( const char* name ) const
|
||||||
{
|
{
|
||||||
|
@ -1991,9 +2004,24 @@ XMLDocument::~XMLDocument()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLDocument::MarkInUse(XMLNode* node)
|
||||||
|
{
|
||||||
|
TIXMLASSERT(node->_parent == 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < _unlinked.Size(); ++i) {
|
||||||
|
if (node == _unlinked[i]) {
|
||||||
|
_unlinked.SwapRemove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void XMLDocument::Clear()
|
void XMLDocument::Clear()
|
||||||
{
|
{
|
||||||
DeleteChildren();
|
DeleteChildren();
|
||||||
|
while( _unlinked.Size()) {
|
||||||
|
DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete.
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
const bool hadError = Error();
|
const bool hadError = Error();
|
||||||
|
|
20
tinyxml2.h
20
tinyxml2.h
|
@ -264,6 +264,13 @@ public:
|
||||||
return _allocated;
|
return _allocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwapRemove(int i) {
|
||||||
|
TIXMLASSERT(i >= 0);
|
||||||
|
TIXMLASSERT(i < _size);
|
||||||
|
_mem[i] = _mem[_size - 1];
|
||||||
|
--_size;
|
||||||
|
}
|
||||||
|
|
||||||
const T* Mem() const {
|
const T* Mem() const {
|
||||||
TIXMLASSERT( _mem );
|
TIXMLASSERT( _mem );
|
||||||
return _mem;
|
return _mem;
|
||||||
|
@ -1826,6 +1833,9 @@ public:
|
||||||
// internal
|
// internal
|
||||||
char* Identify( char* p, XMLNode** node );
|
char* Identify( char* p, XMLNode** node );
|
||||||
|
|
||||||
|
// internal
|
||||||
|
void MarkInUse(XMLNode*);
|
||||||
|
|
||||||
virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
|
virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1846,6 +1856,13 @@ private:
|
||||||
int _errorLineNum;
|
int _errorLineNum;
|
||||||
char* _charBuffer;
|
char* _charBuffer;
|
||||||
int _parseCurLineNum;
|
int _parseCurLineNum;
|
||||||
|
// Memory tracking does add some overhead.
|
||||||
|
// However, the code assumes that you don't
|
||||||
|
// have a bunch of unlinked nodes around.
|
||||||
|
// Therefore it takes less memory to track
|
||||||
|
// in the document vs. a linked list in the XMLNode,
|
||||||
|
// and the performance is the same.
|
||||||
|
DynArray<XMLNode*, 10> _unlinked;
|
||||||
|
|
||||||
MemPoolT< sizeof(XMLElement) > _elementPool;
|
MemPoolT< sizeof(XMLElement) > _elementPool;
|
||||||
MemPoolT< sizeof(XMLAttribute) > _attributePool;
|
MemPoolT< sizeof(XMLAttribute) > _attributePool;
|
||||||
|
@ -1868,6 +1885,8 @@ inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& poo
|
||||||
NodeType* returnNode = new (pool.Alloc()) NodeType( this );
|
NodeType* returnNode = new (pool.Alloc()) NodeType( this );
|
||||||
TIXMLASSERT( returnNode );
|
TIXMLASSERT( returnNode );
|
||||||
returnNode->_memPool = &pool;
|
returnNode->_memPool = &pool;
|
||||||
|
|
||||||
|
_unlinked.Push(returnNode);
|
||||||
return returnNode;
|
return returnNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2201,6 +2220,7 @@ public:
|
||||||
void ClearBuffer() {
|
void ClearBuffer() {
|
||||||
_buffer.Clear();
|
_buffer.Clear();
|
||||||
_buffer.Push(0);
|
_buffer.Push(0);
|
||||||
|
_firstElement = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
29
xmltest.cpp
29
xmltest.cpp
|
@ -1721,6 +1721,35 @@ int main( int argc, const char ** argv )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Evil memory leaks.
|
||||||
|
// If an XMLElement (etc) is allocated via NewElement() (etc.)
|
||||||
|
// and NOT added to the XMLDocument, what happens?
|
||||||
|
//
|
||||||
|
// Previously (buggy):
|
||||||
|
// The memory would be free'd when the XMLDocument is
|
||||||
|
// destructed. But the destructor wasn't called, so that
|
||||||
|
// memory allocated by the XMLElement would not be free'd.
|
||||||
|
// In practice this meant strings allocated by the XMLElement
|
||||||
|
// would leak. An edge case, but annoying.
|
||||||
|
// Now:
|
||||||
|
// The destructor is called. But the list of unlinked nodes
|
||||||
|
// has to be tracked. This has a minor performance impact
|
||||||
|
// that can become significant if you have a lot. (But why
|
||||||
|
// would you do that?)
|
||||||
|
// The only way to see this bug is in a leak tracker. This
|
||||||
|
// is compiled in by default on Windows Debug.
|
||||||
|
{
|
||||||
|
XMLDocument doc;
|
||||||
|
doc.NewElement("LEAK 1");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
XMLDocument doc;
|
||||||
|
XMLElement* ele = doc.NewElement("LEAK 2");
|
||||||
|
doc.DeleteNode(ele);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------- Line Number Tracking --------------
|
// ----------- Line Number Tracking --------------
|
||||||
{
|
{
|
||||||
struct TestUtil: XMLVisitor
|
struct TestUtil: XMLVisitor
|
||||||
|
|
Loading…
Reference in New Issue