summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2009-06-01 08:48:42 (GMT)
committerRemko Tronçon <git@el-tramo.be>2009-06-01 09:24:28 (GMT)
commit2812bddd81f8a1b804c7460f4e14cd0aa393d129 (patch)
treed46294f35150c4f0f43deaf2d31fceaf945ae715 /3rdParty/CppUnit/src
downloadswift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.zip
swift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.tar.bz2
Import.
Diffstat (limited to '3rdParty/CppUnit/src')
-rw-r--r--3rdParty/CppUnit/src/AdditionalMessage.cpp41
-rw-r--r--3rdParty/CppUnit/src/Asserter.cpp101
-rw-r--r--3rdParty/CppUnit/src/DefaultProtector.cpp42
-rw-r--r--3rdParty/CppUnit/src/DefaultProtector.h27
-rw-r--r--3rdParty/CppUnit/src/Exception.cpp126
-rw-r--r--3rdParty/CppUnit/src/Message.cpp170
-rw-r--r--3rdParty/CppUnit/src/Protector.cpp86
-rw-r--r--3rdParty/CppUnit/src/ProtectorChain.cpp86
-rw-r--r--3rdParty/CppUnit/src/ProtectorChain.h51
-rw-r--r--3rdParty/CppUnit/src/ProtectorContext.h38
-rw-r--r--3rdParty/CppUnit/src/SourceLine.cpp81
-rw-r--r--3rdParty/CppUnit/src/StringTools.cpp80
-rw-r--r--3rdParty/CppUnit/src/SynchronizedObject.cpp32
-rw-r--r--3rdParty/CppUnit/src/Test.cpp97
-rw-r--r--3rdParty/CppUnit/src/TestCase.cpp137
-rw-r--r--3rdParty/CppUnit/src/TestComposite.cpp77
-rw-r--r--3rdParty/CppUnit/src/TestFactoryRegistry.cpp161
-rw-r--r--3rdParty/CppUnit/src/TestFailure.cpp71
-rw-r--r--3rdParty/CppUnit/src/TestLeaf.cpp28
-rw-r--r--3rdParty/CppUnit/src/TestNamer.cpp44
-rw-r--r--3rdParty/CppUnit/src/TestPath.cpp254
-rw-r--r--3rdParty/CppUnit/src/TestResult.cpp196
-rw-r--r--3rdParty/CppUnit/src/TestResultCollector.cpp117
-rw-r--r--3rdParty/CppUnit/src/TestRunner.cpp101
-rw-r--r--3rdParty/CppUnit/src/TestSuccessListener.cpp44
-rw-r--r--3rdParty/CppUnit/src/TestSuite.cpp64
-rw-r--r--3rdParty/CppUnit/src/TestSuiteBuilderContext.cpp85
-rw-r--r--3rdParty/CppUnit/src/TextOutputter.cpp140
-rw-r--r--3rdParty/CppUnit/src/TextTestProgressListener.cpp43
-rw-r--r--3rdParty/CppUnit/src/TextTestRunner.cpp144
-rw-r--r--3rdParty/CppUnit/src/TypeInfoHelper.cpp54
-rw-r--r--3rdParty/CppUnit/src/XmlDocument.cpp106
-rw-r--r--3rdParty/CppUnit/src/XmlElement.cpp226
-rw-r--r--3rdParty/CppUnit/src/XmlOutputter.cpp205
34 files changed, 3355 insertions, 0 deletions
diff --git a/3rdParty/CppUnit/src/AdditionalMessage.cpp b/3rdParty/CppUnit/src/AdditionalMessage.cpp
new file mode 100644
index 0000000..9f3da13
--- /dev/null
+++ b/3rdParty/CppUnit/src/AdditionalMessage.cpp
@@ -0,0 +1,41 @@
+#include <cppunit/AdditionalMessage.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+AdditionalMessage::AdditionalMessage()
+{
+}
+
+
+AdditionalMessage::AdditionalMessage( const std::string &detail1 )
+{
+ if ( !detail1.empty() )
+ addDetail( detail1 );
+}
+
+
+AdditionalMessage::AdditionalMessage( const char *detail1 )
+{
+ if ( detail1 && !std::string( detail1 ).empty() )
+ addDetail( std::string(detail1) );
+}
+
+
+AdditionalMessage::AdditionalMessage( const Message &other )
+ : SuperClass( other )
+{
+}
+
+
+AdditionalMessage &
+AdditionalMessage::operator =( const Message &other )
+{
+ SuperClass::operator =( other );
+
+ return *this;
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/Asserter.cpp b/3rdParty/CppUnit/src/Asserter.cpp
new file mode 100644
index 0000000..a9cf95c
--- /dev/null
+++ b/3rdParty/CppUnit/src/Asserter.cpp
@@ -0,0 +1,101 @@
+#include <cppunit/Asserter.h>
+#include <cppunit/Exception.h>
+#include <cppunit/Message.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+void
+Asserter::fail( std::string message,
+ const SourceLine &sourceLine )
+{
+ fail( Message( "assertion failed", message ), sourceLine );
+}
+
+
+void
+Asserter::fail( const Message &message,
+ const SourceLine &sourceLine )
+{
+ throw Exception( message, sourceLine );
+}
+
+
+void
+Asserter::failIf( bool shouldFail,
+ const Message &message,
+ const SourceLine &sourceLine )
+{
+ if ( shouldFail )
+ fail( message, sourceLine );
+}
+
+
+void
+Asserter::failIf( bool shouldFail,
+ std::string message,
+ const SourceLine &sourceLine )
+{
+ failIf( shouldFail, Message( "assertion failed", message ), sourceLine );
+}
+
+
+std::string
+Asserter::makeExpected( const std::string &expectedValue )
+{
+ return "Expected: " + expectedValue;
+}
+
+
+std::string
+Asserter::makeActual( const std::string &actualValue )
+{
+ return "Actual : " + actualValue;
+}
+
+
+Message
+Asserter::makeNotEqualMessage( const std::string &expectedValue,
+ const std::string &actualValue,
+ const AdditionalMessage &additionalMessage,
+ const std::string &shortDescription )
+{
+ Message message( shortDescription,
+ makeExpected( expectedValue ),
+ makeActual( actualValue ) );
+ message.addDetail( additionalMessage );
+
+ return message;
+}
+
+
+void
+Asserter::failNotEqual( std::string expected,
+ std::string actual,
+ const SourceLine &sourceLine,
+ const AdditionalMessage &additionalMessage,
+ std::string shortDescription )
+{
+ fail( makeNotEqualMessage( expected,
+ actual,
+ additionalMessage,
+ shortDescription ),
+ sourceLine );
+}
+
+
+void
+Asserter::failNotEqualIf( bool shouldFail,
+ std::string expected,
+ std::string actual,
+ const SourceLine &sourceLine,
+ const AdditionalMessage &additionalMessage,
+ std::string shortDescription )
+{
+ if ( shouldFail )
+ failNotEqual( expected, actual, sourceLine, additionalMessage, shortDescription );
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/DefaultProtector.cpp b/3rdParty/CppUnit/src/DefaultProtector.cpp
new file mode 100644
index 0000000..6fb306b
--- /dev/null
+++ b/3rdParty/CppUnit/src/DefaultProtector.cpp
@@ -0,0 +1,42 @@
+#include <cppunit/Exception.h>
+#include <cppunit/extensions/TypeInfoHelper.h>
+#include "DefaultProtector.h"
+
+
+CPPUNIT_NS_BEGIN
+
+
+bool
+DefaultProtector::protect( const Functor &functor,
+ const ProtectorContext &context )
+{
+ try
+ {
+ return functor();
+ }
+ catch ( Exception &failure )
+ {
+ reportFailure( context, failure );
+ }
+ catch ( std::exception &e )
+ {
+ std::string shortDescription( "uncaught exception of type " );
+#if CPPUNIT_USE_TYPEINFO_NAME
+ shortDescription += TypeInfoHelper::getClassName( typeid(e) );
+#else
+ shortDescription += "std::exception (or derived).";
+#endif
+ Message message( shortDescription, e.what() );
+ reportError( context, message );
+ }
+ catch ( ... )
+ {
+ reportError( context,
+ Message( "uncaught exception of unknown type") );
+ }
+
+ return false;
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/DefaultProtector.h b/3rdParty/CppUnit/src/DefaultProtector.h
new file mode 100644
index 0000000..4a76ea0
--- /dev/null
+++ b/3rdParty/CppUnit/src/DefaultProtector.h
@@ -0,0 +1,27 @@
+#ifndef CPPUNIT_DEFAULTPROTECTOR_H
+#define CPPUNIT_DEFAULTPROTECTOR_H
+
+#include <cppunit/Protector.h>
+
+CPPUNIT_NS_BEGIN
+
+/*! \brief Default protector that catch all exceptions (Implementation).
+ *
+ * Implementation detail.
+ * \internal This protector catch and generate a failure for the following
+ * exception types:
+ * - Exception
+ * - std::exception
+ * - ...
+ */
+class DefaultProtector : public Protector
+{
+public:
+ bool protect( const Functor &functor,
+ const ProtectorContext &context );
+};
+
+CPPUNIT_NS_END
+
+#endif // CPPUNIT_DEFAULTPROTECTOR_H
+
diff --git a/3rdParty/CppUnit/src/Exception.cpp b/3rdParty/CppUnit/src/Exception.cpp
new file mode 100644
index 0000000..3bbe24b
--- /dev/null
+++ b/3rdParty/CppUnit/src/Exception.cpp
@@ -0,0 +1,126 @@
+#include <cppunit/Exception.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
+/*!
+ * \deprecated Use SourceLine::isValid() instead.
+ */
+const std::string Exception::UNKNOWNFILENAME = "<unknown>";
+
+/*!
+ * \deprecated Use SourceLine::isValid() instead.
+ */
+const long Exception::UNKNOWNLINENUMBER = -1;
+#endif
+
+
+Exception::Exception( const Exception &other )
+ : std::exception( other )
+{
+ m_message = other.m_message;
+ m_sourceLine = other.m_sourceLine;
+}
+
+
+Exception::Exception( const Message &message,
+ const SourceLine &sourceLine )
+ : m_message( message )
+ , m_sourceLine( sourceLine )
+{
+}
+
+
+#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
+Exception::Exception( std::string message,
+ long lineNumber,
+ std::string fileName )
+ : m_message( message )
+ , m_sourceLine( fileName, lineNumber )
+{
+}
+#endif
+
+
+Exception::~Exception() throw()
+{
+}
+
+
+Exception &
+Exception::operator =( const Exception& other )
+{
+// Don't call superclass operator =(). VC++ STL implementation
+// has a bug. It calls the destructor and copy constructor of
+// std::exception() which reset the virtual table to std::exception.
+// SuperClass::operator =(other);
+
+ if ( &other != this )
+ {
+ m_message = other.m_message;
+ m_sourceLine = other.m_sourceLine;
+ }
+
+ return *this;
+}
+
+
+const char*
+Exception::what() const throw()
+{
+ Exception *mutableThis = CPPUNIT_CONST_CAST( Exception *, this );
+ mutableThis->m_whatMessage = m_message.shortDescription() + "\n" +
+ m_message.details();
+ return m_whatMessage.c_str();
+}
+
+
+SourceLine
+Exception::sourceLine() const
+{
+ return m_sourceLine;
+}
+
+
+Message
+Exception::message() const
+{
+ return m_message;
+}
+
+
+void
+Exception::setMessage( const Message &message )
+{
+ m_message = message;
+}
+
+
+#ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
+long
+Exception::lineNumber() const
+{
+ return m_sourceLine.isValid() ? m_sourceLine.lineNumber() :
+ UNKNOWNLINENUMBER;
+}
+
+
+std::string
+Exception::fileName() const
+{
+ return m_sourceLine.isValid() ? m_sourceLine.fileName() :
+ UNKNOWNFILENAME;
+}
+#endif
+
+
+Exception *
+Exception::clone() const
+{
+ return new Exception( *this );
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/Message.cpp b/3rdParty/CppUnit/src/Message.cpp
new file mode 100644
index 0000000..9d6a0e9
--- /dev/null
+++ b/3rdParty/CppUnit/src/Message.cpp
@@ -0,0 +1,170 @@
+#include <cppunit/Message.h>
+#include <stdexcept>
+
+
+CPPUNIT_NS_BEGIN
+
+
+Message::Message()
+{
+}
+
+Message::Message( const Message &other )
+{
+ *this = other;
+}
+
+
+Message::Message( const std::string &shortDescription )
+ : m_shortDescription( shortDescription )
+{
+}
+
+
+Message::Message( const std::string &shortDescription,
+ const std::string &detail1 )
+ : m_shortDescription( shortDescription )
+{
+ addDetail( detail1 );
+}
+
+
+Message::Message( const std::string &shortDescription,
+ const std::string &detail1,
+ const std::string &detail2 )
+ : m_shortDescription( shortDescription )
+{
+ addDetail( detail1, detail2 );
+}
+
+
+Message::Message( const std::string &shortDescription,
+ const std::string &detail1,
+ const std::string &detail2,
+ const std::string &detail3 )
+ : m_shortDescription( shortDescription )
+{
+ addDetail( detail1, detail2, detail3 );
+}
+
+Message &
+Message::operator =( const Message &other )
+{
+ if ( this != &other )
+ {
+ m_shortDescription = other.m_shortDescription.c_str();
+ m_details.clear();
+ Details::const_iterator it = other.m_details.begin();
+ Details::const_iterator itEnd = other.m_details.end();
+ while ( it != itEnd )
+ m_details.push_back( (*it++).c_str() );
+ }
+
+ return *this;
+}
+
+
+const std::string &
+Message::shortDescription() const
+{
+ return m_shortDescription;
+}
+
+
+int
+Message::detailCount() const
+{
+ return m_details.size();
+}
+
+
+std::string
+Message::detailAt( int index ) const
+{
+ if ( index < 0 || index >= detailCount() )
+ throw std::invalid_argument( "Message::detailAt() : invalid index" );
+
+ return m_details[ index ];
+}
+
+
+std::string
+Message::details() const
+{
+ std::string details;
+ for ( Details::const_iterator it = m_details.begin(); it != m_details.end(); ++it )
+ {
+ details += "- ";
+ details += *it;
+ details += '\n';
+ }
+ return details;
+}
+
+
+void
+Message::clearDetails()
+{
+ m_details.clear();
+}
+
+
+void
+Message::addDetail( const std::string &detail )
+{
+ m_details.push_back( detail );
+}
+
+
+void
+Message::addDetail( const std::string &detail1,
+ const std::string &detail2 )
+{
+ addDetail( detail1 );
+ addDetail( detail2 );
+}
+
+
+void
+Message::addDetail( const std::string &detail1,
+ const std::string &detail2,
+ const std::string &detail3 )
+{
+ addDetail( detail1, detail2 );
+ addDetail( detail3 );
+}
+
+
+void
+Message::addDetail( const Message &message )
+{
+ m_details.insert( m_details.end(),
+ message.m_details.begin(),
+ message.m_details.end() );
+}
+
+
+void
+Message::setShortDescription( const std::string &shortDescription )
+{
+ m_shortDescription = shortDescription;
+}
+
+
+bool
+Message::operator ==( const Message &other ) const
+{
+ return m_shortDescription == other.m_shortDescription &&
+ m_details == other.m_details;
+}
+
+
+bool
+Message::operator !=( const Message &other ) const
+{
+ return !( *this == other );
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/Protector.cpp b/3rdParty/CppUnit/src/Protector.cpp
new file mode 100644
index 0000000..5c171ec
--- /dev/null
+++ b/3rdParty/CppUnit/src/Protector.cpp
@@ -0,0 +1,86 @@
+#include <cppunit/Exception.h>
+#include <cppunit/Message.h>
+#include <cppunit/Protector.h>
+#include <cppunit/TestResult.h>
+#include "ProtectorContext.h"
+#include <memory>
+
+CPPUNIT_NS_BEGIN
+
+Functor::~Functor()
+{
+}
+
+
+Protector::~Protector()
+{
+}
+
+
+void
+Protector::reportError( const ProtectorContext &context,
+ const Exception &error ) const
+{
+ std::auto_ptr<Exception> actualError( error.clone() );
+ actualError->setMessage( actualMessage( actualError->message(), context ) );
+ context.m_result->addError( context.m_test,
+ actualError.release() );
+}
+
+
+
+void
+Protector::reportError( const ProtectorContext &context,
+ const Message &message,
+ const SourceLine &sourceLine ) const
+{
+ reportError( context, Exception( message, sourceLine ) );
+}
+
+
+void
+Protector::reportFailure( const ProtectorContext &context,
+ const Exception &failure ) const
+{
+ std::auto_ptr<Exception> actualFailure( failure.clone() );
+ actualFailure->setMessage( actualMessage( actualFailure->message(), context ) );
+ context.m_result->addFailure( context.m_test,
+ actualFailure.release() );
+}
+
+
+Message
+Protector::actualMessage( const Message &message,
+ const ProtectorContext &context ) const
+{
+ Message theActualMessage;
+ if ( context.m_shortDescription.empty() )
+ theActualMessage = message;
+ else
+ {
+ theActualMessage = Message( context.m_shortDescription,
+ message.shortDescription() );
+ theActualMessage.addDetail( message );
+ }
+
+ return theActualMessage;
+}
+
+
+
+
+ProtectorGuard::ProtectorGuard( TestResult *result,
+ Protector *protector )
+ : m_result( result )
+{
+ m_result->pushProtector( protector );
+}
+
+
+ProtectorGuard::~ProtectorGuard()
+{
+ m_result->popProtector();
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/ProtectorChain.cpp b/3rdParty/CppUnit/src/ProtectorChain.cpp
new file mode 100644
index 0000000..f528341
--- /dev/null
+++ b/3rdParty/CppUnit/src/ProtectorChain.cpp
@@ -0,0 +1,86 @@
+#include "ProtectorChain.h"
+
+CPPUNIT_NS_BEGIN
+
+
+class ProtectorChain::ProtectFunctor : public Functor
+{
+public:
+ ProtectFunctor( Protector *protector,
+ const Functor &functor,
+ const ProtectorContext &context )
+ : m_protector( protector )
+ , m_functor( functor )
+ , m_context( context )
+ {
+ }
+
+ bool operator()() const
+ {
+ return m_protector->protect( m_functor, m_context );
+ }
+
+private:
+ Protector *m_protector;
+ const Functor &m_functor;
+ const ProtectorContext &m_context;
+};
+
+
+ProtectorChain::~ProtectorChain()
+{
+ while ( count() > 0 )
+ pop();
+}
+
+
+void
+ProtectorChain::push( Protector *protector )
+{
+ m_protectors.push_back( protector );
+}
+
+
+void
+ProtectorChain::pop()
+{
+ delete m_protectors.back();
+ m_protectors.pop_back();
+}
+
+int
+ProtectorChain::count() const
+{
+ return m_protectors.size();
+}
+
+
+bool
+ProtectorChain::protect( const Functor &functor,
+ const ProtectorContext &context )
+{
+ if ( m_protectors.empty() )
+ return functor();
+
+ Functors functors;
+ for ( int index = m_protectors.size()-1; index >= 0; --index )
+ {
+ const Functor &protectedFunctor =
+ functors.empty() ? functor : *functors.back();
+
+ functors.push_back( new ProtectFunctor( m_protectors[index],
+ protectedFunctor,
+ context ) );
+ }
+
+ const Functor &outermostFunctor = *functors.back();
+ bool succeed = outermostFunctor();
+
+ for ( unsigned int deletingIndex = 0; deletingIndex < m_protectors.size(); ++deletingIndex )
+ delete functors[deletingIndex];
+
+ return succeed;
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/ProtectorChain.h b/3rdParty/CppUnit/src/ProtectorChain.h
new file mode 100644
index 0000000..711b56f
--- /dev/null
+++ b/3rdParty/CppUnit/src/ProtectorChain.h
@@ -0,0 +1,51 @@
+#ifndef CPPUNIT_PROTECTORCHAIN_H
+#define CPPUNIT_PROTECTORCHAIN_H
+
+#include <cppunit/Protector.h>
+#include <cppunit/portability/CppUnitDeque.h>
+
+#if CPPUNIT_NEED_DLL_DECL
+#pragma warning( push )
+#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z
+#endif
+
+
+CPPUNIT_NS_BEGIN
+
+/*! \brief Protector chain (Implementation).
+ * Implementation detail.
+ * \internal Protector that protect a Functor using a chain of nested Protector.
+ */
+class CPPUNIT_API ProtectorChain : public Protector
+{
+public:
+ ~ProtectorChain();
+
+ void push( Protector *protector );
+
+ void pop();
+
+ int count() const;
+
+ bool protect( const Functor &functor,
+ const ProtectorContext &context );
+
+private:
+ class ProtectFunctor;
+
+private:
+ typedef CppUnitDeque<Protector *> Protectors;
+ Protectors m_protectors;
+
+ typedef CppUnitDeque<Functor *> Functors;
+};
+
+
+CPPUNIT_NS_END
+
+#if CPPUNIT_NEED_DLL_DECL
+#pragma warning( pop )
+#endif
+
+#endif // CPPUNIT_PROTECTORCHAIN_H
+
diff --git a/3rdParty/CppUnit/src/ProtectorContext.h b/3rdParty/CppUnit/src/ProtectorContext.h
new file mode 100644
index 0000000..c3d496c
--- /dev/null
+++ b/3rdParty/CppUnit/src/ProtectorContext.h
@@ -0,0 +1,38 @@
+#ifndef CPPUNIT_PROTECTORCONTEXT_H
+#define CPPUNIT_PROTECTORCONTEXT_H
+
+#include <cppunit/Portability.h>
+#include <string>
+
+CPPUNIT_NS_BEGIN
+
+class Test;
+class TestResult;
+
+
+/*! \brief Protector context (Implementation).
+ * Implementation detail.
+ * \internal Context use to report failure in Protector.
+ */
+class CPPUNIT_API ProtectorContext
+{
+public:
+ ProtectorContext( Test *test,
+ TestResult *result,
+ const std::string &shortDescription )
+ : m_test( test )
+ , m_result( result )
+ , m_shortDescription( shortDescription )
+ {
+ }
+
+ Test *m_test;
+ TestResult *m_result;
+ std::string m_shortDescription;
+};
+
+
+CPPUNIT_NS_END
+
+#endif // CPPUNIT_PROTECTORCONTEXT_H
+
diff --git a/3rdParty/CppUnit/src/SourceLine.cpp b/3rdParty/CppUnit/src/SourceLine.cpp
new file mode 100644
index 0000000..dfadae3
--- /dev/null
+++ b/3rdParty/CppUnit/src/SourceLine.cpp
@@ -0,0 +1,81 @@
+#include <cppunit/SourceLine.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+SourceLine::SourceLine() :
+ m_lineNumber( -1 )
+{
+}
+
+
+SourceLine::SourceLine( const SourceLine &other )
+ : m_fileName( other.m_fileName.c_str() )
+ , m_lineNumber( other.m_lineNumber )
+{
+}
+
+
+SourceLine::SourceLine( const std::string &fileName,
+ int lineNumber )
+ : m_fileName( fileName.c_str() )
+ , m_lineNumber( lineNumber )
+{
+}
+
+
+SourceLine &
+SourceLine::operator =( const SourceLine &other )
+{
+ if ( this != &other )
+ {
+ m_fileName = other.m_fileName.c_str();
+ m_lineNumber = other.m_lineNumber;
+ }
+ return *this;
+}
+
+
+SourceLine::~SourceLine()
+{
+}
+
+
+bool
+SourceLine::isValid() const
+{
+ return !m_fileName.empty();
+}
+
+
+int
+SourceLine::lineNumber() const
+{
+ return m_lineNumber;
+}
+
+
+std::string
+SourceLine::fileName() const
+{
+ return m_fileName;
+}
+
+
+bool
+SourceLine::operator ==( const SourceLine &other ) const
+{
+ return m_fileName == other.m_fileName &&
+ m_lineNumber == other.m_lineNumber;
+}
+
+
+bool
+SourceLine::operator !=( const SourceLine &other ) const
+{
+ return !( *this == other );
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/StringTools.cpp b/3rdParty/CppUnit/src/StringTools.cpp
new file mode 100644
index 0000000..dc995d8
--- /dev/null
+++ b/3rdParty/CppUnit/src/StringTools.cpp
@@ -0,0 +1,80 @@
+#include <cppunit/tools/StringTools.h>
+#include <cppunit/portability/Stream.h>
+#include <algorithm>
+
+
+CPPUNIT_NS_BEGIN
+
+
+std::string
+StringTools::toString( int value )
+{
+ OStringStream stream;
+ stream << value;
+ return stream.str();
+}
+
+
+std::string
+StringTools::toString( double value )
+{
+ OStringStream stream;
+ stream << value;
+ return stream.str();
+}
+
+
+StringTools::Strings
+StringTools::split( const std::string &text,
+ char separator )
+{
+ Strings splittedText;
+
+ std::string::const_iterator itStart = text.begin();
+ while ( !text.empty() )
+ {
+ std::string::const_iterator itSeparator = std::find( itStart,
+ text.end(),
+ separator );
+ splittedText.push_back( text.substr( itStart - text.begin(),
+ itSeparator - itStart ) );
+ if ( itSeparator == text.end() )
+ break;
+ itStart = itSeparator +1;
+ }
+
+ return splittedText;
+}
+
+
+std::string
+StringTools::wrap( const std::string &text,
+ int wrapColumn )
+{
+ const char lineBreak = '\n';
+ Strings lines = split( text, lineBreak );
+
+ std::string wrapped;
+ for ( Strings::const_iterator it = lines.begin(); it != lines.end(); ++it )
+ {
+ if ( it != lines.begin() )
+ wrapped += lineBreak;
+
+ const std::string &line = *it;
+ unsigned int index =0;
+ while ( index < line.length() )
+ {
+ std::string lineSlice( line.substr( index, wrapColumn ) );
+ wrapped += lineSlice;
+ index += wrapColumn;
+ if ( index < line.length() )
+ wrapped += lineBreak;
+ }
+ }
+
+ return wrapped;
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/SynchronizedObject.cpp b/3rdParty/CppUnit/src/SynchronizedObject.cpp
new file mode 100644
index 0000000..1764538
--- /dev/null
+++ b/3rdParty/CppUnit/src/SynchronizedObject.cpp
@@ -0,0 +1,32 @@
+#include <cppunit/SynchronizedObject.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+SynchronizedObject::SynchronizedObject( SynchronizationObject *syncObject )
+ : m_syncObject( syncObject == 0 ? new SynchronizationObject() :
+ syncObject )
+{
+}
+
+
+SynchronizedObject::~SynchronizedObject()
+{
+ delete m_syncObject;
+}
+
+
+/** Accept a new synchronization object for protection of this instance
+ * TestResult assumes ownership of the object
+ */
+void
+SynchronizedObject::setSynchronizationObject( SynchronizationObject *syncObject )
+{
+ delete m_syncObject;
+ m_syncObject = syncObject;
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/Test.cpp b/3rdParty/CppUnit/src/Test.cpp
new file mode 100644
index 0000000..fef8be7
--- /dev/null
+++ b/3rdParty/CppUnit/src/Test.cpp
@@ -0,0 +1,97 @@
+#include <cppunit/Portability.h>
+#include <cppunit/Test.h>
+#include <cppunit/TestPath.h>
+#include <stdexcept>
+
+
+CPPUNIT_NS_BEGIN
+
+
+Test *
+Test::getChildTestAt( int index ) const
+{
+ checkIsValidIndex( index );
+ return doGetChildTestAt( index );
+}
+
+
+Test *
+Test::findTest( const std::string &testName ) const
+{
+ TestPath path;
+ Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this );
+ mutableThis->findTestPath( testName, path );
+ if ( !path.isValid() )
+ throw std::invalid_argument( "No test named <" + testName + "> found in test <"
+ + getName() + ">." );
+ return path.getChildTest();
+}
+
+
+bool
+Test::findTestPath( const std::string &testName,
+ TestPath &testPath ) const
+{
+ Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this );
+ if ( getName() == testName )
+ {
+ testPath.add( mutableThis );
+ return true;
+ }
+
+ int childCount = getChildTestCount();
+ for ( int childIndex =0; childIndex < childCount; ++childIndex )
+ {
+ if ( getChildTestAt( childIndex )->findTestPath( testName, testPath ) )
+ {
+ testPath.insert( mutableThis, 0 );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+bool
+Test::findTestPath( const Test *test,
+ TestPath &testPath ) const
+{
+ Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this );
+ if ( this == test )
+ {
+ testPath.add( mutableThis );
+ return true;
+ }
+
+ int childCount = getChildTestCount();
+ for ( int childIndex =0; childIndex < childCount; ++childIndex )
+ {
+ if ( getChildTestAt( childIndex )->findTestPath( test, testPath ) )
+ {
+ testPath.insert( mutableThis, 0 );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+TestPath
+Test::resolveTestPath( const std::string &testPath ) const
+{
+ Test *mutableThis = CPPUNIT_CONST_CAST( Test *, this );
+ return TestPath( mutableThis, testPath );
+}
+
+
+void
+Test::checkIsValidIndex( int index ) const
+{
+ if ( index < 0 || index >= getChildTestCount() )
+ throw std::out_of_range( "Test::checkValidIndex(): invalid index" );
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestCase.cpp b/3rdParty/CppUnit/src/TestCase.cpp
new file mode 100644
index 0000000..13c0525
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestCase.cpp
@@ -0,0 +1,137 @@
+#include <cppunit/Portability.h>
+#include <cppunit/Exception.h>
+#include <cppunit/Protector.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/TestResult.h>
+#include <stdexcept>
+
+#if CPPUNIT_USE_TYPEINFO_NAME
+# include <typeinfo>
+#endif
+
+CPPUNIT_NS_BEGIN
+
+/*! \brief Functor to call test case method (Implementation).
+ *
+ * Implementation detail.
+ */
+class TestCaseMethodFunctor : public Functor
+{
+public:
+ typedef void (TestCase::*Method)();
+
+ TestCaseMethodFunctor( TestCase *target,
+ Method method )
+ : m_target( target )
+ , m_method( method )
+ {
+ }
+
+ bool operator()() const
+ {
+ (m_target->*m_method)();
+ return true;
+ }
+
+private:
+ TestCase *m_target;
+ Method m_method;
+};
+
+
+/** Constructs a test case.
+ * \param name the name of the TestCase.
+ **/
+TestCase::TestCase( const std::string &name )
+ : m_name(name)
+{
+}
+
+
+/// Run the test and catch any exceptions that are triggered by it
+void
+TestCase::run( TestResult *result )
+{
+ result->startTest(this);
+/*
+ try {
+ setUp();
+
+ try {
+ runTest();
+ }
+ catch ( Exception &e ) {
+ Exception *copy = e.clone();
+ result->addFailure( this, copy );
+ }
+ catch ( std::exception &e ) {
+ result->addError( this, new Exception( Message( "uncaught std::exception",
+ e.what() ) ) );
+ }
+ catch (...) {
+ Exception *e = new Exception( Message( "uncaught unknown exception" ) );
+ result->addError( this, e );
+ }
+
+ try {
+ tearDown();
+ }
+ catch (...) {
+ result->addError( this, new Exception( Message( "tearDown() failed" ) ) );
+ }
+ }
+ catch (...) {
+ result->addError( this, new Exception( Message( "setUp() failed" ) ) );
+ }
+*/
+ if ( result->protect( TestCaseMethodFunctor( this, &TestCase::setUp ),
+ this,
+ "setUp() failed" ) )
+ {
+ result->protect( TestCaseMethodFunctor( this, &TestCase::runTest ),
+ this );
+ }
+
+ result->protect( TestCaseMethodFunctor( this, &TestCase::tearDown ),
+ this,
+ "tearDown() failed" );
+
+ result->endTest( this );
+}
+
+
+/// All the work for runTest is deferred to subclasses
+void
+TestCase::runTest()
+{
+}
+
+
+/** Constructs a test case for a suite.
+ * \deprecated This constructor was used by fixture when TestFixture did not exist.
+ * Have your fixture inherits TestFixture instead of TestCase.
+ * \internal
+ * This TestCase was intended for use by the TestCaller and should not
+ * be used by a test case for which run() is called.
+ **/
+TestCase::TestCase()
+ : m_name( "" )
+{
+}
+
+
+/// Destructs a test case
+TestCase::~TestCase()
+{
+}
+
+
+/// Returns the name of the test case
+std::string
+TestCase::getName() const
+{
+ return m_name;
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestComposite.cpp b/3rdParty/CppUnit/src/TestComposite.cpp
new file mode 100644
index 0000000..4768791
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestComposite.cpp
@@ -0,0 +1,77 @@
+#include <cppunit/TestComposite.h>
+#include <cppunit/TestResult.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TestComposite::TestComposite( const std::string &name )
+ : m_name( name )
+{
+}
+
+
+TestComposite::~TestComposite()
+{
+}
+
+
+void
+TestComposite::run( TestResult *result )
+{
+ doStartSuite( result );
+ doRunChildTests( result );
+ doEndSuite( result );
+}
+
+
+int
+TestComposite::countTestCases() const
+{
+ int count = 0;
+
+ int childCount = getChildTestCount();
+ for ( int index =0; index < childCount; ++index )
+ count += getChildTestAt( index )->countTestCases();
+
+ return count;
+}
+
+
+std::string
+TestComposite::getName() const
+{
+ return m_name;
+}
+
+
+void
+TestComposite::doStartSuite( TestResult *controller )
+{
+ controller->startSuite( this );
+}
+
+
+void
+TestComposite::doRunChildTests( TestResult *controller )
+{
+ int childCount = getChildTestCount();
+ for ( int index =0; index < childCount; ++index )
+ {
+ if ( controller->shouldStop() )
+ break;
+
+ getChildTestAt( index )->run( controller );
+ }
+}
+
+
+void
+TestComposite::doEndSuite( TestResult *controller )
+{
+ controller->endSuite( this );
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TestFactoryRegistry.cpp b/3rdParty/CppUnit/src/TestFactoryRegistry.cpp
new file mode 100644
index 0000000..3457da3
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestFactoryRegistry.cpp
@@ -0,0 +1,161 @@
+#include <cppunit/config/SourcePrefix.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/portability/CppUnitMap.h>
+#include <cppunit/TestSuite.h>
+#include <assert.h>
+
+
+CPPUNIT_NS_BEGIN
+
+/*! \brief (INTERNAL) List of all TestFactoryRegistry.
+ */
+class TestFactoryRegistryList
+{
+private:
+ typedef CppUnitMap<std::string, TestFactoryRegistry *, std::less<std::string> > Registries;
+ Registries m_registries;
+
+ enum State {
+ doNotChange =0,
+ notCreated,
+ exist,
+ destroyed
+ };
+
+ static State stateFlag( State newState = doNotChange )
+ {
+ static State state = notCreated;
+ if ( newState != doNotChange )
+ state = newState;
+ return state;
+ }
+
+ static TestFactoryRegistryList *getInstance()
+ {
+ static TestFactoryRegistryList list;
+ return &list;
+ }
+
+ TestFactoryRegistry *getInternalRegistry( const std::string &name )
+ {
+ Registries::const_iterator foundIt = m_registries.find( name );
+ if ( foundIt == m_registries.end() )
+ {
+ TestFactoryRegistry *factory = new TestFactoryRegistry( name );
+ m_registries.insert( std::pair<const std::string, TestFactoryRegistry*>( name, factory ) );
+ return factory;
+ }
+ return (*foundIt).second;
+ }
+
+public:
+ TestFactoryRegistryList()
+ {
+ stateFlag( exist );
+ }
+
+ ~TestFactoryRegistryList()
+ {
+ for ( Registries::iterator it = m_registries.begin(); it != m_registries.end(); ++it )
+ delete (*it).second;
+
+ stateFlag( destroyed );
+ }
+
+ static TestFactoryRegistry *getRegistry( const std::string &name )
+ {
+ // If the following assertion failed, then TestFactoryRegistry::getRegistry()
+ // was called during static variable destruction without checking the registry
+ // validity beforehand using TestFactoryRegistry::isValid() beforehand.
+ assert( isValid() );
+ if ( !isValid() ) // release mode
+ return NULL; // => force CRASH
+
+ return getInstance()->getInternalRegistry( name );
+ }
+
+ static bool isValid()
+ {
+ return stateFlag() != destroyed;
+ }
+};
+
+
+
+TestFactoryRegistry::TestFactoryRegistry( std::string name ) :
+ m_name( name )
+{
+}
+
+
+TestFactoryRegistry::~TestFactoryRegistry()
+{
+}
+
+
+TestFactoryRegistry &
+TestFactoryRegistry::getRegistry( const std::string &name )
+{
+ return *TestFactoryRegistryList::getRegistry( name );
+}
+
+
+void
+TestFactoryRegistry::registerFactory( const std::string &,
+ TestFactory *factory )
+{
+ registerFactory( factory );
+}
+
+
+void
+TestFactoryRegistry::registerFactory( TestFactory *factory )
+{
+ m_factories.insert( factory );
+}
+
+
+void
+TestFactoryRegistry::unregisterFactory( TestFactory *factory )
+{
+ m_factories.erase( factory );
+}
+
+
+void
+TestFactoryRegistry::addRegistry( const std::string &name )
+{
+ registerFactory( &getRegistry( name ) );
+}
+
+
+Test *
+TestFactoryRegistry::makeTest()
+{
+ TestSuite *suite = new TestSuite( m_name );
+ addTestToSuite( suite );
+ return suite;
+}
+
+
+void
+TestFactoryRegistry::addTestToSuite( TestSuite *suite )
+{
+ for ( Factories::iterator it = m_factories.begin();
+ it != m_factories.end();
+ ++it )
+ {
+ TestFactory *factory = *it;
+ suite->addTest( factory->makeTest() );
+ }
+}
+
+
+bool
+TestFactoryRegistry::isValid()
+{
+ return TestFactoryRegistryList::isValid();
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestFailure.cpp b/3rdParty/CppUnit/src/TestFailure.cpp
new file mode 100644
index 0000000..e31e138
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestFailure.cpp
@@ -0,0 +1,71 @@
+#include <cppunit/Exception.h>
+#include <cppunit/Test.h>
+#include <cppunit/TestFailure.h>
+
+CPPUNIT_NS_BEGIN
+
+
+/// Constructs a TestFailure with the given test and exception.
+TestFailure::TestFailure( Test *failedTest,
+ Exception *thrownException,
+ bool isError ) :
+ m_failedTest( failedTest ),
+ m_thrownException( thrownException ),
+ m_isError( isError )
+{
+}
+
+/// Deletes the owned exception.
+TestFailure::~TestFailure()
+{
+ delete m_thrownException;
+}
+
+/// Gets the failed test.
+Test *
+TestFailure::failedTest() const
+{
+ return m_failedTest;
+}
+
+
+/// Gets the thrown exception. Never \c NULL.
+Exception *
+TestFailure::thrownException() const
+{
+ return m_thrownException;
+}
+
+
+/// Gets the failure location.
+SourceLine
+TestFailure::sourceLine() const
+{
+ return m_thrownException->sourceLine();
+}
+
+
+/// Indicates if the failure is a failed assertion or an error.
+bool
+TestFailure::isError() const
+{
+ return m_isError;
+}
+
+
+/// Gets the name of the failed test.
+std::string
+TestFailure::failedTestName() const
+{
+ return m_failedTest->getName();
+}
+
+
+TestFailure *
+TestFailure::clone() const
+{
+ return new TestFailure( m_failedTest, m_thrownException->clone(), m_isError );
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestLeaf.cpp b/3rdParty/CppUnit/src/TestLeaf.cpp
new file mode 100644
index 0000000..3d8767c
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestLeaf.cpp
@@ -0,0 +1,28 @@
+#include <cppunit/TestLeaf.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+int
+TestLeaf::countTestCases() const
+{
+ return 1;
+}
+
+
+int
+TestLeaf::getChildTestCount() const
+{
+ return 0;
+}
+
+
+Test *
+TestLeaf::doGetChildTestAt( int index ) const
+{
+ checkIsValidIndex( index );
+ return NULL; // never called, checkIsValidIndex() always throw.
+}
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestNamer.cpp b/3rdParty/CppUnit/src/TestNamer.cpp
new file mode 100644
index 0000000..eec9be9
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestNamer.cpp
@@ -0,0 +1,44 @@
+#include <cppunit/extensions/TestNamer.h>
+#include <cppunit/extensions/TypeInfoHelper.h>
+#include <string>
+
+
+CPPUNIT_NS_BEGIN
+
+
+#if CPPUNIT_HAVE_RTTI
+TestNamer::TestNamer( const std::type_info &typeInfo )
+{
+ m_fixtureName = TypeInfoHelper::getClassName( typeInfo );
+}
+#endif
+
+
+TestNamer::TestNamer( const std::string &fixtureName )
+ : m_fixtureName( fixtureName )
+{
+}
+
+
+TestNamer::~TestNamer()
+{
+}
+
+
+std::string
+TestNamer::getFixtureName() const
+{
+ return m_fixtureName;
+}
+
+
+std::string
+TestNamer::getTestNameFor( const std::string &testMethodName ) const
+{
+ return getFixtureName() + "::" + testMethodName;
+}
+
+
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestPath.cpp b/3rdParty/CppUnit/src/TestPath.cpp
new file mode 100644
index 0000000..a2783a2
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestPath.cpp
@@ -0,0 +1,254 @@
+#include <cppunit/Portability.h>
+#include <cppunit/Test.h>
+#include <cppunit/TestPath.h>
+#include <stdexcept>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TestPath::TestPath()
+{
+}
+
+
+TestPath::TestPath( Test *root )
+{
+ add( root );
+}
+
+
+TestPath::TestPath( const TestPath &other,
+ int indexFirst,
+ int count )
+{
+ int countAdjustment = 0;
+ if ( indexFirst < 0 )
+ {
+ countAdjustment = indexFirst;
+ indexFirst = 0;
+ }
+
+ if ( count < 0 )
+ count = other.getTestCount();
+ else
+ count += countAdjustment;
+
+ int index = indexFirst;
+ while ( count-- > 0 && index < other.getTestCount() )
+ add( other.getTestAt( index++ ) );
+}
+
+
+TestPath::TestPath( Test *searchRoot,
+ const std::string &pathAsString )
+{
+ PathTestNames testNames;
+
+ Test *parentTest = findActualRoot( searchRoot, pathAsString, testNames );
+ add( parentTest );
+
+ for ( unsigned int index = 1; index < testNames.size(); ++index )
+ {
+ bool childFound = false;
+ for ( int childIndex =0; childIndex < parentTest->getChildTestCount(); ++childIndex )
+ {
+ if ( parentTest->getChildTestAt( childIndex )->getName() == testNames[index] )
+ {
+ childFound = true;
+ parentTest = parentTest->getChildTestAt( childIndex );
+ break;
+ }
+ }
+
+ if ( !childFound )
+ throw std::invalid_argument( "TestPath::TestPath(): failed to resolve test name <"+
+ testNames[index] + "> of path <" + pathAsString + ">" );
+
+ add( parentTest );
+ }
+}
+
+
+TestPath::TestPath( const TestPath &other )
+ : m_tests( other.m_tests )
+{
+}
+
+
+TestPath::~TestPath()
+{
+}
+
+
+TestPath &
+TestPath::operator =( const TestPath &other )
+{
+ if ( &other != this )
+ m_tests = other.m_tests;
+ return *this;
+}
+
+
+bool
+TestPath::isValid() const
+{
+ return getTestCount() > 0;
+}
+
+
+void
+TestPath::add( Test *test )
+{
+ m_tests.push_back( test );
+}
+
+
+void
+TestPath::add( const TestPath &path )
+{
+ for ( int index =0; index < path.getTestCount(); ++index )
+ add( path.getTestAt( index ) );
+}
+
+
+void
+TestPath::insert( Test *test,
+ int index )
+{
+ if ( index < 0 || index > getTestCount() )
+ throw std::out_of_range( "TestPath::insert(): index out of range" );
+ m_tests.insert( m_tests.begin() + index, test );
+}
+
+void
+TestPath::insert( const TestPath &path,
+ int index )
+{
+ int itemIndex = path.getTestCount() -1;
+ while ( itemIndex >= 0 )
+ insert( path.getTestAt( itemIndex-- ), index );
+}
+
+
+void
+TestPath::removeTests()
+{
+ while ( isValid() )
+ removeTest( 0 );
+}
+
+
+void
+TestPath::removeTest( int index )
+{
+ checkIndexValid( index );
+ m_tests.erase( m_tests.begin() + index );
+}
+
+
+void
+TestPath::up()
+{
+ checkIndexValid( 0 );
+ removeTest( getTestCount() -1 );
+}
+
+
+int
+TestPath::getTestCount() const
+{
+ return m_tests.size();
+}
+
+
+Test *
+TestPath::getTestAt( int index ) const
+{
+ checkIndexValid( index );
+ return m_tests[index];
+}
+
+
+Test *
+TestPath::getChildTest() const
+{
+ return getTestAt( getTestCount() -1 );
+}
+
+
+void
+TestPath::checkIndexValid( int index ) const
+{
+ if ( index < 0 || index >= getTestCount() )
+ throw std::out_of_range( "TestPath::checkIndexValid(): index out of range" );
+}
+
+
+std::string
+TestPath::toString() const
+{
+ std::string asString( "/" );
+ for ( int index =0; index < getTestCount(); ++index )
+ {
+ if ( index > 0 )
+ asString += '/';
+ asString += getTestAt(index)->getName();
+ }
+
+ return asString;
+}
+
+
+Test *
+TestPath::findActualRoot( Test *searchRoot,
+ const std::string &pathAsString,
+ PathTestNames &testNames )
+{
+ bool isRelative = splitPathString( pathAsString, testNames );
+
+ if ( isRelative && pathAsString.empty() )
+ return searchRoot;
+
+ if ( testNames.empty() )
+ throw std::invalid_argument( "TestPath::TestPath(): invalid root or root name in absolute path" );
+
+ Test *root = isRelative ? searchRoot->findTest( testNames[0] ) // throw if bad test name
+ : searchRoot;
+ if ( root->getName() != testNames[0] )
+ throw std::invalid_argument( "TestPath::TestPath(): searchRoot does not match path root name" );
+
+ return root;
+}
+
+
+bool
+TestPath::splitPathString( const std::string &pathAsString,
+ PathTestNames &testNames )
+{
+ if ( pathAsString.empty() )
+ return true;
+
+ bool isRelative = pathAsString[0] != '/';
+
+ int index = (isRelative ? 0 : 1);
+ while ( true )
+ {
+ int separatorIndex = pathAsString.find( '/', index );
+ if ( separatorIndex >= 0 )
+ {
+ testNames.push_back( pathAsString.substr( index, separatorIndex - index ) );
+ index = separatorIndex + 1;
+ }
+ else
+ {
+ testNames.push_back( pathAsString.substr( index ) );
+ break;
+ }
+ }
+
+ return isRelative;
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestResult.cpp b/3rdParty/CppUnit/src/TestResult.cpp
new file mode 100644
index 0000000..6be19f1
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestResult.cpp
@@ -0,0 +1,196 @@
+#include <cppunit/Test.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/TestListener.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/tools/Algorithm.h>
+#include <algorithm>
+#include "DefaultProtector.h"
+#include "ProtectorChain.h"
+#include "ProtectorContext.h"
+
+CPPUNIT_NS_BEGIN
+
+
+TestResult::TestResult( SynchronizationObject *syncObject )
+ : SynchronizedObject( syncObject )
+ , m_protectorChain( new ProtectorChain() )
+ , m_stop( false )
+{
+ m_protectorChain->push( new DefaultProtector() );
+}
+
+
+TestResult::~TestResult()
+{
+ delete m_protectorChain;
+}
+
+
+void
+TestResult::reset()
+{
+ ExclusiveZone zone( m_syncObject );
+ m_stop = false;
+}
+
+
+void
+TestResult::addError( Test *test,
+ Exception *e )
+{
+ TestFailure failure( test, e, true );
+ addFailure( failure );
+}
+
+
+void
+TestResult::addFailure( Test *test, Exception *e )
+{
+ TestFailure failure( test, e, false );
+ addFailure( failure );
+}
+
+
+void
+TestResult::addFailure( const TestFailure &failure )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->addFailure( failure );
+}
+
+
+void
+TestResult::startTest( Test *test )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->startTest( test );
+}
+
+
+void
+TestResult::endTest( Test *test )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->endTest( test );
+}
+
+
+void
+TestResult::startSuite( Test *test )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->startSuite( test );
+}
+
+
+void
+TestResult::endSuite( Test *test )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->endSuite( test );
+}
+
+
+bool
+TestResult::shouldStop() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_stop;
+}
+
+
+void
+TestResult::stop()
+{
+ ExclusiveZone zone( m_syncObject );
+ m_stop = true;
+}
+
+
+void
+TestResult::addListener( TestListener *listener )
+{
+ ExclusiveZone zone( m_syncObject );
+ m_listeners.push_back( listener );
+}
+
+
+void
+TestResult::removeListener ( TestListener *listener )
+{
+ ExclusiveZone zone( m_syncObject );
+ removeFromSequence( m_listeners, listener );
+}
+
+
+void
+TestResult::runTest( Test *test )
+{
+ startTestRun( test );
+ test->run( this );
+ endTestRun( test );
+}
+
+
+void
+TestResult::startTestRun( Test *test )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->startTestRun( test, this );
+}
+
+
+void
+TestResult::endTestRun( Test *test )
+{
+ ExclusiveZone zone( m_syncObject );
+ for ( TestListeners::iterator it = m_listeners.begin();
+ it != m_listeners.end();
+ ++it )
+ (*it)->endTestRun( test, this );
+}
+
+
+bool
+TestResult::protect( const Functor &functor,
+ Test *test,
+ const std::string &shortDescription )
+{
+ ProtectorContext context( test, this, shortDescription );
+ return m_protectorChain->protect( functor, context );
+}
+
+
+void
+TestResult::pushProtector( Protector *protector )
+{
+ m_protectorChain->push( protector );
+}
+
+
+void
+TestResult::popProtector()
+{
+ m_protectorChain->pop();
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TestResultCollector.cpp b/3rdParty/CppUnit/src/TestResultCollector.cpp
new file mode 100644
index 0000000..4371c50
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestResultCollector.cpp
@@ -0,0 +1,117 @@
+#include <cppunit/TestFailure.h>
+#include <cppunit/TestResultCollector.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TestResultCollector::TestResultCollector( SynchronizationObject *syncObject )
+ : TestSuccessListener( syncObject )
+{
+ reset();
+}
+
+
+TestResultCollector::~TestResultCollector()
+{
+ freeFailures();
+}
+
+
+void
+TestResultCollector::freeFailures()
+{
+ TestFailures::iterator itFailure = m_failures.begin();
+ while ( itFailure != m_failures.end() )
+ delete *itFailure++;
+ m_failures.clear();
+}
+
+
+void
+TestResultCollector::reset()
+{
+ TestSuccessListener::reset();
+
+ ExclusiveZone zone( m_syncObject );
+ freeFailures();
+ m_testErrors = 0;
+ m_tests.clear();
+}
+
+
+void
+TestResultCollector::startTest( Test *test )
+{
+ ExclusiveZone zone (m_syncObject);
+ m_tests.push_back( test );
+}
+
+
+void
+TestResultCollector::addFailure( const TestFailure &failure )
+{
+ TestSuccessListener::addFailure( failure );
+
+ ExclusiveZone zone( m_syncObject );
+ if ( failure.isError() )
+ ++m_testErrors;
+ m_failures.push_back( failure.clone() );
+}
+
+
+/// Gets the number of run tests.
+int
+TestResultCollector::runTests() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_tests.size();
+}
+
+
+/// Gets the number of detected errors (uncaught exception).
+int
+TestResultCollector::testErrors() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_testErrors;
+}
+
+
+/// Gets the number of detected failures (failed assertion).
+int
+TestResultCollector::testFailures() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_failures.size() - m_testErrors;
+}
+
+
+/// Gets the total number of detected failures.
+int
+TestResultCollector::testFailuresTotal() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_failures.size();
+}
+
+
+/// Returns a the list failures (random access collection).
+const TestResultCollector::TestFailures &
+TestResultCollector::failures() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_failures;
+}
+
+
+const TestResultCollector::Tests &
+TestResultCollector::tests() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_tests;
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TestRunner.cpp b/3rdParty/CppUnit/src/TestRunner.cpp
new file mode 100644
index 0000000..8d95a63
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestRunner.cpp
@@ -0,0 +1,101 @@
+#include <cppunit/config/SourcePrefix.h>
+#include <cppunit/TestRunner.h>
+#include <cppunit/TestPath.h>
+#include <cppunit/TestResult.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TestRunner::WrappingSuite::WrappingSuite( const std::string &name )
+ : TestSuite( name )
+{
+}
+
+
+int
+TestRunner::WrappingSuite::getChildTestCount() const
+{
+ if ( hasOnlyOneTest() )
+ return getUniqueChildTest()->getChildTestCount();
+ return TestSuite::getChildTestCount();
+}
+
+
+std::string
+TestRunner::WrappingSuite::getName() const
+{
+ if ( hasOnlyOneTest() )
+ return getUniqueChildTest()->getName();
+ return TestSuite::getName();
+}
+
+
+Test *
+TestRunner::WrappingSuite::doGetChildTestAt( int index ) const
+{
+ if ( hasOnlyOneTest() )
+ return getUniqueChildTest()->getChildTestAt( index );
+ return TestSuite::doGetChildTestAt( index );
+}
+
+
+void
+TestRunner::WrappingSuite::run( TestResult *result )
+{
+ if ( hasOnlyOneTest() )
+ getUniqueChildTest()->run( result );
+ else
+ TestSuite::run( result );
+}
+
+
+bool
+TestRunner::WrappingSuite::hasOnlyOneTest() const
+{
+ return TestSuite::getChildTestCount() == 1;
+}
+
+
+Test *
+TestRunner::WrappingSuite::getUniqueChildTest() const
+{
+ return TestSuite::doGetChildTestAt( 0 );
+}
+
+
+
+
+
+TestRunner::TestRunner()
+ : m_suite( new WrappingSuite() )
+{
+}
+
+
+TestRunner::~TestRunner()
+{
+ delete m_suite;
+}
+
+
+void
+TestRunner::addTest( Test *test )
+{
+ m_suite->addTest( test );
+}
+
+
+void
+TestRunner::run( TestResult &controller,
+ const std::string &testPath )
+{
+ TestPath path = m_suite->resolveTestPath( testPath );
+ Test *testToRun = path.getChildTest();
+
+ controller.runTest( testToRun );
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TestSuccessListener.cpp b/3rdParty/CppUnit/src/TestSuccessListener.cpp
new file mode 100644
index 0000000..a5572a9
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestSuccessListener.cpp
@@ -0,0 +1,44 @@
+#include <cppunit/TestSuccessListener.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TestSuccessListener::TestSuccessListener( SynchronizationObject *syncObject )
+ : SynchronizedObject( syncObject )
+ , m_success( true )
+{
+}
+
+
+TestSuccessListener::~TestSuccessListener()
+{
+}
+
+
+void
+TestSuccessListener::reset()
+{
+ ExclusiveZone zone( m_syncObject );
+ m_success = true;
+}
+
+
+void
+TestSuccessListener::addFailure( const TestFailure & )
+{
+ ExclusiveZone zone( m_syncObject );
+ m_success = false;
+}
+
+
+bool
+TestSuccessListener::wasSuccessful() const
+{
+ ExclusiveZone zone( m_syncObject );
+ return m_success;
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TestSuite.cpp b/3rdParty/CppUnit/src/TestSuite.cpp
new file mode 100644
index 0000000..8dd2ea6
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestSuite.cpp
@@ -0,0 +1,64 @@
+#include <cppunit/config/SourcePrefix.h>
+#include <cppunit/TestSuite.h>
+#include <cppunit/TestResult.h>
+
+CPPUNIT_NS_BEGIN
+
+
+/// Default constructor
+TestSuite::TestSuite( std::string name )
+ : TestComposite( name )
+{
+}
+
+
+/// Destructor
+TestSuite::~TestSuite()
+{
+ deleteContents();
+}
+
+
+/// Deletes all tests in the suite.
+void
+TestSuite::deleteContents()
+{
+ int childCount = getChildTestCount();
+ for ( int index =0; index < childCount; ++index )
+ delete getChildTestAt( index );
+
+ m_tests.clear();
+}
+
+
+/// Adds a test to the suite.
+void
+TestSuite::addTest( Test *test )
+{
+ m_tests.push_back( test );
+}
+
+
+const CppUnitVector<Test *> &
+TestSuite::getTests() const
+{
+ return m_tests;
+}
+
+
+int
+TestSuite::getChildTestCount() const
+{
+ return m_tests.size();
+}
+
+
+Test *
+TestSuite::doGetChildTestAt( int index ) const
+{
+ return m_tests[index];
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TestSuiteBuilderContext.cpp b/3rdParty/CppUnit/src/TestSuiteBuilderContext.cpp
new file mode 100644
index 0000000..ff71b52
--- /dev/null
+++ b/3rdParty/CppUnit/src/TestSuiteBuilderContext.cpp
@@ -0,0 +1,85 @@
+#include <cppunit/TestSuite.h>
+#include <cppunit/extensions/TestFixtureFactory.h>
+#include <cppunit/extensions/TestNamer.h>
+#include <cppunit/extensions/TestSuiteBuilderContext.h>
+
+
+CPPUNIT_NS_BEGIN
+
+TestSuiteBuilderContextBase::TestSuiteBuilderContextBase(
+ TestSuite &suite,
+ const TestNamer &namer,
+ TestFixtureFactory &factory )
+ : m_suite( suite )
+ , m_namer( namer )
+ , m_factory( factory )
+{
+}
+
+
+TestSuiteBuilderContextBase::~TestSuiteBuilderContextBase()
+{
+}
+
+
+void
+TestSuiteBuilderContextBase::addTest( Test *test )
+{
+ m_suite.addTest( test );
+}
+
+
+std::string
+TestSuiteBuilderContextBase::getFixtureName() const
+{
+ return m_namer.getFixtureName();
+}
+
+
+std::string
+TestSuiteBuilderContextBase::getTestNameFor(
+ const std::string &testMethodName ) const
+{
+ return m_namer.getTestNameFor( testMethodName );
+}
+
+
+TestFixture *
+TestSuiteBuilderContextBase::makeTestFixture() const
+{
+ return m_factory.makeFixture();
+}
+
+
+void
+TestSuiteBuilderContextBase::addProperty( const std::string &key,
+ const std::string &value )
+{
+ Properties::iterator it = m_properties.begin();
+ for ( ; it != m_properties.end(); ++it )
+ {
+ if ( (*it).first == key )
+ {
+ (*it).second = value;
+ return;
+ }
+ }
+
+ Property property( key, value );
+ m_properties.push_back( property );
+}
+
+const std::string
+TestSuiteBuilderContextBase::getStringProperty( const std::string &key ) const
+{
+ Properties::const_iterator it = m_properties.begin();
+ for ( ; it != m_properties.end(); ++it )
+ {
+ if ( (*it).first == key )
+ return (*it).second;
+ }
+ return "";
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TextOutputter.cpp b/3rdParty/CppUnit/src/TextOutputter.cpp
new file mode 100644
index 0000000..f74214f
--- /dev/null
+++ b/3rdParty/CppUnit/src/TextOutputter.cpp
@@ -0,0 +1,140 @@
+#include <cppunit/Exception.h>
+#include <cppunit/SourceLine.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/TextOutputter.h>
+#include <cppunit/TestResultCollector.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TextOutputter::TextOutputter( TestResultCollector *result,
+ OStream &stream )
+ : m_result( result )
+ , m_stream( stream )
+{
+}
+
+
+TextOutputter::~TextOutputter()
+{
+}
+
+
+void
+TextOutputter::write()
+{
+ printHeader();
+ m_stream << "\n";
+ printFailures();
+ m_stream << "\n";
+}
+
+
+void
+TextOutputter::printFailures()
+{
+ TestResultCollector::TestFailures::const_iterator itFailure = m_result->failures().begin();
+ int failureNumber = 1;
+ while ( itFailure != m_result->failures().end() )
+ {
+ m_stream << "\n";
+ printFailure( *itFailure++, failureNumber++ );
+ }
+}
+
+
+void
+TextOutputter::printFailure( TestFailure *failure,
+ int failureNumber )
+{
+ printFailureListMark( failureNumber );
+ m_stream << ' ';
+ printFailureTestName( failure );
+ m_stream << ' ';
+ printFailureType( failure );
+ m_stream << ' ';
+ printFailureLocation( failure->sourceLine() );
+ m_stream << "\n";
+ printFailureDetail( failure->thrownException() );
+ m_stream << "\n";
+}
+
+
+void
+TextOutputter::printFailureListMark( int failureNumber )
+{
+ m_stream << failureNumber << ")";
+}
+
+
+void
+TextOutputter::printFailureTestName( TestFailure *failure )
+{
+ m_stream << "test: " << failure->failedTestName();
+}
+
+
+void
+TextOutputter::printFailureType( TestFailure *failure )
+{
+ m_stream << "("
+ << (failure->isError() ? "E" : "F")
+ << ")";
+}
+
+
+void
+TextOutputter::printFailureLocation( SourceLine sourceLine )
+{
+ if ( !sourceLine.isValid() )
+ return;
+
+ m_stream << "line: " << sourceLine.lineNumber()
+ << ' ' << sourceLine.fileName();
+}
+
+
+void
+TextOutputter::printFailureDetail( Exception *thrownException )
+{
+ m_stream << thrownException->message().shortDescription() << "\n";
+ m_stream << thrownException->message().details();
+}
+
+
+void
+TextOutputter::printHeader()
+{
+ if ( m_result->wasSuccessful() )
+ m_stream << "\nOK (" << m_result->runTests () << " tests)\n" ;
+ else
+ {
+ m_stream << "\n";
+ printFailureWarning();
+ printStatistics();
+ }
+}
+
+
+void
+TextOutputter::printFailureWarning()
+{
+ m_stream << "!!!FAILURES!!!\n";
+}
+
+
+void
+TextOutputter::printStatistics()
+{
+ m_stream << "Test Results:\n";
+
+ m_stream << "Run: " << m_result->runTests()
+ << " Failures: " << m_result->testFailures()
+ << " Errors: " << m_result->testErrors()
+ << "\n";
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TextTestProgressListener.cpp b/3rdParty/CppUnit/src/TextTestProgressListener.cpp
new file mode 100644
index 0000000..5bbe768
--- /dev/null
+++ b/3rdParty/CppUnit/src/TextTestProgressListener.cpp
@@ -0,0 +1,43 @@
+#include <cppunit/TestFailure.h>
+#include <cppunit/TextTestProgressListener.h>
+#include <cppunit/portability/Stream.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+TextTestProgressListener::TextTestProgressListener()
+{
+}
+
+
+TextTestProgressListener::~TextTestProgressListener()
+{
+}
+
+
+void
+TextTestProgressListener::startTest( Test * )
+{
+ stdCOut() << ".";
+}
+
+
+void
+TextTestProgressListener::addFailure( const TestFailure &failure )
+{
+ stdCOut() << ( failure.isError() ? "E" : "F" );
+}
+
+
+void
+TextTestProgressListener::endTestRun( Test *,
+ TestResult * )
+{
+ stdCOut() << "\n";
+ stdCOut().flush();
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/TextTestRunner.cpp b/3rdParty/CppUnit/src/TextTestRunner.cpp
new file mode 100644
index 0000000..1534ec0
--- /dev/null
+++ b/3rdParty/CppUnit/src/TextTestRunner.cpp
@@ -0,0 +1,144 @@
+// ==> Implementation of cppunit/ui/text/TestRunner.h
+
+#include <cppunit/config/SourcePrefix.h>
+#include <cppunit/TestSuite.h>
+#include <cppunit/TextTestResult.h>
+#include <cppunit/TextOutputter.h>
+#include <cppunit/TextTestProgressListener.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/ui/text/TextTestRunner.h>
+#include <cppunit/portability/Stream.h>
+#include <stdexcept>
+
+
+CPPUNIT_NS_BEGIN
+
+
+/*! Constructs a new text runner.
+ * \param outputter used to print text result. Owned by the runner.
+ */
+TextTestRunner::TextTestRunner( Outputter *outputter )
+ : m_result( new TestResultCollector() )
+ , m_eventManager( new TestResult() )
+ , m_outputter( outputter )
+{
+ if ( !m_outputter )
+ m_outputter = new TextOutputter( m_result, stdCOut() );
+ m_eventManager->addListener( m_result );
+}
+
+
+TextTestRunner::~TextTestRunner()
+{
+ delete m_eventManager;
+ delete m_outputter;
+ delete m_result;
+}
+
+
+/*! Runs the named test case.
+ *
+ * \param testName Name of the test case to run. If an empty is given, then
+ * all added tests are run. The name can be the name of any
+ * test in the hierarchy.
+ * \param doWait if \c true then the user must press the RETURN key
+ * before the run() method exit.
+ * \param doPrintResult if \c true (default) then the test result are printed
+ * on the standard output.
+ * \param doPrintProgress if \c true (default) then TextTestProgressListener is
+ * used to show the progress.
+ * \return \c true is the test was successful, \c false if the test
+ * failed or was not found.
+ */
+bool
+TextTestRunner::run( std::string testName,
+ bool doWait,
+ bool doPrintResult,
+ bool doPrintProgress )
+{
+ TextTestProgressListener progress;
+ if ( doPrintProgress )
+ m_eventManager->addListener( &progress );
+
+ TestRunner *pThis = this;
+ pThis->run( *m_eventManager, testName );
+
+ if ( doPrintProgress )
+ m_eventManager->removeListener( &progress );
+
+ printResult( doPrintResult );
+ wait( doWait );
+
+ return m_result->wasSuccessful();
+}
+
+
+void
+TextTestRunner::wait( bool doWait )
+{
+#if !defined( CPPUNIT_NO_STREAM )
+ if ( doWait )
+ {
+ stdCOut() << "<RETURN> to continue\n";
+ stdCOut().flush();
+ std::cin.get ();
+ }
+#endif
+}
+
+
+void
+TextTestRunner::printResult( bool doPrintResult )
+{
+ stdCOut() << "\n";
+ if ( doPrintResult )
+ m_outputter->write();
+}
+
+
+/*! Returns the result of the test run.
+ * Use this after calling run() to access the result of the test run.
+ */
+TestResultCollector &
+TextTestRunner::result() const
+{
+ return *m_result;
+}
+
+
+/*! Returns the event manager.
+ * The instance of TestResult results returned is the one that is used to run the
+ * test. Use this to register additional TestListener before running the tests.
+ */
+TestResult &
+TextTestRunner::eventManager() const
+{
+ return *m_eventManager;
+}
+
+
+/*! Specifies an alternate outputter.
+ *
+ * Notes that the outputter will be use after the test run only if \a printResult was
+ * \c true.
+ * \param outputter New outputter to use. The previous outputter is destroyed.
+ * The TextTestRunner assumes ownership of the outputter.
+ * \see CompilerOutputter, XmlOutputter, TextOutputter.
+ */
+void
+TextTestRunner::setOutputter( Outputter *outputter )
+{
+ delete m_outputter;
+ m_outputter = outputter;
+}
+
+
+void
+TextTestRunner::run( TestResult &controller,
+ const std::string &testPath )
+{
+ TestRunner::run( controller, testPath );
+}
+
+
+CPPUNIT_NS_END
diff --git a/3rdParty/CppUnit/src/TypeInfoHelper.cpp b/3rdParty/CppUnit/src/TypeInfoHelper.cpp
new file mode 100644
index 0000000..2febac6
--- /dev/null
+++ b/3rdParty/CppUnit/src/TypeInfoHelper.cpp
@@ -0,0 +1,54 @@
+#include <cppunit/Portability.h>
+#include <cppunit/extensions/TypeInfoHelper.h>
+#include <stdlib.h>
+
+#if CPPUNIT_HAVE_RTTI
+
+#include <string>
+
+#if CPPUNIT_HAVE_GCC_ABI_DEMANGLE
+#include <cxxabi.h>
+#endif
+
+
+CPPUNIT_NS_BEGIN
+
+
+std::string
+TypeInfoHelper::getClassName( const std::type_info &info )
+{
+#if defined(CPPUNIT_HAVE_GCC_ABI_DEMANGLE) && CPPUNIT_HAVE_GCC_ABI_DEMANGLE
+
+ int status = 0;
+ char* c_name = 0;
+
+ c_name = abi::__cxa_demangle( info.name(), 0, 0, &status );
+
+ std::string name( c_name );
+ free( c_name );
+
+#else // CPPUNIT_HAVE_GCC_ABI_DEMANGLE
+
+ static std::string classPrefix( "class " );
+ std::string name( info.name() );
+
+ // Work around gcc 3.0 bug: strip number before type name.
+ unsigned int firstNotDigitIndex = 0;
+ while ( firstNotDigitIndex < name.length() &&
+ name[firstNotDigitIndex] >= '0' &&
+ name[firstNotDigitIndex] <= '9' )
+ ++firstNotDigitIndex;
+ name = name.substr( firstNotDigitIndex );
+
+ if ( name.substr( 0, classPrefix.length() ) == classPrefix )
+ return name.substr( classPrefix.length() );
+
+#endif // CPPUNIT_HAVE_GCC_ABI_DEMANGLE
+
+ return name;
+}
+
+
+CPPUNIT_NS_END
+
+#endif // CPPUNIT_HAVE_RTTI
diff --git a/3rdParty/CppUnit/src/XmlDocument.cpp b/3rdParty/CppUnit/src/XmlDocument.cpp
new file mode 100644
index 0000000..31f9115
--- /dev/null
+++ b/3rdParty/CppUnit/src/XmlDocument.cpp
@@ -0,0 +1,106 @@
+#include <cppunit/config/SourcePrefix.h>
+#include <cppunit/tools/XmlDocument.h>
+#include <cppunit/tools/XmlElement.h>
+
+
+CPPUNIT_NS_BEGIN
+
+
+XmlDocument::XmlDocument( const std::string &encoding,
+ const std::string &styleSheet )
+ : m_styleSheet( styleSheet )
+ , m_rootElement( new XmlElement( "DummyRoot" ) )
+ , m_standalone( true )
+{
+ setEncoding( encoding );
+}
+
+
+XmlDocument::~XmlDocument()
+{
+ delete m_rootElement;
+}
+
+
+
+std::string
+XmlDocument::encoding() const
+{
+ return m_encoding;
+}
+
+
+void
+XmlDocument::setEncoding( const std::string &encoding )
+{
+ m_encoding = encoding.empty() ? std::string("ISO-8859-1") : encoding;
+}
+
+
+std::string
+XmlDocument::styleSheet() const
+{
+ return m_styleSheet;
+}
+
+
+void
+XmlDocument::setStyleSheet( const std::string &styleSheet )
+{
+ m_styleSheet = styleSheet;
+}
+
+
+bool
+XmlDocument::standalone() const
+{
+ return m_standalone;
+}
+
+
+void
+XmlDocument::setStandalone( bool standalone )
+{
+ m_standalone = standalone;
+}
+
+
+void
+XmlDocument::setRootElement( XmlElement *rootElement )
+{
+ if ( rootElement == m_rootElement )
+ return;
+
+ delete m_rootElement;
+ m_rootElement = rootElement;
+}
+
+
+XmlElement &
+XmlDocument::rootElement() const
+{
+ return *m_rootElement;
+}
+
+
+std::string
+XmlDocument::toString() const
+{
+ std::string asString = "<?xml version=\"1.0\" "
+ "encoding='" + m_encoding + "'";
+ if ( m_standalone )
+ asString += " standalone='yes'";
+
+ asString += " ?>\n";
+
+ if ( !m_styleSheet.empty() )
+ asString += "<?xml-stylesheet type=\"text/xsl\" href=\"" + m_styleSheet + "\"?>\n";
+
+ asString += m_rootElement->toString();
+
+ return asString;
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/XmlElement.cpp b/3rdParty/CppUnit/src/XmlElement.cpp
new file mode 100644
index 0000000..f930ad4
--- /dev/null
+++ b/3rdParty/CppUnit/src/XmlElement.cpp
@@ -0,0 +1,226 @@
+#include <cppunit/tools/StringTools.h>
+#include <cppunit/tools/XmlElement.h>
+#include <stdexcept>
+
+
+CPPUNIT_NS_BEGIN
+
+
+XmlElement::XmlElement( std::string elementName,
+ std::string content )
+ : m_name( elementName )
+ , m_content( content )
+{
+}
+
+
+XmlElement::XmlElement( std::string elementName,
+ int numericContent )
+ : m_name( elementName )
+{
+ setContent( numericContent );
+}
+
+
+XmlElement::~XmlElement()
+{
+ Elements::iterator itNode = m_elements.begin();
+ while ( itNode != m_elements.end() )
+ {
+ XmlElement *element = *itNode++;
+ delete element;
+ }
+}
+
+
+std::string
+XmlElement::name() const
+{
+ return m_name;
+}
+
+
+std::string
+XmlElement::content() const
+{
+ return m_content;
+}
+
+
+void
+XmlElement::setName( const std::string &name )
+{
+ m_name = name;
+}
+
+
+void
+XmlElement::setContent( const std::string &content )
+{
+ m_content = content;
+}
+
+
+void
+XmlElement::setContent( int numericContent )
+{
+ m_content = StringTools::toString( numericContent );
+}
+
+
+void
+XmlElement::addAttribute( std::string attributeName,
+ std::string value )
+{
+ m_attributes.push_back( Attribute( attributeName, value ) );
+}
+
+
+void
+XmlElement::addAttribute( std::string attributeName,
+ int numericValue )
+{
+ addAttribute( attributeName, StringTools::toString( numericValue ) );
+}
+
+
+void
+XmlElement::addElement( XmlElement *node )
+{
+ m_elements.push_back( node );
+}
+
+
+int
+XmlElement::elementCount() const
+{
+ return m_elements.size();
+}
+
+
+XmlElement *
+XmlElement::elementAt( int index ) const
+{
+ if ( index < 0 || index >= elementCount() )
+ throw std::invalid_argument( "XmlElement::elementAt(), out of range index" );
+
+ return m_elements[ index ];
+}
+
+
+XmlElement *
+XmlElement::elementFor( const std::string &name ) const
+{
+ Elements::const_iterator itElement = m_elements.begin();
+ for ( ; itElement != m_elements.end(); ++itElement )
+ {
+ if ( (*itElement)->name() == name )
+ return *itElement;
+ }
+
+ throw std::invalid_argument( "XmlElement::elementFor(), not matching child element found" );
+ return NULL; // make some compilers happy.
+}
+
+
+std::string
+XmlElement::toString( const std::string &indent ) const
+{
+ std::string element( indent );
+ element += "<";
+ element += m_name;
+ if ( !m_attributes.empty() )
+ {
+ element += " ";
+ element += attributesAsString();
+ }
+ element += ">";
+
+ if ( !m_elements.empty() )
+ {
+ element += "\n";
+
+ std::string subNodeIndent( indent + " " );
+ Elements::const_iterator itNode = m_elements.begin();
+ while ( itNode != m_elements.end() )
+ {
+ const XmlElement *node = *itNode++;
+ element += node->toString( subNodeIndent );
+ }
+
+ element += indent;
+ }
+
+ if ( !m_content.empty() )
+ {
+ element += escape( m_content );
+ if ( !m_elements.empty() )
+ {
+ element += "\n";
+ element += indent;
+ }
+ }
+
+ element += "</";
+ element += m_name;
+ element += ">\n";
+
+ return element;
+}
+
+
+std::string
+XmlElement::attributesAsString() const
+{
+ std::string attributes;
+ Attributes::const_iterator itAttribute = m_attributes.begin();
+ while ( itAttribute != m_attributes.end() )
+ {
+ if ( !attributes.empty() )
+ attributes += " ";
+
+ const Attribute &attribute = *itAttribute++;
+ attributes += attribute.first;
+ attributes += "=\"";
+ attributes += escape( attribute.second );
+ attributes += "\"";
+ }
+ return attributes;
+}
+
+
+std::string
+XmlElement::escape( std::string value ) const
+{
+ std::string escaped;
+ for ( unsigned int index =0; index < value.length(); ++index )
+ {
+ char c = value[index ];
+ switch ( c ) // escape all predefined XML entity (safe?)
+ {
+ case '<':
+ escaped += "&lt;";
+ break;
+ case '>':
+ escaped += "&gt;";
+ break;
+ case '&':
+ escaped += "&amp;";
+ break;
+ case '\'':
+ escaped += "&apos;";
+ break;
+ case '"':
+ escaped += "&quot;";
+ break;
+ default:
+ escaped += c;
+ }
+ }
+
+ return escaped;
+}
+
+
+CPPUNIT_NS_END
+
diff --git a/3rdParty/CppUnit/src/XmlOutputter.cpp b/3rdParty/CppUnit/src/XmlOutputter.cpp
new file mode 100644
index 0000000..c605e33
--- /dev/null
+++ b/3rdParty/CppUnit/src/XmlOutputter.cpp
@@ -0,0 +1,205 @@
+#include <cppunit/Exception.h>
+#include <cppunit/Test.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/XmlOutputterHook.h>
+#include <cppunit/tools/XmlDocument.h>
+#include <cppunit/tools/XmlElement.h>
+#include <stdlib.h>
+#include <algorithm>
+
+
+CPPUNIT_NS_BEGIN
+
+
+XmlOutputter::XmlOutputter( TestResultCollector *result,
+ OStream &stream,
+ std::string encoding )
+ : m_result( result )
+ , m_stream( stream )
+ , m_xml( new XmlDocument( encoding ) )
+{
+}
+
+
+XmlOutputter::~XmlOutputter()
+{
+ delete m_xml;
+}
+
+
+void
+XmlOutputter::addHook( XmlOutputterHook *hook )
+{
+ m_hooks.push_back( hook );
+}
+
+
+void
+XmlOutputter::removeHook( XmlOutputterHook *hook )
+{
+ m_hooks.erase( std::find( m_hooks.begin(), m_hooks.end(), hook ) );
+}
+
+
+void
+XmlOutputter::write()
+{
+ setRootNode();
+ m_stream << m_xml->toString();
+}
+
+
+void
+XmlOutputter::setStyleSheet( const std::string &styleSheet )
+{
+ m_xml->setStyleSheet( styleSheet );
+}
+
+
+void
+XmlOutputter::setStandalone( bool standalone )
+{
+ m_xml->setStandalone( standalone );
+}
+
+
+void
+XmlOutputter::setRootNode()
+{
+ XmlElement *rootNode = new XmlElement( "TestRun" );
+ m_xml->setRootElement( rootNode );
+
+ for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it )
+ (*it)->beginDocument( m_xml );
+
+ FailedTests failedTests;
+ fillFailedTestsMap( failedTests );
+
+ addFailedTests( failedTests, rootNode );
+ addSuccessfulTests( failedTests, rootNode );
+ addStatistics( rootNode );
+
+ for ( Hooks::iterator itEnd = m_hooks.begin(); itEnd != m_hooks.end(); ++itEnd )
+ (*itEnd)->endDocument( m_xml );
+}
+
+
+void
+XmlOutputter::fillFailedTestsMap( FailedTests &failedTests )
+{
+ const TestResultCollector::TestFailures &failures = m_result->failures();
+ TestResultCollector::TestFailures::const_iterator itFailure = failures.begin();
+ while ( itFailure != failures.end() )
+ {
+ TestFailure *failure = *itFailure++;
+ failedTests.insert( std::pair<Test* const, TestFailure*>(failure->failedTest(), failure ) );
+ }
+}
+
+
+void
+XmlOutputter::addFailedTests( FailedTests &failedTests,
+ XmlElement *rootNode )
+{
+ XmlElement *testsNode = new XmlElement( "FailedTests" );
+ rootNode->addElement( testsNode );
+
+ const TestResultCollector::Tests &tests = m_result->tests();
+ for ( unsigned int testNumber = 0; testNumber < tests.size(); ++testNumber )
+ {
+ Test *test = tests[testNumber];
+ if ( failedTests.find( test ) != failedTests.end() )
+ addFailedTest( test, failedTests[test], testNumber+1, testsNode );
+ }
+}
+
+
+void
+XmlOutputter::addSuccessfulTests( FailedTests &failedTests,
+ XmlElement *rootNode )
+{
+ XmlElement *testsNode = new XmlElement( "SuccessfulTests" );
+ rootNode->addElement( testsNode );
+
+ const TestResultCollector::Tests &tests = m_result->tests();
+ for ( unsigned int testNumber = 0; testNumber < tests.size(); ++testNumber )
+ {
+ Test *test = tests[testNumber];
+ if ( failedTests.find( test ) == failedTests.end() )
+ addSuccessfulTest( test, testNumber+1, testsNode );
+ }
+}
+
+
+void
+XmlOutputter::addStatistics( XmlElement *rootNode )
+{
+ XmlElement *statisticsElement = new XmlElement( "Statistics" );
+ rootNode->addElement( statisticsElement );
+ statisticsElement->addElement( new XmlElement( "Tests", m_result->runTests() ) );
+ statisticsElement->addElement( new XmlElement( "FailuresTotal",
+ m_result->testFailuresTotal() ) );
+ statisticsElement->addElement( new XmlElement( "Errors", m_result->testErrors() ) );
+ statisticsElement->addElement( new XmlElement( "Failures", m_result->testFailures() ) );
+
+ for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it )
+ (*it)->statisticsAdded( m_xml, statisticsElement );
+}
+
+
+void
+XmlOutputter::addFailedTest( Test *test,
+ TestFailure *failure,
+ int testNumber,
+ XmlElement *testsNode )
+{
+ Exception *thrownException = failure->thrownException();
+
+ XmlElement *testElement = new XmlElement( "FailedTest" );
+ testsNode->addElement( testElement );
+ testElement->addAttribute( "id", testNumber );
+ testElement->addElement( new XmlElement( "Name", test->getName() ) );
+ testElement->addElement( new XmlElement( "FailureType",
+ failure->isError() ? "Error" :
+ "Assertion" ) );
+
+ if ( failure->sourceLine().isValid() )
+ addFailureLocation( failure, testElement );
+
+ testElement->addElement( new XmlElement( "Message", thrownException->what() ) );
+
+ for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it )
+ (*it)->failTestAdded( m_xml, testElement, test, failure );
+}
+
+
+void
+XmlOutputter::addFailureLocation( TestFailure *failure,
+ XmlElement *testElement )
+{
+ XmlElement *locationNode = new XmlElement( "Location" );
+ testElement->addElement( locationNode );
+ SourceLine sourceLine = failure->sourceLine();
+ locationNode->addElement( new XmlElement( "File", sourceLine.fileName() ) );
+ locationNode->addElement( new XmlElement( "Line", sourceLine.lineNumber() ) );
+}
+
+
+void
+XmlOutputter::addSuccessfulTest( Test *test,
+ int testNumber,
+ XmlElement *testsNode )
+{
+ XmlElement *testElement = new XmlElement( "Test" );
+ testsNode->addElement( testElement );
+ testElement->addAttribute( "id", testNumber );
+ testElement->addElement( new XmlElement( "Name", test->getName() ) );
+
+ for ( Hooks::iterator it = m_hooks.begin(); it != m_hooks.end(); ++it )
+ (*it)->successfulTestAdded( m_xml, testElement, test );
+}
+
+
+CPPUNIT_NS_END