Merge remote-tracking branch 'origin/master'

This commit is contained in:
Lee Thomason 2014-02-21 22:47:21 -08:00
commit 7de26f7dc7
6 changed files with 273 additions and 53 deletions

View File

@ -10,8 +10,8 @@ include(GNUInstallDirs)
################################
# set lib version here
set(GENERIC_LIB_VERSION "1.0.12")
set(GENERIC_LIB_SOVERSION "1")
set(GENERIC_LIB_VERSION "1.0.14")
set(GENERIC_LIB_SOVERSION "1")
################################
@ -53,6 +53,7 @@ if(BUILD_STATIC_LIBS)
endif(BUILD_STATIC_LIBS)
add_library(tinyxml2 SHARED tinyxml2.cpp tinyxml2.h)
set_target_properties(tinyxml2 PROPERTIES
COMPILE_DEFINITIONS "TINYXML2_EXPORT"
VERSION "${GENERIC_LIB_VERSION}"
SOVERSION "${GENERIC_LIB_SOVERSION}")

2
dox
View File

@ -32,7 +32,7 @@ PROJECT_NAME = "TinyXML-2"
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 1.0.12
PROJECT_NUMBER = 1.0.14
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer

View File

@ -51,11 +51,10 @@ What it doesn't do.
TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs
(eXtensible Stylesheet Language.) There are other parsers out there
that are much more fully
featured. But they are also much bigger, take longer to set up in
your project, have a higher learning curve, and often have a more
restrictive license. If you are working with browsers or have more
complete XML needs, TinyXML-2 is not the parser for you.
that are much more fully featured. But they are also much bigger,
take longer to set up in your project, have a higher learning curve,
and often have a more restrictive license. If you are working with
browsers or have more complete XML needs, TinyXML-2 is not the parser for you.
TinyXML-1 vs. TinyXML-2
-----------------------
@ -309,8 +308,9 @@ in shaping what is a very successful library. Extra thanks to Yves
Berquin and Andrew Ellerton who were key contributors.
TinyXML-2 grew from that effort. Lee Thomason is the original author
of TinyXML-2 (and TinyXML-1) but hopefully TinyXML-2 will be improved
of TinyXML-2 (and TinyXML-1) but TinyXML-2 has been and is being improved
by many contributors.
Thanks to John Mackay for the TinyXML-2 logo.
Thanks to John Mackay at http://john.mackay.rosalilastudio.com for the TinyXML-2 logo!

View File

