Commit 39827e0e authored by Sylvain Thery's avatar Sylvain Thery

tinyxml2 copy in third_party

parent 69b46a46
cmake_minimum_required(VERSION 2.8)
project(CGoGN)
cmake_policy(SET CMP0042 NEW) # rpath new policy
#SET ( CMAKE_VERBOSE_MAKEFILE 1 )
......@@ -42,8 +43,15 @@ IF (NOT (${CMAKE_BUILD_TYPE} MATCHES "Debug|Release"))
ENDIF()
# for shared or not shared
SET ( BUILD_SHARED_LIBS OFF CACHE BOOL "if used all library are build as shared type (.so/.dylib/.dll)" )
# for shared or not shared (default except on windows)
if(WIN32)
SET ( BUILD_SHARED_LIBS OFF CACHE BOOL "if used all library are build as shared type (.so/.dylib/.dll)" )
else()
SET ( BUILD_SHARED_LIBS ON CACHE BOOL "if used all library are build as shared type (.so/.dylib/.dll)" )
endif()
#IF(EXISTS "${CGoGN_ROOT_DIR}/ThirdParty/include/Assimp")
IF(EXISTS "${CGoGN_ROOT_DIR}/lib/${CMAKE_BUILD_TYPE}/*assimp*")
......@@ -68,9 +76,10 @@ SET ( COMPILE_BENCHES ON CACHE BOOL "compile benches" )
SET ( COMPILE_SANDBOX ON CACHE BOOL "compile all in sandbox" )
#create one big lib
#create one big lib
SET ( ONELIB OFF CACHE BOOL "build CGoGN in one lib" )
SET ( WITH_GLEWMX OFF CACHE BOOL "use multi-contex GLEW" )
SET( USE_OGL_CORE_PROFILE OFF CACHE BOOL "use OpenGL 3.3 core profile (do not work on mac)" )
......
cmake_minimum_required(VERSION 2.8)
include(ExternalProject)
project(CGoGN_ThirdParty)
# for access to var CMAKE_INSTALL_LIBDIR
include(GNUInstallDirs)
cmake_policy(SET CMP0042 NEW) # rpath new policy
SET(CGoGN_ROOT_DIR ${CMAKE_SOURCE_DIR}/..)
IF(WIN32)
ENDIF(WIN32)
IF (${CMAKE_CURRENT_BINARY_DIR} MATCHES "(.*)Debug")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Debug/Release" FORCE)
......@@ -24,29 +18,14 @@ IF(WIN32)
INCLUDE_DIRECTORIES(${CGoGN_ROOT_DIR}/windows_dependencies/include/suitesparse)
SET(LIBRARY_OUTPUT_PATH ${CGoGN_ROOT_DIR}/lib)
set(CMAKE_CONFIGURATION_TYPES Release Debug)
SET (BUILD_SHARED_LIBS OFF CACHE BOOL "if used all library are build as shared type (.so/.dylib/.dll)")
ELSE()
SET(LIBRARY_OUTPUT_PATH ${CGoGN_ROOT_DIR}/lib/${CMAKE_BUILD_TYPE})
ExternalProject_Add(
Tinyxml2
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2
GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git
CMAKE_CACHE_ARGS "-DCMAKE_BUILD_TYPE:string=${CMAKE_BUILD_TYPE}"
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CGoGN_ROOT_DIR}/ThirdParty/TinyXml2"
BUILD_COMMAND make
INSTALL_COMMAND make install
)
INSTALL (DIRECTORY TinyXml2/include/ DESTINATION ${CGoGN_ROOT_DIR}/ThirdParty/include)
INSTALL (DIRECTORY TinyXml2/${CMAKE_INSTALL_LIBDIR}/ DESTINATION ${CGoGN_ROOT_DIR}/lib/${CMAKE_BUILD_TYPE}
PATTERN "pkgconfig" EXCLUDE )
SET (BUILD_SHARED_LIBS ON CACHE BOOL "if used all library are build as shared type (.so/.dylib/.dll)")
ENDIF()
# for shared or not shared
SET (BUILD_SHARED_LIBS OFF CACHE BOOL
"if used all library are build as shared type (.so/.dylib/.dll)")
SET (WITH_ASSIMP OFF CACHE BOOL "build with Assimp")
SET (WITH_ZINRI ON CACHE BOOL "build with Zinri libs")
......@@ -78,3 +57,7 @@ IF (WITH_ASSIMP)
add_subdirectory(Assimp Assimp/build)
INSTALL (DIRECTORY Assimp/include/ DESTINATION ${CGoGN_ROOT_DIR}/ThirdParty/include/Assimp)
ENDIF (WITH_ASSIMP)
add_subdirectory(TinyXml2 TinyXml2/build)
INSTALL (DIRECTORY TinyXml2/ DESTINATION ${CGoGN_ROOT_DIR}/ThirdParty/include/TinyXml2 FILES_MATCHING PATTERN "*.h")
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
#cmake_policy(VERSION 2.6)
project(tinyxml2)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.")
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
option(BUILD_SHARED_LIBS "build shared or static libraries" ON)
add_library(tinyxml2 tinyxml2.cpp tinyxml2.h)
set_target_properties(tinyxml2 PROPERTIES COMPILE_DEFINITIONS "TINYXML2_EXPORT")
#install(TARGETS tinyxml2
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
#install(FILES tinyxml2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
#foreach(p LIB INCLUDE)
# set(var CMAKE_INSTALL_${p}DIR)
# if(NOT IS_ABSOLUTE "${${var}}")
# set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
# endif()
#endforeach()
#configure_file(tinyxml2.pc.in tinyxml2.pc @ONLY)
#install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
#add_test(xmltest ${SAMPLE_NAME} COMMAND $<TARGET_FILE:${SAMPLE_NAME}>)
This is a "partial" copy of original TinyXML-2 library.
http://www.grinninglizard.com/tinyxml2/
Packaged version is not usable on all Linux distribution
Git version is not locally installabe on mac.
CMakeLists.txt has been modified for easy local installation.
Only needed files for building the library have been kept.
/*
Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
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.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "tinyxml2.h"
#include <new> // yes, this one new style header, is in the Android SDK.
#if defined(ANDROID_NDK) || defined(__QNXNTO__)
# include <stddef.h>
#else
# include <cstddef>
#endif
static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF
static const char LF = LINE_FEED;
static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out
static const char CR = CARRIAGE_RETURN;
static const char SINGLE_QUOTE = '\'';
static const char DOUBLE_QUOTE = '\"';
// Bunch of unicode info at:
// http://www.unicode.org/faq/utf_bom.html
// ef bb bf (Microsoft "lead bytes") - designates UTF-8
static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
namespace tinyxml2
{
struct Entity {
const char* pattern;
int length;
char value;
};
static const int NUM_ENTITIES = 5;
static const Entity entities[NUM_ENTITIES] = {
{ "quot", 4, DOUBLE_QUOTE },
{ "amp", 3, '&' },
{ "apos", 4, SINGLE_QUOTE },
{ "lt", 2, '<' },
{ "gt", 2, '>' }
};
StrPair::~StrPair()
{
Reset();
}
void StrPair::TransferTo( StrPair* other )
{
if ( this == other ) {
return;
}
// This in effect implements the assignment operator by "moving"
// ownership (as in auto_ptr).
TIXMLASSERT( other->_flags == 0 );
TIXMLASSERT( other->_start == 0 );
TIXMLASSERT( other->_end == 0 );
other->Reset();
other->_flags = _flags;
other->_start = _start;
other->_end = _end;
_flags = 0;
_start = 0;
_end = 0;
}
void StrPair::Reset()
{
if ( _flags & NEEDS_DELETE ) {
delete [] _start;
}
_flags = 0;
_start = 0;
_end = 0;
}
void StrPair::SetStr( const char* str, int flags )
{
Reset();
size_t len = strlen( str );
_start = new char[ len+1 ];
memcpy( _start, str, len+1 );
_end = _start + len;
_flags = flags | NEEDS_DELETE;
}
char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
{
TIXMLASSERT( endTag && *endTag );
char* start = p;
char endChar = *endTag;
size_t length = strlen( endTag );
// Inner loop of text parsing.
while ( *p ) {
if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
Set( start, p, strFlags );
return p + length;
}
++p;
}
return 0;
}
char* StrPair::ParseName( char* p )
{
if ( !p || !(*p) ) {
return 0;
}
if ( !XMLUtil::IsNameStartChar( *p ) ) {
return 0;
}
char* const start = p;
++p;
while ( *p && XMLUtil::IsNameChar( *p ) ) {
++p;
}
Set( start, p, 0 );
return p;
}
void StrPair::CollapseWhitespace()
{
// Adjusting _start would cause undefined behavior on delete[]
TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 );
// Trim leading space.
_start = XMLUtil::SkipWhiteSpace( _start );
if ( *_start ) {
char* p = _start; // the read pointer
char* q = _start; // the write pointer
while( *p ) {
if ( XMLUtil::IsWhiteSpace( *p )) {
p = XMLUtil::SkipWhiteSpace( p );
if ( *p == 0 ) {
break; // don't write to q; this trims the trailing space.
}
*q = ' ';
++q;
}
*q = *p;
++q;
++p;
}
*q = 0;
}
}
const char* StrPair::GetStr()
{
TIXMLASSERT( _start );
TIXMLASSERT( _end );
if ( _flags & NEEDS_FLUSH ) {
*_end = 0;
_flags ^= NEEDS_FLUSH;
if ( _flags ) {
char* p = _start; // the read pointer
char* q = _start; // the write pointer
while( p < _end ) {
if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) {
// CR-LF pair becomes LF
// CR alone becomes LF
// LF-CR becomes LF
if ( *(p+1) == LF ) {
p += 2;
}
else {
++p;
}
*q++ = LF;
}
else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) {
if ( *(p+1) == CR ) {
p += 2;
}
else {
++p;
}
*q++ = LF;
}
else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) {
// Entities handled by tinyXML2:
// - special entities in the entity table [in/out]
// - numeric character reference [in]
// &#20013; or &#x4e2d;
if ( *(p+1) == '#' ) {
const int buflen = 10;
char buf[buflen] = { 0 };
int len = 0;
p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );
TIXMLASSERT( 0 <= len && len <= buflen );
TIXMLASSERT( q + len <= p );
memcpy( q, buf, len );
q += len;
}
else {
int i=0;
for(; i<NUM_ENTITIES; ++i ) {
const Entity& entity = entities[i];
if ( strncmp( p + 1, entity.pattern, entity.length ) == 0
&& *( p + entity.length + 1 ) == ';' ) {
// Found an entity - convert.
*q = entity.value;
++q;
p += entity.length + 2;
break;
}
}
if ( i == NUM_ENTITIES ) {
// fixme: treat as error?
++p;
++q;
}
}
}
else {
*q = *p;
++p;
++q;
}
}
*q = 0;
}
// The loop below has plenty going on, and this
// is a less useful mode. Break it out.
if ( _flags & COLLAPSE_WHITESPACE ) {
CollapseWhitespace();
}
_flags = (_flags & NEEDS_DELETE);
}
TIXMLASSERT( _start );
return _start;
}
// --------- XMLUtil ----------- //
const char* XMLUtil::ReadBOM( const char* p, bool* bom )
{
TIXMLASSERT( p );
TIXMLASSERT( bom );
*bom = false;
const unsigned char* pu = reinterpret_cast<const unsigned char*>(p);
// Check for BOM:
if ( *(pu+0) == TIXML_UTF_LEAD_0
&& *(pu+1) == TIXML_UTF_LEAD_1
&& *(pu+2) == TIXML_UTF_LEAD_2 ) {
*bom = true;
p += 3;
}
TIXMLASSERT( p );
return p;
}
void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
{
const unsigned long BYTE_MASK = 0xBF;
const unsigned long BYTE_MARK = 0x80;
const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
if (input < 0x80) {
*length = 1;
}
else if ( input < 0x800 ) {
*length = 2;
}
else if ( input < 0x10000 ) {
*length = 3;
}
else if ( input < 0x200000 ) {
*length = 4;
}
else {
*length = 0; // This code won't covert this correctly anyway.
return;
}
output += *length;
// Scary scary fall throughs.
switch (*length) {
case 4:
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
input >>= 6;
case 3:
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
input >>= 6;
case 2:
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
input >>= 6;
case 1:
--output;
*output = (char)(input | FIRST_BYTE_MARK[*length]);
default:
break;
}
}
const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length )
{
// Presume an entity, and pull it out.
*length = 0;
if ( *(p+1) == '#' && *(p+2) ) {
unsigned long ucs = 0;
TIXMLASSERT( sizeof( ucs ) >= 4 );
ptrdiff_t delta = 0;
unsigned mult = 1;
static const char SEMICOLON = ';';
if ( *(p+2) == 'x' ) {
// Hexadecimal.
if ( !*(p+3) ) {
return 0;
}
const char* q = p+3;
q = strchr( q, SEMICOLON );
if ( !q ) {
return 0;
}
TIXMLASSERT( *q == SEMICOLON );
delta = q-p;
--q;
while ( *q != 'x' ) {
if ( *q >= '0' && *q <= '9' ) {
ucs += mult * (*q - '0');
}
else if ( *q >= 'a' && *q <= 'f' ) {
ucs += mult * (*q - 'a' + 10);
}
else if ( *q >= 'A' && *q <= 'F' ) {
ucs += mult * (*q - 'A' + 10 );
}
else {
return 0;
}
TIXMLASSERT( mult <= UINT_MAX / 16 );
mult *= 16;
--q;
}
}
else {
// Decimal.
if ( !*(p+2) ) {
return 0;
}
const char* q = p+2;
q = strchr( q, SEMICOLON );
if ( !q ) {
return 0;
}
TIXMLASSERT( *q == SEMICOLON );
delta = q-p;
--q;
while ( *q != '#' ) {
if ( *q >= '0' && *q <= '9' ) {
ucs += mult * (*q - '0');
}
else {
return 0;
}
TIXMLASSERT( mult <= UINT_MAX / 10 );
mult *= 10;
--q;
}
}
// convert the UCS to UTF-8
ConvertUTF32ToUTF8( ucs, value, length );
return p + delta + 1;
}
return p+1;
}
void XMLUtil::ToStr( int v, char* buffer, int bufferSize )
{
TIXML_SNPRINTF( buffer, bufferSize, "%d", v );
}
void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize )
{
TIXML_SNPRINTF( buffer, bufferSize, "%u", v );
}
void XMLUtil::ToStr( bool v, char* buffer, int bufferSize )
{
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 )
{
TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
}
void XMLUtil::ToStr( double v, char* buffer, int bufferSize )
{
TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v );
}
bool XMLUtil::ToInt( const char* str, int* value )
{
if ( TIXML_SSCANF( str, "%d", value ) == 1 ) {
return true;
}
return false;
}
bool XMLUtil::ToUnsigned( const char* str, unsigned *value )
{
if ( TIXML_SSCANF( str, "%u", value ) == 1 ) {
return true;
}
return false;
}
bool XMLUtil::ToBool( const char* str, bool* value )
{
int ival = 0;
if ( ToInt( str, &ival )) {
*value = (ival==0) ? false : true;
return true;
}
if ( StringEqual( str, "true" ) ) {
*value = true;
return true;
}
else if ( StringEqual( str, "false" ) ) {
*value = false;
return true;
}
return false;
}
bool XMLUtil::ToFloat( const char* str, float* value )
{
if ( TIXML_SSCANF( str, "%f", value ) == 1 ) {
return true;
}
return false;
}
bool XMLUtil::ToDouble( const char* str, double* value )
{
if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) {
return true;
}
return false;
}
char* XMLDocument::Identify( char* p, XMLNode** node )
{
char* const start = p;
p = XMLUtil::SkipWhiteSpace( p );
if( !*p ) {
return p;
}
// What is this thing?
// These strings define the matching patters:
static const char* xmlHeader = { "<?" };
static const char* commentHeader = { "<!--" };
static const char* dtdHeader = { "<!" };
static const char* cdataHeader = { "<![CDATA[" };
static const char* elementHeader = { "<" }; // and a header for everything else; check last.
static const int xmlHeaderLen = 2;
static const int commentHeaderLen = 4;
static const int dtdHeaderLen = 2;
static const int cdataHeaderLen = 9;
static const int elementHeaderLen = 1;
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool
TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool
XMLNode* returnNode = 0;
if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {
TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );
returnNode = new (_commentPool.Alloc()) XMLDeclaration( this );
returnNode->_memPool = &_commentPool;
p += xmlHeaderLen;
}
else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {
TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );
returnNode = new (_commentPool.Alloc()) XMLComment( this );
returnNode->_memPool = &_commentPool;
p += commentHeaderLen;
}
else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
XMLText* text = new (_textPool.Alloc()) XMLText( this );
returnNode = text;
returnNode->_memPool = &_textPool;
p += cdataHeaderLen;
text->SetCData( true );
}
else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {
TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );
returnNode = new (_commentPool.Alloc()) XMLUnknown( this );
returnNode->_memPool = &_commentPool;
p += dtdHeaderLen;
}
else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {
TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );
returnNode = new (_elementPool.Alloc()) XMLElement( this );
returnNode->_memPool = &_elementPool;
p += elementHeaderLen;
}
else {
TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );
returnNode = new (_textPool.Alloc()) XMLText( this );
returnNode->_memPool = &_textPool;
p = start; // Back it up, all the text counts.
}
*node = returnNode;
return p;
}
bool XMLDocument::Accept( XMLVisitor* visitor ) const
{
TIXMLASSERT( visitor );
if ( visitor->VisitEnter( *this ) ) {
for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {
if ( !node->Accept( visitor ) ) {
break;
}