@ -422,16 +422,19 @@ 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, "%f", v );
TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v );
}
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?
// - Elements start with a letter or underscore, but xml is reserved.
// - Comments: <!--
// - Declaration: <?
// - Everything else is unknown to tinyxml.
//
// These strings define the matching patters:
static const char* xmlHeader = { "<?" };
static const char* commentHeader = { "<!--" };
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
{
if ( FirstChild() && FirstChild()->ToText() ) {
@ -1639,6 +1688,13 @@ XMLError XMLDocument::LoadFile( FILE* fp )
{
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 );
size_t size = ftell( fp );
fseek( fp, 0, SEEK_SET );

View File

@ -116,9 +116,15 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
#define TIXML_SSCANF sscanf
#endif
/* Versioning, past 1.0.14:
A backwards-incompatible change or API change bumps the major version.
An API addition or a backwards-compatible change, bumps the minor version.
Simple bug fixes bump the build number.
*/
static const int TIXML2_MAJOR_VERSION = 1;
static const int TIXML2_MINOR_VERSION = 0;
static const int TIXML2_PATCH_VERSION = 12;
static const int TIXML2_MINOR_VERSION = 1;
static const int TIXML2_PATCH_VERSION = 0;
namespace tinyxml2
{
@ -216,6 +222,10 @@ public:
}
}
void Clear() {
_size = 0;
}
void Push( T t ) {
EnsureCapacity( _size+1 );
_mem[_size++] = t;
@ -1317,6 +1327,11 @@ public:
XMLAttribute* a = FindOrCreateAttribute( name );
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.
@ -1360,6 +1375,52 @@ public:
*/
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
shown by example. Given you have a document is this form:
@ -1420,6 +1481,7 @@ private:
//void LinkAttribute( XMLAttribute* attrib );
char* ParseAttributes( char* p );
enum { BUF_SIZE = 200 };
int _closingType;
// The attribute list is ordered; there is no 'lastAttribute'
// because the list needs to be scanned for dupes before adding
@ -1962,23 +2024,35 @@ public:
int CStrSize() const {
return _buffer.Size();
}
/**
If in print to memory mode, reset the buffer to the
beginning.
*/
void ClearBuffer() {
_buffer.Clear();
_buffer.Push(0);
}
protected:
void SealElement();
/** 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;
DynArray< const char*, 10 > _stack;
private:
void PrintSpace( int depth );
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
void Print( const char* format, ... );
bool _firstElement;
FILE* _fp;
int _depth;
int _textDepth;
bool _processEntities;
bool _compactMode;
bool _compactMode;
enum {
ENTITY_RANGE = 64,

View File

@ -617,6 +617,61 @@ int main( int argc, const char ** argv )
}
// --------SetText()-----------
{
const char* str = "<foo></foo>";
XMLDocument doc;
doc.Parse( str );
XMLElement* element = doc.RootElement();
element->SetText("darkness.");
XMLTest( "SetText() normal use (open/close).", "darkness.", element->GetText() );
element->SetText("blue flame.");
XMLTest( "SetText() replace.", "blue flame.", element->GetText() );
str = "<foo/>";
doc.Parse( str );
element = doc.RootElement();
element->SetText("The driver");
XMLTest( "SetText() normal use. (self-closing)", "The driver", element->GetText() );
element->SetText("<b>horses</b>");
XMLTest( "SetText() replace with tag-like text.", "<b>horses</b>", element->GetText() );
//doc.Print();
str = "<foo><bar>Text in nested element</bar></foo>";
doc.Parse( str );
element = doc.RootElement();
element->SetText("wolves");
XMLTest( "SetText() prefix to nested non-text children.", "wolves", element->GetText() );
str = "<foo/>";
doc.Parse( str );
element = doc.RootElement();
element->SetText( "str" );
XMLTest( "SetText types", "str", element->GetText() );
element->SetText( 1 );
XMLTest( "SetText types", "1", element->GetText() );
element->SetText( 1U );
XMLTest( "SetText types", "1", element->GetText() );
element->SetText( true );
XMLTest( "SetText types", "1", element->GetText() ); // TODO: should be 'true'?
element->SetText( 1.5f );
XMLTest( "SetText types", "1.5", element->GetText() );
element->SetText( 1.5 );
XMLTest( "SetText types", "1.5", element->GetText() );
}
// ---------- CDATA ---------------
{
const char* str = "<xmlElement>"
@ -1139,18 +1194,6 @@ int main( int argc, const char ** argv )
XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() );
}
#if 0 // the question being explored is what kind of print to use:
// https://github.com/leethomason/tinyxml2/issues/63
{
const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9'/>";
XMLDocument doc;
doc.Parse( xml );
doc.FirstChildElement()->SetAttribute( "attrA", 123456789.123456789 );
doc.FirstChildElement()->SetAttribute( "attrB", 1.001e9 );
doc.Print();
}
#endif
{
// An assert should not fire.
const char* xml = "<element/>";
@ -1240,39 +1283,85 @@ int main( int argc, const char ** argv )
"</root>";
XMLDocument doc;
doc.Parse( xml );
doc.Parse(xml);
XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
XMLElement* two = doc.RootElement()->FirstChildElement("two");
two->InsertFirstChild(subtree);
XMLPrinter printer1( 0, true );
doc.Accept( &printer1 );
XMLTest( "Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());
XMLPrinter printer1(0, true);
doc.Accept(&printer1);
XMLTest("Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());
doc.Parse( xml );
doc.Parse(xml);
subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
two = doc.RootElement()->FirstChildElement("two");
doc.RootElement()->InsertAfterChild(two, subtree);
XMLPrinter printer2( 0, true );
doc.Accept( &printer2 );
XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false );
XMLPrinter printer2(0, true);
doc.Accept(&printer2);
XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false);
doc.Parse( xml );
doc.Parse(xml);
XMLNode* one = doc.RootElement()->FirstChildElement("one");
subtree = one->FirstChildElement("subtree");
doc.RootElement()->InsertAfterChild(one, subtree);
XMLPrinter printer3( 0, true );
doc.Accept( &printer3 );
XMLTest( "Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false );
XMLPrinter printer3(0, true);
doc.Accept(&printer3);
XMLTest("Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false);
doc.Parse( xml );
doc.Parse(xml);
subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
two = doc.RootElement()->FirstChildElement("two");
doc.RootElement()->InsertEndChild(subtree);
XMLPrinter printer4( 0, true );
doc.Accept( &printer4 );
XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false );
XMLPrinter printer4(0, true);
doc.Accept(&printer4);
XMLTest("Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false);
}
{
const char* xml = "<svg width = \"128\" height = \"128\">"
" <text> </text>"
"</svg>";
XMLDocument doc;
doc.Parse(xml);
doc.Print();
}
#if 1
// the question being explored is what kind of print to use:
// https://github.com/leethomason/tinyxml2/issues/63
{
//const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9' attrC='1.0e-10' attrD='1001000000.000000' attrE='0.1234567890123456789'/>";
const char* xml = "<element/>";
XMLDocument doc;
doc.Parse( xml );
doc.FirstChildElement()->SetAttribute( "attrA-f64", 123456789.123456789 );
doc.FirstChildElement()->SetAttribute( "attrB-f64", 1.001e9 );
doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e9 );
doc.FirstChildElement()->SetAttribute( "attrC-f64", 1.0e20 );
doc.FirstChildElement()->SetAttribute( "attrD-f64", 1.0e-10 );
doc.FirstChildElement()->SetAttribute( "attrD-f64", 0.123456789 );
doc.FirstChildElement()->SetAttribute( "attrA-f32", 123456789.123456789f );
doc.FirstChildElement()->SetAttribute( "attrB-f32", 1.001e9f );
doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e9f );
doc.FirstChildElement()->SetAttribute( "attrC-f32", 1.0e20f );
doc.FirstChildElement()->SetAttribute( "attrD-f32", 1.0e-10f );
doc.FirstChildElement()->SetAttribute( "attrD-f32", 0.123456789f );
doc.Print();
/* The result of this test is platform, compiler, and library version dependent. :("
XMLPrinter printer;
doc.Print( &printer );
XMLTest( "Float and double formatting.",
"<element attrA-f64=\"123456789.12345679\" attrB-f64=\"1001000000\" attrC-f64=\"1e+20\" attrD-f64=\"0.123456789\" attrA-f32=\"1.2345679e+08\" attrB-f32=\"1.001e+09\" attrC-f32=\"1e+20\" attrD-f32=\"0.12345679\"/>\n",
printer.CStr(),
true );
*/
}
#endif
// ----------- Performance tracking --------------
{
#if defined( _MSC_VER )