CppUTest is a C /C++ based unit xUnit test framework for unit testing and for test-driving your code.

CppUTest

Where to find more information

Getting test reports on the console

You may need to tailor the file src/Platforms/mbed/UtestPlatform.cpp to your needs. In particular, if you want console output, you might want to look at the function PlatformSpecificPutchar().

Quick introduction (some code!)

To write your first test, all you need is a new cpp file with a TEST_GROUP and a TEST, like:

#include "CppUTest/TestHarness.h"

TEST_GROUP(FirstTestGroup)
{
};

TEST(FirstTestGroup, FirstTest)
{
   FAIL("Fail me!");
}

This test will fail.

You can add new tests to the test group by just writing more tests in the file, like this:

TEST(FirstTestGroup, SecondTest)
{
   STRCMP_EQUAL("hello", "world");
   LONGS_EQUAL(1, 2);
   CHECK(false);
}

You do need to trigger the tests from somewhere in your program. It could look something like:

#include "CppUTest/TestRegistry.h"
#include "CppUTest/CommandLineTestRunner.h"

int main(int ac, char** av)
{
    ....
    unsigned failureCount = 0;
    {
        ConsoleTestOutput output;
        CommandLineTestRunner runner(ac, av, &output, TestRegistry::getCurrentRegistry());
        failureCount = runner.runAllTestsMain();
    }

    if (failureCount == 0) {
        console.printf("PASSED\r\n");
    }
    ...
}

For more information, We’d recommend to read the manual or, even better, check some existing tests such as SimpleStringTest or (a bit more complicated) MemoryLeakDetectorTest or the mocking tests or just check out the Cheat Sheet.

Files at this revision

API Documentation at this revision

Comitter:
Rohit Grover
Date:
Tue Jun 17 15:52:54 2014 +0100
Parent:
0:0b799af9d58e
Child:
2:82161d9e7b36
Commit message:
updating to the latest version of cppUtest; tested against nordic's m-kit

Changed in this revision

include/CppUTest/CommandLineArguments.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/CppUTestConfig.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/JUnitTestOutput.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/MemoryLeakDetectorNewMacros.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/MemoryLeakWarningPlugin.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/PlatformSpecificFunctions_c.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/SimpleString.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/TestFailure.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/TestPlugin.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/TestResult.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/Utest.h Show annotated file Show diff for this revision Revisions of this file
include/CppUTest/UtestMacros.h Show annotated file Show diff for this revision Revisions of this file
include/Platforms/armcc/Platform.h Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/CommandLineArguments.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/CommandLineTestRunner.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/JUnitTestOutput.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/MemoryLeakDetector.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/MemoryLeakWarningPlugin.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/SimpleString.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestFailure.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestHarness_c.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestMemoryAllocator.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestOutput.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestPlugin.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestRegistry.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/TestResult.cpp Show annotated file Show diff for this revision Revisions of this file
src/CppUTest/Utest.cpp Show annotated file Show diff for this revision Revisions of this file
src/Platforms/armcc/UtestPlatform.cpp Show annotated file Show diff for this revision Revisions of this file
src/Platforms/mbed/UtestPlatform.cpp Show diff for this revision Revisions of this file
--- a/include/CppUTest/CommandLineArguments.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/CommandLineArguments.h	Tue Jun 17 15:52:54 2014 +0100
@@ -48,6 +48,7 @@
 	bool isJUnitOutput() const;
 	bool isEclipseOutput() const;
 	bool runTestsInSeperateProcess() const;
+	const SimpleString& getPackageName() const;
 	const char* usage() const;
 
 private:
@@ -65,6 +66,7 @@
 	TestFilter groupFilter_;
 	TestFilter nameFilter_;
 	OutputType outputType_;
+	SimpleString packageName_;
 
 	SimpleString getParameterField(int ac, const char** av, int& i, const SimpleString& parameterName);
 	void SetRepeatCount(int ac, const char** av, int& index);
@@ -74,6 +76,7 @@
 	void SetStrictNameFilter(int ac, const char** av, int& index);
 	void SetTestToRunBasedOnVerboseOutput(int ac, const char** av, int& index, const char* parameterName);
 	bool SetOutputType(int ac, const char** av, int& index);
+	void SetPackageName(int ac, const char** av, int& index);
 
 	CommandLineArguments(const CommandLineArguments&);
 	CommandLineArguments& operator=(const CommandLineArguments&);
--- a/include/CppUTest/CppUTestConfig.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/CppUTestConfig.h	Tue Jun 17 15:52:54 2014 +0100
@@ -62,8 +62,7 @@
  #endif
 #endif
 
-
-#if NEED_TO_ENABLE_CPP_SUPPORT /* disabled by default because mbed's
+#if NEED_TO_ENABLE_CPP_SUPPORT /* disabled by default because our
                                 * toolchain doesn't support exceptions. */
     /* Do we use Standard C++ or not? */
     #ifndef CPPUTEST_USE_STD_CPP_LIB
@@ -124,17 +123,27 @@
   #endif
 #else
   #define UT_THROW(exception)
-  #define UT_NOTHROW
+  #ifdef __clang__
+    #define UT_NOTHROW throw()
+  #else
+    #define UT_NOTHROW
+  #endif
 #endif
 
 /*
- * CLang's operator delete requires an NOTHROW block. For now, when we use CLang, then have an empty exception specifier.
- * However, this ought to be done inside the configure.ac in the future.
+ * Visual C++ doesn't define __cplusplus as C++11 yet (201103), however it doesn't want the throw(exception) either, but
+ * it does want throw().
  */
 
-#ifdef __clang__
-#undef UT_NOTHROW
-#define UT_NOTHROW throw()
+#ifdef _MSC_VER
+  #undef UT_THROW
+  #define UT_THROW(exception)
+#endif
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+	#define DEFAULT_COPY_CONSTRUCTOR(classname) classname(const classname &) = default;
+#else
+	#define DEFAULT_COPY_CONSTRUCTOR(classname)
 #endif
 
 /*
@@ -163,7 +172,8 @@
 #endif
 #endif
 
-#if defined(__cplusplus) && __cplusplus >= 201103L
+/* Visual C++ 10.0+ (2010+) supports the override keyword, but doesn't define the C++ version as C++11 */
+#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && (_MSC_VER >= 1600)))
 #define _override override
 #else
 #define _override
--- a/include/CppUTest/JUnitTestOutput.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/JUnitTestOutput.h	Tue Jun 17 15:52:54 2014 +0100
@@ -57,6 +57,7 @@
 	virtual void flush() _override;
 
 	virtual SimpleString createFileName(const SimpleString& group);
+	void setPackageName(const SimpleString &package);
 
 protected:
 
--- a/include/CppUTest/MemoryLeakDetectorNewMacros.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/MemoryLeakDetectorNewMacros.h	Tue Jun 17 15:52:54 2014 +0100
@@ -21,7 +21,8 @@
 
 #include "CppUTestConfig.h"
 
-#if CPPUTEST_USE_MEM_LEAK_DETECTION
+/* Make sure that mem leak detection is on and that this is being included from a C++ file */
+#if CPPUTEST_USE_MEM_LEAK_DETECTION && defined(__cplusplus)
 
 /* This #ifndef prevents <new> from being included twice and enables the file to be included anywhere */
 #ifndef CPPUTEST_USE_NEW_MACROS
--- a/include/CppUTest/MemoryLeakWarningPlugin.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/MemoryLeakWarningPlugin.h	Tue Jun 17 15:52:54 2014 +0100
@@ -66,6 +66,7 @@
 
 	static void turnOffNewDeleteOverloads();
 	static void turnOnNewDeleteOverloads();
+	static bool areNewDeleteOverloaded();
 private:
 	MemoryLeakDetector* memLeakDetector_;
 	bool ignoreAllWarnings_;
--- a/include/CppUTest/PlatformSpecificFunctions_c.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/PlatformSpecificFunctions_c.h	Tue Jun 17 15:52:54 2014 +0100
@@ -56,9 +56,6 @@
 /* String operations */
 int PlatformSpecificAtoI(const char*str);
 size_t PlatformSpecificStrLen(const char* str);
-char* PlatformSpecificStrCat(char* s1, const char* s2);
-char* PlatformSpecificStrCpy(char* s1, const char* s2);
-char* PlatformSpecificStrNCpy(char* s1, const char* s2, size_t size);
 int PlatformSpecificStrCmp(const char* s1, const char* s2);
 int PlatformSpecificStrNCmp(const char* s1, const char* s2, size_t size);
 char* PlatformSpecificStrStr(const char* s1, const char* s2);
--- a/include/CppUTest/SimpleString.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/SimpleString.h	Tue Jun 17 15:52:54 2014 +0100
@@ -90,13 +90,15 @@
 	static void setStringAllocator(TestMemoryAllocator* allocator);
 
 	static char* allocStringBuffer(size_t size);
+	static char* StrNCpy(char* s1, const char* s2, size_t n);
 	static void deallocStringBuffer(char* str);
 private:
 	char *buffer_;
 
 	static TestMemoryAllocator* stringAllocator_;
 
-	char* getEmptyString() const;
+	char* getEmptyString() const; 
+	static char* copyToNewBuffer(const char* bufferToCopy, size_t bufferSize=0);
 };
 
 class SimpleStringCollection
@@ -124,15 +126,17 @@
 SimpleString StringFrom(char value);
 SimpleString StringFrom(const char *value);
 SimpleString StringFromOrNull(const char * value);
+SimpleString StringFrom(int value);
+SimpleString StringFrom(unsigned int value);
 SimpleString StringFrom(long value);
-SimpleString StringFrom(int value);
+SimpleString StringFrom(unsigned long value);
 SimpleString HexStringFrom(long value);
+SimpleString HexStringFrom(unsigned long value);
 SimpleString HexStringFrom(const void* value);
 SimpleString StringFrom(double value, int precision = 6);
 SimpleString StringFrom(const SimpleString& other);
 SimpleString StringFromFormat(const char* format, ...) __check_format__(printf, 1, 2);
 SimpleString VStringFromFormat(const char* format, va_list args);
-SimpleString StringFrom(unsigned int value);
 
 #if CPPUTEST_USE_STD_CPP_LIB
 
@@ -140,7 +144,6 @@
 #include <stdint.h>
 
 SimpleString StringFrom(const std::string& other);
-SimpleString StringFrom(unsigned long);
 
 #endif
 
--- a/include/CppUTest/TestFailure.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/TestFailure.h	Tue Jun 17 15:52:54 2014 +0100
@@ -122,6 +122,12 @@
 	LongsEqualFailure(UtestShell* test, const char* fileName, int lineNumber, long expected, long actual);
 };
 
+class UnsignedLongsEqualFailure : public TestFailure
+{
+public:
+	UnsignedLongsEqualFailure(UtestShell* test, const char* fileName, int lineNumber, unsigned long expected, unsigned long actual);
+};
+
 class StringEqualFailure : public TestFailure
 {
 public:
--- a/include/CppUTest/TestPlugin.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/TestPlugin.h	Tue Jun 17 15:52:54 2014 +0100
@@ -95,7 +95,7 @@
 
 	enum
 	{
-		MAX_SET = 1024
+		MAX_SET = 16
 	};
 };
 
--- a/include/CppUTest/TestResult.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/TestResult.h	Tue Jun 17 15:52:54 2014 +0100
@@ -42,6 +42,7 @@
 {
 public:
 	TestResult(TestOutput&);
+	DEFAULT_COPY_CONSTRUCTOR(TestResult)
 	virtual ~TestResult();
 
 	virtual void testsStarted();
--- a/include/CppUTest/Utest.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/Utest.h	Tue Jun 17 15:52:54 2014 +0100
@@ -111,7 +111,8 @@
     virtual void assertCstrNoCaseEqual(const char *expected, const char *actual, const char *fileName, int lineNumber);
     virtual void assertCstrContains(const char *expected, const char *actual, const char *fileName, int lineNumber);
     virtual void assertCstrNoCaseContains(const char *expected, const char *actual, const char *fileName, int lineNumber);
-    virtual void assertLongsEqual(long  expected, long  actual, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
+    virtual void assertLongsEqual(long expected, long actual, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
+    virtual void assertUnsignedLongsEqual(unsigned long expected, unsigned long actual, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
     virtual void assertPointersEqual(const void *expected, const void *actual, const char *fileName, int lineNumber);
     virtual void assertDoublesEqual(double expected, double actual, double threshold, const char *fileName, int lineNumber, const TestTerminator& testTerminator = NormalTestTerminator());
     virtual void assertEquals(bool failed, const char* expected, const char* actual, const char* file, int line, const TestTerminator& testTerminator = NormalTestTerminator());
--- a/include/CppUTest/UtestMacros.h	Tue Jan 28 09:27:41 2014 +0000
+++ b/include/CppUTest/UtestMacros.h	Tue Jun 17 15:52:54 2014 +0100
@@ -122,6 +122,10 @@
 	  if ((expected) != (expected)) \
 	  	  UtestShell::getCurrent()->print("WARNING:\n\tThe \"Expected Parameter\" parameter is evaluated multiple times resulting in different values.\n\tThus the value in the error message is probably incorrect.", file, line); \
 	  UtestShell::getCurrent()->assertEquals(true, StringFrom(expected).asCharString(), StringFrom(actual).asCharString(), file, line); \
+  } \
+  else \
+  { \
+    UtestShell::getCurrent()->assertLongsEqual((long)0, (long)0, file, line); \
   } }
 
 //This check checks for char* string equality using strcmp.
@@ -154,9 +158,15 @@
 #define LONGS_EQUAL(expected,actual)\
   LONGS_EQUAL_LOCATION(expected,actual,__FILE__, __LINE__)
 
+#define UNSIGNED_LONGS_EQUAL(expected,actual)\
+  UNSIGNED_LONGS_EQUAL_LOCATION(expected,actual,__FILE__, __LINE__)
+
 #define LONGS_EQUAL_LOCATION(expected,actual,file,line)\
   { UtestShell::getCurrent()->assertLongsEqual((long)expected, (long)actual,  file, line); }
 
+#define UNSIGNED_LONGS_EQUAL_LOCATION(expected,actual,file,line)\
+  { UtestShell::getCurrent()->assertUnsignedLongsEqual((unsigned long)expected, (unsigned long)actual,  file, line); }
+
 #define BYTES_EQUAL(expected, actual)\
     LONGS_EQUAL((expected) & 0xff,(actual) & 0xff)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Platforms/armcc/Platform.h	Tue Jun 17 15:52:54 2014 +0100
@@ -0,0 +1,6 @@
+
+#ifndef PLATFORM_H_
+#define PLATFORM_H_
+
+#endif /*PLATFORM_H_*/
+
--- a/src/CppUTest/CommandLineArguments.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/CommandLineArguments.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,179 +1,193 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/CommandLineArguments.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-CommandLineArguments::CommandLineArguments(int ac, const char** av) :
-	ac_(ac), av_(av), verbose_(false), runTestsAsSeperateProcess_(false), repeat_(1), groupFilter_(""), nameFilter_(""), outputType_(OUTPUT_ECLIPSE)
-{
-}
-
-CommandLineArguments::~CommandLineArguments()
-{
-}
-
-bool CommandLineArguments::parse(TestPlugin* plugin)
-{
-	bool correctParameters = true;
-	for (int i = 1; i < ac_; i++) {
-		SimpleString argument = av_[i];
-		if (argument == "-v") verbose_ = true;
-		else if (argument == "-p") runTestsAsSeperateProcess_ = true;
-		else if (argument.startsWith("-r")) SetRepeatCount(ac_, av_, i);
-		else if (argument.startsWith("-g")) SetGroupFilter(ac_, av_, i);
-		else if (argument.startsWith("-sg")) SetStrictGroupFilter(ac_, av_, i);
-		else if (argument.startsWith("-n")) SetNameFilter(ac_, av_, i);
-		else if (argument.startsWith("-sn")) SetStrictNameFilter(ac_, av_, i);
-		else if (argument.startsWith("TEST(")) SetTestToRunBasedOnVerboseOutput(ac_, av_, i, "TEST(");
-		else if (argument.startsWith("IGNORE_TEST(")) SetTestToRunBasedOnVerboseOutput(ac_, av_, i, "IGNORE_TEST(");
-		else if (argument.startsWith("-o")) correctParameters = SetOutputType(ac_, av_, i);
-		else if (argument.startsWith("-p")) correctParameters = plugin->parseAllArguments(ac_, av_, i);
-		else correctParameters = false;
-
-		if (correctParameters == false) {
-			return false;
-		}
-	}
-	return true;
-}
-
-const char* CommandLineArguments::usage() const
-{
-	return "usage [-v] [-r#] [-g|sg groupName] [-n|sn testName] [-o{normal, junit}]\n";
-}
-
-bool CommandLineArguments::isVerbose() const
-{
-	return verbose_;
-}
-
-bool CommandLineArguments::runTestsInSeperateProcess() const
-{
-	return runTestsAsSeperateProcess_;
-}
-
-
-int CommandLineArguments::getRepeatCount() const
-{
-	return repeat_;
-}
-
-TestFilter CommandLineArguments::getGroupFilter() const
-{
-	return groupFilter_;
-}
-
-TestFilter CommandLineArguments::getNameFilter() const
-{
-	return nameFilter_;
-}
-
-void CommandLineArguments::SetRepeatCount(int ac, const char** av, int& i)
-{
-	repeat_ = 0;
-
-	SimpleString repeatParameter(av[i]);
-	if (repeatParameter.size() > 2) repeat_ = PlatformSpecificAtoI(av[i] + 2);
-	else if (i + 1 < ac) {
-		repeat_ = PlatformSpecificAtoI(av[i + 1]);
-		if (repeat_ != 0) i++;
-	}
-
-	if (0 == repeat_) repeat_ = 2;
-
-}
-
-SimpleString CommandLineArguments::getParameterField(int ac, const char** av, int& i, const SimpleString& parameterName)
-{
-	size_t parameterLength = parameterName.size();
-	SimpleString parameter(av[i]);
-	if (parameter.size() >  parameterLength) return av[i] + parameterLength;
-	else if (i + 1 < ac) return av[++i];
-	return "";
-}
-
-void CommandLineArguments::SetGroupFilter(int ac, const char** av, int& i)
-{
-	groupFilter_ = TestFilter(getParameterField(ac, av, i, "-g"));
-}
-
-void CommandLineArguments::SetStrictGroupFilter(int ac, const char** av, int& i)
-{
-	groupFilter_ = TestFilter(getParameterField(ac, av, i, "-sg"));
-	groupFilter_.strictMatching();
-}
-
-void CommandLineArguments::SetNameFilter(int ac, const char** av, int& i)
-{
-	nameFilter_ = getParameterField(ac, av, i, "-n");
-}
-
-void CommandLineArguments::SetStrictNameFilter(int ac, const char** av, int& index)
-{
-	nameFilter_ = getParameterField(ac, av, index, "-sn");
-	nameFilter_.strictMatching();
-}
-
-void CommandLineArguments::SetTestToRunBasedOnVerboseOutput(int ac, const char** av, int& index, const char* parameterName)
-{
-	SimpleString wholename = getParameterField(ac, av, index, parameterName);
-	SimpleString testname = wholename.subStringFromTill(',', ')');
-	testname = testname.subString(2, testname.size());
-	groupFilter_ = wholename.subStringFromTill(wholename.at(0), ',');
-	nameFilter_ = testname;
-	nameFilter_.strictMatching();
-	groupFilter_.strictMatching();
-}
-
-bool CommandLineArguments::SetOutputType(int ac, const char** av, int& i)
-{
-	SimpleString outputType = getParameterField(ac, av, i, "-o");
-	if (outputType.size() == 0) return false;
-
-	if (outputType == "normal" || outputType == "eclipse") {
-		outputType_ = OUTPUT_ECLIPSE;
-		return true;
-	}
-	if (outputType == "junit") {
-		outputType_ = OUTPUT_JUNIT;
-		return true;
-	}
-	return false;
-}
-
-bool CommandLineArguments::isEclipseOutput() const
-{
-	return outputType_ == OUTPUT_ECLIPSE;
-}
-
-bool CommandLineArguments::isJUnitOutput() const
-{
-	return outputType_ == OUTPUT_JUNIT;
-}
-
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/CommandLineArguments.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+CommandLineArguments::CommandLineArguments(int ac, const char** av) :
+	ac_(ac), av_(av), verbose_(false), runTestsAsSeperateProcess_(false), repeat_(1), groupFilter_(""), nameFilter_(""), outputType_(OUTPUT_ECLIPSE), packageName_("")
+{
+}
+
+CommandLineArguments::~CommandLineArguments()
+{
+}
+
+bool CommandLineArguments::parse(TestPlugin* plugin)
+{
+	bool correctParameters = true;
+	for (int i = 1; i < ac_; i++) {
+		SimpleString argument = av_[i];
+		if (argument == "-v") verbose_ = true;
+		else if (argument == "-p") runTestsAsSeperateProcess_ = true;
+		else if (argument.startsWith("-r")) SetRepeatCount(ac_, av_, i);
+		else if (argument.startsWith("-g")) SetGroupFilter(ac_, av_, i);
+		else if (argument.startsWith("-sg")) SetStrictGroupFilter(ac_, av_, i);
+		else if (argument.startsWith("-n")) SetNameFilter(ac_, av_, i);
+		else if (argument.startsWith("-sn")) SetStrictNameFilter(ac_, av_, i);
+		else if (argument.startsWith("TEST(")) SetTestToRunBasedOnVerboseOutput(ac_, av_, i, "TEST(");
+		else if (argument.startsWith("IGNORE_TEST(")) SetTestToRunBasedOnVerboseOutput(ac_, av_, i, "IGNORE_TEST(");
+		else if (argument.startsWith("-o")) correctParameters = SetOutputType(ac_, av_, i);
+		else if (argument.startsWith("-p")) correctParameters = plugin->parseAllArguments(ac_, av_, i);
+		else if (argument.startsWith("-k")) SetPackageName(ac_, av_, i);
+		else correctParameters = false;
+
+		if (correctParameters == false) {
+			return false;
+		}
+	}
+	return true;
+}
+
+const char* CommandLineArguments::usage() const
+{
+	return "usage [-v] [-r#] [-g|sg groupName] [-n|sn testName] [-o{normal, junit}] [-k packageName]\n";
+}
+
+bool CommandLineArguments::isVerbose() const
+{
+	return verbose_;
+}
+
+bool CommandLineArguments::runTestsInSeperateProcess() const
+{
+	return runTestsAsSeperateProcess_;
+}
+
+
+int CommandLineArguments::getRepeatCount() const
+{
+	return repeat_;
+}
+
+TestFilter CommandLineArguments::getGroupFilter() const
+{
+	return groupFilter_;
+}
+
+TestFilter CommandLineArguments::getNameFilter() const
+{
+	return nameFilter_;
+}
+
+void CommandLineArguments::SetRepeatCount(int ac, const char** av, int& i)
+{
+	repeat_ = 0;
+
+	SimpleString repeatParameter(av[i]);
+	if (repeatParameter.size() > 2) repeat_ = PlatformSpecificAtoI(av[i] + 2);
+	else if (i + 1 < ac) {
+		repeat_ = PlatformSpecificAtoI(av[i + 1]);
+		if (repeat_ != 0) i++;
+	}
+
+	if (0 == repeat_) repeat_ = 2;
+
+}
+
+SimpleString CommandLineArguments::getParameterField(int ac, const char** av, int& i, const SimpleString& parameterName)
+{
+	size_t parameterLength = parameterName.size();
+	SimpleString parameter(av[i]);
+	if (parameter.size() >  parameterLength) return av[i] + parameterLength;
+	else if (i + 1 < ac) return av[++i];
+	return "";
+}
+
+void CommandLineArguments::SetGroupFilter(int ac, const char** av, int& i)
+{
+	groupFilter_ = TestFilter(getParameterField(ac, av, i, "-g"));
+}
+
+void CommandLineArguments::SetStrictGroupFilter(int ac, const char** av, int& i)
+{
+	groupFilter_ = TestFilter(getParameterField(ac, av, i, "-sg"));
+	groupFilter_.strictMatching();
+}
+
+void CommandLineArguments::SetNameFilter(int ac, const char** av, int& i)
+{
+	nameFilter_ = getParameterField(ac, av, i, "-n");
+}
+
+void CommandLineArguments::SetStrictNameFilter(int ac, const char** av, int& index)
+{
+	nameFilter_ = getParameterField(ac, av, index, "-sn");
+	nameFilter_.strictMatching();
+}
+
+void CommandLineArguments::SetTestToRunBasedOnVerboseOutput(int ac, const char** av, int& index, const char* parameterName)
+{
+	SimpleString wholename = getParameterField(ac, av, index, parameterName);
+	SimpleString testname = wholename.subStringFromTill(',', ')');
+	testname = testname.subString(2, testname.size());
+	groupFilter_ = wholename.subStringFromTill(wholename.at(0), ',');
+	nameFilter_ = testname;
+	nameFilter_.strictMatching();
+	groupFilter_.strictMatching();
+}
+
+void CommandLineArguments::SetPackageName(int ac, const char** av, int& i)
+{
+	SimpleString packageName = getParameterField(ac, av, i, "-k");
+	if (packageName.size() == 0) return;
+
+	packageName_ = packageName;
+}
+
+bool CommandLineArguments::SetOutputType(int ac, const char** av, int& i)
+{
+	SimpleString outputType = getParameterField(ac, av, i, "-o");
+	if (outputType.size() == 0) return false;
+
+	if (outputType == "normal" || outputType == "eclipse") {
+		outputType_ = OUTPUT_ECLIPSE;
+		return true;
+	}
+	if (outputType == "junit") {
+		outputType_ = OUTPUT_JUNIT;
+		return true;
+	}
+	return false;
+}
+
+bool CommandLineArguments::isEclipseOutput() const
+{
+	return outputType_ == OUTPUT_ECLIPSE;
+}
+
+bool CommandLineArguments::isJUnitOutput() const
+{
+	return outputType_ == OUTPUT_JUNIT;
+}
+
+const SimpleString& CommandLineArguments::getPackageName() const
+{
+	return packageName_;
+}
+
--- a/src/CppUTest/CommandLineTestRunner.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/CommandLineTestRunner.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,143 +1,146 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/CommandLineTestRunner.h"
-#include "CppUTest/TestOutput.h"
-#include "CppUTest/JUnitTestOutput.h"
-#include "CppUTest/TestRegistry.h"
-
-CommandLineTestRunner::CommandLineTestRunner(int ac, const char** av, TestOutput* output, TestRegistry* registry) :
-	output_(output), jUnitOutput_(NULL), arguments_(NULL), registry_(registry)
-{
-	arguments_ = new CommandLineArguments(ac, av);
-}
-
-CommandLineTestRunner::~CommandLineTestRunner()
-{
-	delete arguments_;
-	delete jUnitOutput_;
-}
-
-int CommandLineTestRunner::RunAllTests(int ac, char** av)
-{
-	return RunAllTests(ac, const_cast<const char**> (av));
-}
-
-int CommandLineTestRunner::RunAllTests(int ac, const char** av)
-{
-	int result = 0;
-	ConsoleTestOutput output;
-
-	MemoryLeakWarningPlugin memLeakWarn(DEF_PLUGIN_MEM_LEAK);
-	memLeakWarn.destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(true);
-	TestRegistry::getCurrentRegistry()->installPlugin(&memLeakWarn);
-
-	{
-		CommandLineTestRunner runner(ac, av, &output, TestRegistry::getCurrentRegistry());
-		result = runner.runAllTestsMain();
-	}
-
-	if (result == 0) {
-		output << memLeakWarn.FinalReport(0);
-	}
-	TestRegistry::getCurrentRegistry()->removePluginByName(DEF_PLUGIN_MEM_LEAK);
-	return result;
-}
-
-int CommandLineTestRunner::runAllTestsMain()
-{
-	int testResult = 0;
-
-	SetPointerPlugin pPlugin(DEF_PLUGIN_SET_POINTER);
-	registry_->installPlugin(&pPlugin);
-
-	if (parseArguments(registry_->getFirstPlugin()))
-		testResult = runAllTests();
-
-	registry_->removePluginByName(DEF_PLUGIN_SET_POINTER);
-	return testResult;
-}
-
-void CommandLineTestRunner::initializeTestRun()
-{
-	registry_->groupFilter(arguments_->getGroupFilter());
-	registry_->nameFilter(arguments_->getNameFilter());
-	if (arguments_->isVerbose()) output_->verbose();
-	if (arguments_->runTestsInSeperateProcess()) registry_->setRunTestsInSeperateProcess();
-}
-
-int CommandLineTestRunner::runAllTests()
-{
-	initializeTestRun();
-	int loopCount = 0;
-	int failureCount = 0;
-	int repeat_ = arguments_->getRepeatCount();
-
-	while (loopCount++ < repeat_) {
-		output_->printTestRun(loopCount, repeat_);
-		TestResult tr(*output_);
-		registry_->runAllTests(tr);
-		failureCount += tr.getFailureCount();
-	}
-
-	return failureCount;
-}
-
-bool CommandLineTestRunner::parseArguments(TestPlugin* plugin)
-{
-	if (arguments_->parse(plugin)) {
-		if (arguments_->isJUnitOutput()) {
-			output_ = jUnitOutput_ = new JUnitTestOutput;
-		}
-		return true;
-	}
-	else {
-		output_->print(arguments_->usage());
-		return false;
-	}
-}
-
-bool CommandLineTestRunner::isVerbose()
-{
-	return arguments_->isVerbose();
-}
-
-int CommandLineTestRunner::getRepeatCount()
-{
-	return arguments_->getRepeatCount();
-}
-
-TestFilter CommandLineTestRunner::getGroupFilter()
-{
-	return arguments_->getGroupFilter();
-}
-
-TestFilter CommandLineTestRunner::getNameFilter()
-{
-	return arguments_->getNameFilter();
-}
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/CommandLineTestRunner.h"
+#include "CppUTest/TestOutput.h"
+#include "CppUTest/JUnitTestOutput.h"
+#include "CppUTest/TestRegistry.h"
+
+CommandLineTestRunner::CommandLineTestRunner(int ac, const char** av, TestOutput* output, TestRegistry* registry) :
+	output_(output), jUnitOutput_(NULL), arguments_(NULL), registry_(registry)
+{
+	arguments_ = new CommandLineArguments(ac, av);
+}
+
+CommandLineTestRunner::~CommandLineTestRunner()
+{
+	delete arguments_;
+	delete jUnitOutput_;
+}
+
+int CommandLineTestRunner::RunAllTests(int ac, char** av)
+{
+	return RunAllTests(ac, const_cast<const char**> (av));
+}
+
+int CommandLineTestRunner::RunAllTests(int ac, const char** av)
+{
+	int result = 0;
+	ConsoleTestOutput output;
+
+	// MemoryLeakWarningPlugin memLeakWarn(DEF_PLUGIN_MEM_LEAK);
+	// memLeakWarn.destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(true);
+	// TestRegistry::getCurrentRegistry()->installPlugin(&memLeakWarn);
+
+	{
+		CommandLineTestRunner runner(ac, av, &output, TestRegistry::getCurrentRegistry());
+		result = runner.runAllTestsMain();
+	}
+
+	// if (result == 0) {
+	// 	output << memLeakWarn.FinalReport(0);
+	// }
+	// TestRegistry::getCurrentRegistry()->removePluginByName(DEF_PLUGIN_MEM_LEAK);
+	return result;
+}
+
+int CommandLineTestRunner::runAllTestsMain()
+{
+	int testResult = 0;
+
+	SetPointerPlugin pPlugin(DEF_PLUGIN_SET_POINTER);
+	registry_->installPlugin(&pPlugin);
+
+	if (parseArguments(registry_->getFirstPlugin()))
+		testResult = runAllTests();
+
+	registry_->removePluginByName(DEF_PLUGIN_SET_POINTER);
+	return testResult;
+}
+
+void CommandLineTestRunner::initializeTestRun()
+{
+	registry_->groupFilter(arguments_->getGroupFilter());
+	registry_->nameFilter(arguments_->getNameFilter());
+	if (arguments_->isVerbose()) output_->verbose();
+	if (arguments_->runTestsInSeperateProcess()) registry_->setRunTestsInSeperateProcess();
+}
+
+int CommandLineTestRunner::runAllTests()
+{
+	initializeTestRun();
+	int loopCount = 0;
+	int failureCount = 0;
+	int repeat_ = arguments_->getRepeatCount();
+
+	while (loopCount++ < repeat_) {
+		output_->printTestRun(loopCount, repeat_);
+		TestResult tr(*output_);
+		registry_->runAllTests(tr);
+		failureCount += tr.getFailureCount();
+	}
+
+	return failureCount;
+}
+
+bool CommandLineTestRunner::parseArguments(TestPlugin* plugin)
+{
+	if (arguments_->parse(plugin)) {
+		if (arguments_->isJUnitOutput()) {
+			output_ = jUnitOutput_ = new JUnitTestOutput;
+			if (jUnitOutput_ != NULL) {
+				jUnitOutput_->setPackageName(arguments_->getPackageName());
+			}
+		}
+		return true;
+	}
+	else {
+		output_->print(arguments_->usage());
+		return false;
+	}
+}
+
+bool CommandLineTestRunner::isVerbose()
+{
+	return arguments_->isVerbose();
+}
+
+int CommandLineTestRunner::getRepeatCount()
+{
+	return arguments_->getRepeatCount();
+}
+
+TestFilter CommandLineTestRunner::getGroupFilter()
+{
+	return arguments_->getGroupFilter();
+}
+
+TestFilter CommandLineTestRunner::getNameFilter()
+{
+	return arguments_->getNameFilter();
+}
--- a/src/CppUTest/JUnitTestOutput.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/JUnitTestOutput.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,270 +1,280 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/JUnitTestOutput.h"
-#include "CppUTest/TestResult.h"
-#include "CppUTest/TestFailure.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-struct JUnitTestCaseResultNode
-{
-	JUnitTestCaseResultNode() :
-		execTime_(0), failure_(0), next_(0)
-	{
-	}
-
-	SimpleString name_;
-	long execTime_;
-	TestFailure* failure_;
-	JUnitTestCaseResultNode* next_;
-};
-
-struct JUnitTestGroupResult
-{
-	JUnitTestGroupResult() :
-		testCount_(0), failureCount_(0), startTime_(0), groupExecTime_(0), head_(0), tail_(0)
-	{
-	}
-
-	int testCount_;
-	int failureCount_;
-	long startTime_;
-	long groupExecTime_;
-	SimpleString group_;
-	JUnitTestCaseResultNode* head_;
-	JUnitTestCaseResultNode* tail_;
-};
-
-struct JUnitTestOutputImpl
-{
-	JUnitTestGroupResult results_;
-	PlatformSpecificFile file_;
-};
-
-JUnitTestOutput::JUnitTestOutput() :
-	impl_(new JUnitTestOutputImpl)
-{
-}
-
-JUnitTestOutput::~JUnitTestOutput()
-{
-	resetTestGroupResult();
-	delete impl_;
-}
-
-void JUnitTestOutput::resetTestGroupResult()
-{
-	impl_->results_.testCount_ = 0;
-	impl_->results_.failureCount_ = 0;
-	impl_->results_.group_ = "";
-	JUnitTestCaseResultNode* cur = impl_->results_.head_;
-	while (cur) {
-		JUnitTestCaseResultNode* tmp = cur->next_;
-		;
-		if (cur->failure_) delete cur->failure_;
-		delete cur;
-		cur = tmp;
-	}
-	impl_->results_.head_ = 0;
-	impl_->results_.tail_ = 0;
-}
-
-void JUnitTestOutput::printTestsStarted()
-{
-}
-
-void JUnitTestOutput::printCurrentGroupStarted(const UtestShell& /*test*/)
-{
-}
-
-void JUnitTestOutput::printCurrentTestEnded(const TestResult& result)
-{
-	impl_->results_.tail_->execTime_
-			= result.getCurrentTestTotalExecutionTime();
-}
-
-void JUnitTestOutput::printTestsEnded(const TestResult& /*result*/)
-{
-}
-
-void JUnitTestOutput::printCurrentGroupEnded(const TestResult& result)
-{
-	impl_->results_.groupExecTime_ = result.getCurrentGroupTotalExecutionTime();
-	writeTestGroupToFile();
-	resetTestGroupResult();
-}
-
-void JUnitTestOutput::printCurrentTestStarted(const UtestShell& test)
-{
-	impl_->results_.testCount_++;
-	impl_->results_.group_ = test.getGroup();
-	impl_->results_.startTime_ = GetPlatformSpecificTimeInMillis();
-
-	if (impl_->results_.tail_ == 0) {
-		impl_->results_.head_ = impl_->results_.tail_
-				= new JUnitTestCaseResultNode;
-	}
-	else {
-		impl_->results_.tail_->next_ = new JUnitTestCaseResultNode;
-		impl_->results_.tail_ = impl_->results_.tail_->next_;
-	}
-	impl_->results_.tail_->name_ = test.getName();
-}
-
-SimpleString JUnitTestOutput::createFileName(const SimpleString& group)
-{
-	SimpleString fileName = "cpputest_";
-	fileName += group;
-	fileName.replace('/', '_');
-	fileName += ".xml";
-	return fileName;
-}
-
-void JUnitTestOutput::writeXmlHeader()
-{
-	writeToFile("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
-}
-
-void JUnitTestOutput::writeTestSuiteSummery()
-{
-	SimpleString
-			buf =
-					StringFromFormat(
-							"<testsuite errors=\"0\" failures=\"%d\" hostname=\"localhost\" name=\"%s\" tests=\"%d\" time=\"%d.%03d\" timestamp=\"%s\">\n",
-							impl_->results_.failureCount_,
-							impl_->results_.group_.asCharString(),
-							impl_->results_.testCount_,
-							(int) (impl_->results_.groupExecTime_ / 1000), (int) (impl_->results_.groupExecTime_ % 1000),
-							GetPlatformSpecificTimeString());
-	writeToFile(buf.asCharString());
-}
-
-void JUnitTestOutput::writeProperties()
-{
-	writeToFile("<properties>\n");
-	writeToFile("</properties>\n");
-}
-
-void JUnitTestOutput::writeTestCases()
-{
-	JUnitTestCaseResultNode* cur = impl_->results_.head_;
-	while (cur) {
-		SimpleString buf = StringFromFormat(
-				"<testcase classname=\"%s\" name=\"%s\" time=\"%d.%03d\">\n",
-				impl_->results_.group_.asCharString(),
-				cur->name_.asCharString(), (int) (cur->execTime_ / 1000), (int)(cur->execTime_ % 1000));
-		writeToFile(buf.asCharString());
-
-		if (cur->failure_) {
-			writeFailure(cur);
-		}
-		writeToFile("</testcase>\n");
-		cur = cur->next_;
-	}
-}
-
-void JUnitTestOutput::writeFailure(JUnitTestCaseResultNode* node)
-{
-	SimpleString message = node->failure_->getMessage().asCharString();
-	message.replace('"', '\'');
-	message.replace('<', '[');
-	message.replace('>', ']');
-	message.replace("&", "&amp;");
-	message.replace("\n", "{newline}");
-	SimpleString buf = StringFromFormat(
-			"<failure message=\"%s:%d: %s\" type=\"AssertionFailedError\">\n",
-			node->failure_->getFileName().asCharString(),
-			node->failure_->getFailureLineNumber(), message.asCharString());
-	writeToFile(buf.asCharString());
-	writeToFile("</failure>\n");
-}
-
-void JUnitTestOutput::writeFileEnding()
-{
-	writeToFile("<system-out></system-out>\n");
-	writeToFile("<system-err></system-err>\n");
-	writeToFile("</testsuite>");
-}
-
-void JUnitTestOutput::writeTestGroupToFile()
-{
-	openFileForWrite(createFileName(impl_->results_.group_));
-	writeXmlHeader();
-	writeTestSuiteSummery();
-	writeProperties();
-	writeTestCases();
-	writeFileEnding();
-	closeFile();
-}
-
-void JUnitTestOutput::verbose()
-{
-}
-
-void JUnitTestOutput::printBuffer(const char*)
-{
-}
-
-void JUnitTestOutput::print(const char*)
-{
-}
-
-void JUnitTestOutput::print(long)
-{
-}
-
-void JUnitTestOutput::print(const TestFailure& failure)
-{
-	if (impl_->results_.tail_->failure_ == 0) {
-		impl_->results_.failureCount_++;
-		impl_->results_.tail_->failure_ = new TestFailure(failure);
-	}
-}
-
-void JUnitTestOutput::printTestRun(int /*number*/, int /*total*/)
-{
-}
-
-void JUnitTestOutput::flush()
-{
-}
-
-void JUnitTestOutput::openFileForWrite(const SimpleString& fileName)
-{
-	impl_->file_ = PlatformSpecificFOpen(fileName.asCharString(), "w");
-}
-
-void JUnitTestOutput::writeToFile(const SimpleString& buffer)
-{
-	PlatformSpecificFPuts(buffer.asCharString(), impl_->file_);
-}
-
-void JUnitTestOutput::closeFile()
-{
-	PlatformSpecificFClose(impl_->file_);
-}
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/JUnitTestOutput.h"
+#include "CppUTest/TestResult.h"
+#include "CppUTest/TestFailure.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+struct JUnitTestCaseResultNode
+{
+	JUnitTestCaseResultNode() :
+		execTime_(0), failure_(0), next_(0)
+	{
+	}
+
+	SimpleString name_;
+	long execTime_;
+	TestFailure* failure_;
+	JUnitTestCaseResultNode* next_;
+};
+
+struct JUnitTestGroupResult
+{
+	JUnitTestGroupResult() :
+		testCount_(0), failureCount_(0), startTime_(0), groupExecTime_(0), head_(0), tail_(0)
+	{
+	}
+
+	int testCount_;
+	int failureCount_;
+	long startTime_;
+	long groupExecTime_;
+	SimpleString group_;
+	JUnitTestCaseResultNode* head_;
+	JUnitTestCaseResultNode* tail_;
+};
+
+struct JUnitTestOutputImpl
+{
+	JUnitTestGroupResult results_;
+	PlatformSpecificFile file_;
+	SimpleString package_;
+};
+
+JUnitTestOutput::JUnitTestOutput() :
+	impl_(new JUnitTestOutputImpl)
+{
+}
+
+JUnitTestOutput::~JUnitTestOutput()
+{
+	resetTestGroupResult();
+	delete impl_;
+}
+
+void JUnitTestOutput::resetTestGroupResult()
+{
+	impl_->results_.testCount_ = 0;
+	impl_->results_.failureCount_ = 0;
+	impl_->results_.group_ = "";
+	JUnitTestCaseResultNode* cur = impl_->results_.head_;
+	while (cur) {
+		JUnitTestCaseResultNode* tmp = cur->next_;
+		;
+		delete cur->failure_;
+		delete cur;
+		cur = tmp;
+	}
+	impl_->results_.head_ = 0;
+	impl_->results_.tail_ = 0;
+}
+
+void JUnitTestOutput::printTestsStarted()
+{
+}
+
+void JUnitTestOutput::printCurrentGroupStarted(const UtestShell& /*test*/)
+{
+}
+
+void JUnitTestOutput::printCurrentTestEnded(const TestResult& result)
+{
+	impl_->results_.tail_->execTime_
+			= result.getCurrentTestTotalExecutionTime();
+}
+
+void JUnitTestOutput::printTestsEnded(const TestResult& /*result*/)
+{
+}
+
+void JUnitTestOutput::printCurrentGroupEnded(const TestResult& result)
+{
+	impl_->results_.groupExecTime_ = result.getCurrentGroupTotalExecutionTime();
+	writeTestGroupToFile();
+	resetTestGroupResult();
+}
+
+void JUnitTestOutput::printCurrentTestStarted(const UtestShell& test)
+{
+	impl_->results_.testCount_++;
+	impl_->results_.group_ = test.getGroup();
+	impl_->results_.startTime_ = GetPlatformSpecificTimeInMillis();
+
+	if (impl_->results_.tail_ == 0) {
+		impl_->results_.head_ = impl_->results_.tail_
+				= new JUnitTestCaseResultNode;
+	}
+	else {
+		impl_->results_.tail_->next_ = new JUnitTestCaseResultNode;
+		impl_->results_.tail_ = impl_->results_.tail_->next_;
+	}
+	impl_->results_.tail_->name_ = test.getName();
+}
+
+SimpleString JUnitTestOutput::createFileName(const SimpleString& group)
+{
+	SimpleString fileName = "cpputest_";
+	fileName += group;
+	fileName.replace('/', '_');
+	fileName += ".xml";
+	return fileName;
+}
+
+void JUnitTestOutput::setPackageName(const SimpleString& package)
+{
+	if (impl_ != NULL) {
+		impl_->package_ = package;
+	}
+}
+
+void JUnitTestOutput::writeXmlHeader()
+{
+	writeToFile("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+}
+
+void JUnitTestOutput::writeTestSuiteSummery()
+{
+	SimpleString
+			buf =
+					StringFromFormat(
+							"<testsuite errors=\"0\" failures=\"%d\" hostname=\"localhost\" name=\"%s\" tests=\"%d\" time=\"%d.%03d\" timestamp=\"%s\">\n",
+							impl_->results_.failureCount_,
+							impl_->results_.group_.asCharString(),
+							impl_->results_.testCount_,
+							(int) (impl_->results_.groupExecTime_ / 1000), (int) (impl_->results_.groupExecTime_ % 1000),
+							GetPlatformSpecificTimeString());
+	writeToFile(buf.asCharString());
+}
+
+void JUnitTestOutput::writeProperties()
+{
+	writeToFile("<properties>\n");
+	writeToFile("</properties>\n");
+}
+
+void JUnitTestOutput::writeTestCases()
+{
+	JUnitTestCaseResultNode* cur = impl_->results_.head_;
+	while (cur) {
+		SimpleString buf = StringFromFormat(
+				"<testcase classname=\"%s%s%s\" name=\"%s\" time=\"%d.%03d\">\n",
+				impl_->package_.asCharString(),
+				impl_->package_.isEmpty() == true ? "" : ".",
+				impl_->results_.group_.asCharString(),
+				cur->name_.asCharString(), (int) (cur->execTime_ / 1000), (int)(cur->execTime_ % 1000));
+		writeToFile(buf.asCharString());
+
+		if (cur->failure_) {
+			writeFailure(cur);
+		}
+		writeToFile("</testcase>\n");
+		cur = cur->next_;
+	}
+}
+
+void JUnitTestOutput::writeFailure(JUnitTestCaseResultNode* node)
+{
+	SimpleString message = node->failure_->getMessage().asCharString();
+	message.replace('"', '\'');
+	message.replace('<', '[');
+	message.replace('>', ']');
+	message.replace("&", "&amp;");
+	message.replace("\n", "{newline}");
+	SimpleString buf = StringFromFormat(
+			"<failure message=\"%s:%d: %s\" type=\"AssertionFailedError\">\n",
+			node->failure_->getFileName().asCharString(),
+			node->failure_->getFailureLineNumber(), message.asCharString());
+	writeToFile(buf.asCharString());
+	writeToFile("</failure>\n");
+}
+
+void JUnitTestOutput::writeFileEnding()
+{
+	writeToFile("<system-out></system-out>\n");
+	writeToFile("<system-err></system-err>\n");
+	writeToFile("</testsuite>");
+}
+
+void JUnitTestOutput::writeTestGroupToFile()
+{
+	openFileForWrite(createFileName(impl_->results_.group_));
+	writeXmlHeader();
+	writeTestSuiteSummery();
+	writeProperties();
+	writeTestCases();
+	writeFileEnding();
+	closeFile();
+}
+
+void JUnitTestOutput::verbose()
+{
+}
+
+void JUnitTestOutput::printBuffer(const char*)
+{
+}
+
+void JUnitTestOutput::print(const char*)
+{
+}
+
+void JUnitTestOutput::print(long)
+{
+}
+
+void JUnitTestOutput::print(const TestFailure& failure)
+{
+	if (impl_->results_.tail_->failure_ == 0) {
+		impl_->results_.failureCount_++;
+		impl_->results_.tail_->failure_ = new TestFailure(failure);
+	}
+}
+
+void JUnitTestOutput::printTestRun(int /*number*/, int /*total*/)
+{
+}
+
+void JUnitTestOutput::flush()
+{
+}
+
+void JUnitTestOutput::openFileForWrite(const SimpleString& fileName)
+{
+	impl_->file_ = PlatformSpecificFOpen(fileName.asCharString(), "w");
+}
+
+void JUnitTestOutput::writeToFile(const SimpleString& buffer)
+{
+	PlatformSpecificFPuts(buffer.asCharString(), impl_->file_);
+}
+
+void JUnitTestOutput::closeFile()
+{
+	PlatformSpecificFClose(impl_->file_);
+}
--- a/src/CppUTest/MemoryLeakDetector.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/MemoryLeakDetector.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,621 +1,621 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/MemoryLeakDetector.h"
-#include "CppUTest/TestMemoryAllocator.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-#define UNKNOWN ((char*)("<unknown>"))
-
-SimpleStringBuffer::SimpleStringBuffer() :
-	positions_filled_(0), write_limit_(SIMPLE_STRING_BUFFER_LEN-1)
-{
-}
-
-void SimpleStringBuffer::clear()
-{
-	positions_filled_ = 0;
-	buffer_[0] = '\0';
-}
-
-void SimpleStringBuffer::add(const char* format, ...)
-{
-	int count = 0;
-	size_t positions_left = write_limit_ - positions_filled_;
-	if (positions_left <= 0) return;
-
-	va_list arguments;
-	va_start(arguments, format);
-	count = PlatformSpecificVSNprintf(buffer_ + positions_filled_, positions_left+1, format, arguments);
-    if (count > 0) positions_filled_ += (size_t) count;
-	if (positions_filled_ > write_limit_) positions_filled_ = write_limit_;
-	va_end(arguments);
-}
-
-char* SimpleStringBuffer::toString()
-{
-	return buffer_;
-}
-
-void SimpleStringBuffer::setWriteLimit(size_t write_limit)
-{
-	write_limit_ = write_limit;
-	if (write_limit_ > SIMPLE_STRING_BUFFER_LEN-1)
-		write_limit_ = SIMPLE_STRING_BUFFER_LEN-1;
-}
-void SimpleStringBuffer::resetWriteLimit()
-{
-	write_limit_ = SIMPLE_STRING_BUFFER_LEN-1;
-}
-
-bool SimpleStringBuffer::reachedItsCapacity()
-{
-	return positions_filled_ >= write_limit_;
-}
-
-////////////////////////
-
-#define MEM_LEAK_TOO_MUCH "\netc etc etc etc. !!!! Too much memory leaks to report. Bailing out\n"
-#define MEM_LEAK_FOOTER "Total number of leaks: "
-#define MEM_LEAK_ADDITION_MALLOC_WARNING "NOTE:\n" \
-										 "\tMemory leak reports about malloc and free can be caused by allocating using the cpputest version of malloc,\n" \
-										 "\tbut deallocate using the standard free.\n" \
-										 "\tIf this is the case, check whether your malloc/free replacements are working (#define malloc cpputest_malloc etc).\n"
-
-MemoryLeakOutputStringBuffer::MemoryLeakOutputStringBuffer()
-	: total_leaks_(0), giveWarningOnUsingMalloc_(false)
-{
-}
-
-void MemoryLeakOutputStringBuffer::addAllocationLocation(const char* allocationFile, int allocationLineNumber, size_t allocationSize, TestMemoryAllocator* allocator)
-{
-	outputBuffer_.add("   allocated at file: %s line: %d size: %lu type: %s\n", allocationFile, allocationLineNumber, (unsigned long) allocationSize, allocator->alloc_name());
-}
-
-void MemoryLeakOutputStringBuffer::addDeallocationLocation(const char* freeFile, int freeLineNumber, TestMemoryAllocator* allocator)
-{
-	outputBuffer_.add("   deallocated at file: %s line: %d type: %s\n", freeFile, freeLineNumber, allocator->free_name());
-}
-
-void MemoryLeakOutputStringBuffer::addNoMemoryLeaksMessage()
-{
-	outputBuffer_.add("No memory leaks were detected.");
-}
-
-void MemoryLeakOutputStringBuffer::startMemoryLeakReporting()
-{
-	giveWarningOnUsingMalloc_ = false;
-	total_leaks_ = 0;
-
-	size_t memory_leak_normal_footer_size = sizeof(MEM_LEAK_FOOTER) + 10 + sizeof(MEM_LEAK_TOO_MUCH); /* the number of leaks */
-	size_t memory_leak_foot_size_with_malloc_warning = memory_leak_normal_footer_size + sizeof(MEM_LEAK_ADDITION_MALLOC_WARNING);
-
-	outputBuffer_.setWriteLimit(SimpleStringBuffer::SIMPLE_STRING_BUFFER_LEN - memory_leak_foot_size_with_malloc_warning);
-}
-
-void MemoryLeakOutputStringBuffer::reportMemoryLeak(MemoryLeakDetectorNode* leak)
-{
-	if (total_leaks_ == 0) {
-		addMemoryLeakHeader();
-	}
-
-	total_leaks_++;
-	outputBuffer_.add("Alloc num (%u) Leak size: %lu Allocated at: %s and line: %d. Type: \"%s\"\n\t Memory: <%p> Content: \"%.15s\"\n",
-			leak->number_, (unsigned long) leak->size_, leak->file_, leak->line_, leak->allocator_->alloc_name(), leak->memory_, leak->memory_);
-
-	if (PlatformSpecificStrCmp(leak->allocator_->alloc_name(), "malloc") == 0)
-		giveWarningOnUsingMalloc_ = true;
-}
-
-void MemoryLeakOutputStringBuffer::stopMemoryLeakReporting()
-{
-	if (total_leaks_ == 0) {
-		addNoMemoryLeaksMessage();
-		return;
-	}
-
-	bool buffer_reached_its_capacity = outputBuffer_.reachedItsCapacity();
-	outputBuffer_.resetWriteLimit();
-
-	if (buffer_reached_its_capacity)
-		addErrorMessageForTooMuchLeaks();
-
-	addMemoryLeakFooter(total_leaks_);
-
-	if (giveWarningOnUsingMalloc_)
-		addWarningForUsingMalloc();
-
-}
-
-void MemoryLeakOutputStringBuffer::addMemoryLeakHeader()
-{
-	outputBuffer_.add("Memory leak(s) found.\n");
-}
-
-void MemoryLeakOutputStringBuffer::addErrorMessageForTooMuchLeaks()
-{
-	outputBuffer_.add(MEM_LEAK_TOO_MUCH);
-}
-
-void MemoryLeakOutputStringBuffer::addMemoryLeakFooter(int amountOfLeaks)
-{
-	outputBuffer_.add("%s %d\n", MEM_LEAK_FOOTER, amountOfLeaks);
-}
-
-void MemoryLeakOutputStringBuffer::addWarningForUsingMalloc()
-{
-	outputBuffer_.add(MEM_LEAK_ADDITION_MALLOC_WARNING);
-}
-
-void MemoryLeakOutputStringBuffer::reportDeallocateNonAllocatedMemoryFailure(const char* freeFile, int freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
-{
-	reportFailure("Deallocating non-allocated memory\n", "<unknown>", 0, 0, NullUnknownAllocator::defaultAllocator(), freeFile, freeLine, freeAllocator, reporter);
-}
-
-void MemoryLeakOutputStringBuffer::reportAllocationDeallocationMismatchFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
-{
-	reportFailure("Allocation/deallocation type mismatch\n", node->file_, node->line_, node->size_, node->allocator_, freeFile, freeLineNumber, freeAllocator, reporter);
-}
-
-void MemoryLeakOutputStringBuffer::reportMemoryCorruptionFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
-{
-		reportFailure("Memory corruption (written out of bounds?)\n", node->file_, node->line_, node->size_, node->allocator_, freeFile, freeLineNumber, freeAllocator, reporter);
-}
-
-void MemoryLeakOutputStringBuffer::reportFailure(const char* message, const char* allocFile, int allocLine, size_t allocSize, TestMemoryAllocator* allocAllocator, const char* freeFile, int freeLine,
-		TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
-{
-	outputBuffer_.add("%s", message);
-	addAllocationLocation(allocFile, allocLine, allocSize, allocAllocator);
-	addDeallocationLocation(freeFile, freeLine, freeAllocator);
-	reporter->fail(toString());
-}
-
-
-char* MemoryLeakOutputStringBuffer::toString()
-{
-	return outputBuffer_.toString();
-}
-
-void MemoryLeakOutputStringBuffer::clear()
-{
-	outputBuffer_.clear();
-}
-
-////////////////////////
-
-void MemoryLeakDetectorNode::init(char* memory, unsigned number, size_t size, TestMemoryAllocator* allocator, MemLeakPeriod period, const char* file, int line)
-{
-	number_ = number;
-	memory_ = memory;
-	size_ = size;
-	allocator_ = allocator;
-	period_ = period;
-	file_ = file;
-	line_ = line;
-}
-
-///////////////////////
-
-bool MemoryLeakDetectorList::isInPeriod(MemoryLeakDetectorNode* node, MemLeakPeriod period)
-{
-	return period == mem_leak_period_all || node->period_ == period || (node->period_ != mem_leak_period_disabled && period == mem_leak_period_enabled);
-}
-
-void MemoryLeakDetectorList::clearAllAccounting(MemLeakPeriod period)
-{
-	MemoryLeakDetectorNode* cur = head_;
-	MemoryLeakDetectorNode* prev = 0;
-
-	while (cur) {
-		if (isInPeriod(cur, period)) {
-			if (prev) {
-				prev->next_ = cur->next_;
-				cur = prev;
-			}
-			else {
-				head_ = cur->next_;
-				cur = head_;
-				continue;
-			}
-		}
-		prev = cur;
-		cur = cur->next_;
-	}
-}
-
-void MemoryLeakDetectorList::addNewNode(MemoryLeakDetectorNode* node)
-{
-	node->next_ = head_;
-	head_ = node;
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorList::removeNode(char* memory)
-{
-	MemoryLeakDetectorNode* cur = head_;
-	MemoryLeakDetectorNode* prev = 0;
-	while (cur) {
-		if (cur->memory_ == memory) {
-			if (prev) {
-				prev->next_ = cur->next_;
-				return cur;
-			}
-			else {
-				head_ = cur->next_;
-				return cur;
-			}
-		}
-		prev = cur;
-		cur = cur->next_;
-	}
-	return 0;
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorList::retrieveNode(char* memory)
-{
-  MemoryLeakDetectorNode* cur = head_;
-  while (cur) {
-    if (cur->memory_ == memory)
-      return cur;
-    cur = cur->next_;
-  }
-  return NULL;
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorList::getLeakFrom(MemoryLeakDetectorNode* node, MemLeakPeriod period)
-{
-	for (MemoryLeakDetectorNode* cur = node; cur; cur = cur->next_)
-		if (isInPeriod(cur, period)) return cur;
-	return 0;
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorList::getFirstLeak(MemLeakPeriod period)
-{
-	return getLeakFrom(head_, period);
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorList::getNextLeak(MemoryLeakDetectorNode* node, MemLeakPeriod period)
-{
-	return getLeakFrom(node->next_, period);
-}
-
-int MemoryLeakDetectorList::getTotalLeaks(MemLeakPeriod period)
-{
-	int total_leaks = 0;
-	for (MemoryLeakDetectorNode* node = head_; node; node = node->next_) {
-		if (isInPeriod(node, period)) total_leaks++;
-	}
-	return total_leaks;
-}
-
-bool MemoryLeakDetectorList::hasLeaks(MemLeakPeriod period)
-{
-	for (MemoryLeakDetectorNode* node = head_; node; node = node->next_)
-		if (isInPeriod(node, period)) return true;
-	return false;
-}
-
-/////////////////////////////////////////////////////////////
-
-unsigned long MemoryLeakDetectorTable::hash(char* memory)
-{
-	return (unsigned long)((size_t)memory % hash_prime);
-}
-
-void MemoryLeakDetectorTable::clearAllAccounting(MemLeakPeriod period)
-{
-	for (int i = 0; i < hash_prime; i++)
-		table_[i].clearAllAccounting(period);
-}
-
-void MemoryLeakDetectorTable::addNewNode(MemoryLeakDetectorNode* node)
-{
-	table_[hash(node->memory_)].addNewNode(node);
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorTable::removeNode(char* memory)
-{
-	return table_[hash(memory)].removeNode(memory);
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorTable::retrieveNode(char* memory)
-{
-  return table_[hash(memory)].retrieveNode(memory);
-}
-
-bool MemoryLeakDetectorTable::hasLeaks(MemLeakPeriod period)
-{
-	for (int i = 0; i < hash_prime; i++)
-		if (table_[i].hasLeaks(period)) return true;
-	return false;
-}
-
-int MemoryLeakDetectorTable::getTotalLeaks(MemLeakPeriod period)
-{
-	int total_leaks = 0;
-	for (int i = 0; i < hash_prime; i++)
-		total_leaks += table_[i].getTotalLeaks(period);
-	return total_leaks;
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorTable::getFirstLeak(MemLeakPeriod period)
-{
-	for (int i = 0; i < hash_prime; i++) {
-		MemoryLeakDetectorNode* node = table_[i].getFirstLeak(period);
-		if (node) return node;
-	}
-	return 0;
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetectorTable::getNextLeak(MemoryLeakDetectorNode* leak, MemLeakPeriod period)
-{
-	unsigned long i = hash(leak->memory_);
-	MemoryLeakDetectorNode* node = table_[i].getNextLeak(leak, period);
-	if (node) return node;
-
-	for (++i; i < hash_prime; i++) {
-		node = table_[i].getFirstLeak(period);
-		if (node) return node;
-	}
-	return 0;
-}
-
-/////////////////////////////////////////////////////////////
-
-MemoryLeakDetector::MemoryLeakDetector(MemoryLeakFailure* reporter)
-{
-	doAllocationTypeChecking_ = true;
-	allocationSequenceNumber_ = 1;
-	current_period_ = mem_leak_period_disabled;
-	reporter_ = reporter;
-	outputBuffer_ = MemoryLeakOutputStringBuffer();
-	memoryTable_ = MemoryLeakDetectorTable();
-}
-
-void MemoryLeakDetector::clearAllAccounting(MemLeakPeriod period)
-{
-	memoryTable_.clearAllAccounting(period);
-}
-
-void MemoryLeakDetector::startChecking()
-{
-	outputBuffer_.clear();
-	current_period_ = mem_leak_period_checking;
-}
-
-void MemoryLeakDetector::stopChecking()
-{
-	current_period_ = mem_leak_period_enabled;
-}
-
-void MemoryLeakDetector::enable()
-{
-	current_period_ = mem_leak_period_enabled;
-}
-
-void MemoryLeakDetector::disable()
-{
-	current_period_ = mem_leak_period_disabled;
-}
-
-void MemoryLeakDetector::disableAllocationTypeChecking()
-{
-	doAllocationTypeChecking_ = false;
-}
-
-void MemoryLeakDetector::enableAllocationTypeChecking()
-{
-	doAllocationTypeChecking_ = true;
-}
-
-unsigned MemoryLeakDetector::getCurrentAllocationNumber()
-{
-	return allocationSequenceNumber_;
-}
-
-static size_t calculateVoidPointerAlignedSize(size_t size)
-{
-	return (sizeof(void*) - (size % sizeof(void*))) + size;
-}
-
-size_t MemoryLeakDetector::sizeOfMemoryWithCorruptionInfo(size_t size)
-{
-	return calculateVoidPointerAlignedSize(size + memory_corruption_buffer_size);
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetector::getNodeFromMemoryPointer(char* memory, size_t memory_size)
-{
-	return (MemoryLeakDetectorNode*) (void*) (memory + sizeOfMemoryWithCorruptionInfo(memory_size));
-}
-
-void MemoryLeakDetector::storeLeakInformation(MemoryLeakDetectorNode * node, char *new_memory, size_t size, TestMemoryAllocator *allocator, const char *file, int line)
-{
-	node->init(new_memory, allocationSequenceNumber_++, size, allocator, current_period_, file, line);
-	addMemoryCorruptionInformation(node->memory_ + node->size_);
-	memoryTable_.addNewNode(node);
-}
-
-char* MemoryLeakDetector::reallocateMemoryAndLeakInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately)
-{
-	char* new_memory = reallocateMemoryWithAccountingInformation(allocator, memory, size, file, line, allocatNodesSeperately);
-	if (new_memory == NULL) return NULL;
-
-	MemoryLeakDetectorNode *node = createMemoryLeakAccountingInformation(allocator, size, new_memory, allocatNodesSeperately);
-	storeLeakInformation(node, new_memory, size, allocator, file, line);
-	return node->memory_;
-}
-
-void MemoryLeakDetector::invalidateMemory(char* memory)
-{
-  MemoryLeakDetectorNode* node = memoryTable_.retrieveNode(memory);
-  if (node)
-    PlatformSpecificMemset(memory, 0xCD, node->size_);
-}
-
-void MemoryLeakDetector::addMemoryCorruptionInformation(char* memory)
-{
-	memory[0] = 'B';
-	memory[1] = 'A';
-	memory[2] = 'S';
-}
-
-bool MemoryLeakDetector::validMemoryCorruptionInformation(char* memory)
-{
-	return memory[0] == 'B' && memory[1] == 'A' && memory[2] == 'S';
-}
-
-bool MemoryLeakDetector::matchingAllocation(TestMemoryAllocator *alloc_allocator, TestMemoryAllocator *free_allocator)
-{
-	if (alloc_allocator == free_allocator) return true;
-	if (!doAllocationTypeChecking_) return true;
-	return free_allocator->isOfEqualType(alloc_allocator);
-}
-
-void MemoryLeakDetector::checkForCorruption(MemoryLeakDetectorNode* node, const char* file, int line, TestMemoryAllocator* allocator, bool allocateNodesSeperately)
-{
-	if (!matchingAllocation(node->allocator_, allocator))
-		outputBuffer_.reportAllocationDeallocationMismatchFailure(node, file, line, allocator, reporter_);
-	else if (!validMemoryCorruptionInformation(node->memory_ + node->size_))
-		outputBuffer_.reportMemoryCorruptionFailure(node, file, line, allocator, reporter_);
-	else if (allocateNodesSeperately)
-		allocator->freeMemoryLeakNode((char*) node);
-}
-
-char* MemoryLeakDetector::allocMemory(TestMemoryAllocator* allocator, size_t size, bool allocatNodesSeperately)
-{
-	return allocMemory(allocator, size, UNKNOWN, 0, allocatNodesSeperately);
-}
-
-char* MemoryLeakDetector::allocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately)
-{
-	if (allocatNodesSeperately) return allocator->alloc_memory(sizeOfMemoryWithCorruptionInfo(size), file, line);
-	else return allocator->alloc_memory(sizeOfMemoryWithCorruptionInfo(size) + sizeof(MemoryLeakDetectorNode), file, line);
-}
-
-char* MemoryLeakDetector::reallocateMemoryWithAccountingInformation(TestMemoryAllocator* /*allocator*/, char* memory, size_t size, const char* /*file*/, int /*line*/, bool allocatNodesSeperately)
-{
-	if (allocatNodesSeperately) return (char*) PlatformSpecificRealloc(memory, sizeOfMemoryWithCorruptionInfo(size));
-	else return (char*) PlatformSpecificRealloc(memory, sizeOfMemoryWithCorruptionInfo(size) + sizeof(MemoryLeakDetectorNode));
-}
-
-MemoryLeakDetectorNode* MemoryLeakDetector::createMemoryLeakAccountingInformation(TestMemoryAllocator* allocator, size_t size, char* memory, bool allocatNodesSeperately)
-{
-	if (allocatNodesSeperately) return (MemoryLeakDetectorNode*) (void*) allocator->allocMemoryLeakNode(sizeof(MemoryLeakDetectorNode));
-	else return getNodeFromMemoryPointer(memory, size);
-}
-
-char* MemoryLeakDetector::allocMemory(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately)
-{
-	/* With malloc, it is harder to guarantee that the allocator free is called.
-	 * This is because operator new is overloaded via linker symbols, but malloc just via #defines.
-	 * If the same allocation is used and the wrong free is called, it will deallocate the memory leak information
-	 * without the memory leak detector ever noticing it!
-	 * So, for malloc, we'll allocate the memory separately so we can detect this and give a proper error.
-	 */
-
-	char* memory = allocateMemoryWithAccountingInformation(allocator, size, file, line, allocatNodesSeperately);
-	if (memory == NULL) return NULL;
-	MemoryLeakDetectorNode* node = createMemoryLeakAccountingInformation(allocator, size, memory, allocatNodesSeperately);
-
-	storeLeakInformation(node, memory, size, allocator, file, line);
-	return node->memory_;
-}
-
-void MemoryLeakDetector::removeMemoryLeakInformationWithoutCheckingOrDeallocatingTheMemoryButDeallocatingTheAccountInformation(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately)
-{
-	MemoryLeakDetectorNode* node = memoryTable_.removeNode((char*) memory);
-	if (allocatNodesSeperately) allocator->freeMemoryLeakNode( (char*) node);
-}
-
-void MemoryLeakDetector::deallocMemory(TestMemoryAllocator* allocator, void* memory, const char* file, int line, bool allocatNodesSeperately)
-{
-	if (memory == 0) return;
-
-	MemoryLeakDetectorNode* node = memoryTable_.removeNode((char*) memory);
-	if (node == NULL) {
-		outputBuffer_.reportDeallocateNonAllocatedMemoryFailure(file, line, allocator, reporter_);
-		return;
-	}
-	if (!allocator->hasBeenDestroyed()) {
-		checkForCorruption(node, file, line, allocator, allocatNodesSeperately);
-		allocator->free_memory((char*) memory, file, line);
-	}
-}
-
-void MemoryLeakDetector::deallocMemory(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately)
-{
-	deallocMemory(allocator, (char*) memory, UNKNOWN, 0, allocatNodesSeperately);
-}
-
-char* MemoryLeakDetector::reallocMemory(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately)
-{
-	if (memory) {
-		MemoryLeakDetectorNode* node = memoryTable_.removeNode(memory);
-		if (node == NULL) {
-			outputBuffer_.reportDeallocateNonAllocatedMemoryFailure(file, line, allocator, reporter_);
-			return NULL;
-		}
-		checkForCorruption(node, file, line, allocator, allocatNodesSeperately);
-	}
-	return reallocateMemoryAndLeakInformation(allocator, memory, size, file, line, allocatNodesSeperately);
-}
-
-void MemoryLeakDetector::ConstructMemoryLeakReport(MemLeakPeriod period)
-{
-	MemoryLeakDetectorNode* leak = memoryTable_.getFirstLeak(period);
-
-	outputBuffer_.startMemoryLeakReporting();
-
-	while (leak) {
-		outputBuffer_.reportMemoryLeak(leak);
-		leak = memoryTable_.getNextLeak(leak, period);
-	}
-
-	outputBuffer_.stopMemoryLeakReporting();
-}
-
-const char* MemoryLeakDetector::report(MemLeakPeriod period)
-{
-	outputBuffer_.clear();
-	ConstructMemoryLeakReport(period);
-
-	return outputBuffer_.toString();
-}
-
-void MemoryLeakDetector::markCheckingPeriodLeaksAsNonCheckingPeriod()
-{
-	MemoryLeakDetectorNode* leak = memoryTable_.getFirstLeak(mem_leak_period_checking);
-	while (leak) {
-		if (leak->period_ == mem_leak_period_checking) leak->period_ = mem_leak_period_enabled;
-		leak = memoryTable_.getNextLeak(leak, mem_leak_period_checking);
-	}
-}
-
-int MemoryLeakDetector::totalMemoryLeaks(MemLeakPeriod period)
-{
-	return memoryTable_.getTotalLeaks(period);
-}
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/MemoryLeakDetector.h"
+#include "CppUTest/TestMemoryAllocator.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+#define UNKNOWN ((char*)("<unknown>"))
+
+SimpleStringBuffer::SimpleStringBuffer() :
+	positions_filled_(0), write_limit_(SIMPLE_STRING_BUFFER_LEN-1)
+{
+}
+
+void SimpleStringBuffer::clear()
+{
+	positions_filled_ = 0;
+	buffer_[0] = '\0';
+}
+
+void SimpleStringBuffer::add(const char* format, ...)
+{
+	int count = 0;
+	size_t positions_left = write_limit_ - positions_filled_;
+	if (positions_left <= 0) return;
+
+	va_list arguments;
+	va_start(arguments, format);
+	count = PlatformSpecificVSNprintf(buffer_ + positions_filled_, positions_left+1, format, arguments);
+    if (count > 0) positions_filled_ += (size_t) count;
+	if (positions_filled_ > write_limit_) positions_filled_ = write_limit_;
+	va_end(arguments);
+}
+
+char* SimpleStringBuffer::toString()
+{
+	return buffer_;
+}
+
+void SimpleStringBuffer::setWriteLimit(size_t write_limit)
+{
+	write_limit_ = write_limit;
+	if (write_limit_ > SIMPLE_STRING_BUFFER_LEN-1)
+		write_limit_ = SIMPLE_STRING_BUFFER_LEN-1;
+}
+void SimpleStringBuffer::resetWriteLimit()
+{
+	write_limit_ = SIMPLE_STRING_BUFFER_LEN-1;
+}
+
+bool SimpleStringBuffer::reachedItsCapacity()
+{
+	return positions_filled_ >= write_limit_;
+}
+
+////////////////////////
+
+#define MEM_LEAK_TOO_MUCH "\netc etc etc etc. !!!! Too much memory leaks to report. Bailing out\n"
+#define MEM_LEAK_FOOTER "Total number of leaks: "
+#define MEM_LEAK_ADDITION_MALLOC_WARNING "NOTE:\n" \
+										 "\tMemory leak reports about malloc and free can be caused by allocating using the cpputest version of malloc,\n" \
+										 "\tbut deallocate using the standard free.\n" \
+										 "\tIf this is the case, check whether your malloc/free replacements are working (#define malloc cpputest_malloc etc).\n"
+
+MemoryLeakOutputStringBuffer::MemoryLeakOutputStringBuffer()
+	: total_leaks_(0), giveWarningOnUsingMalloc_(false)
+{
+}
+
+void MemoryLeakOutputStringBuffer::addAllocationLocation(const char* allocationFile, int allocationLineNumber, size_t allocationSize, TestMemoryAllocator* allocator)
+{
+	outputBuffer_.add("   allocated at file: %s line: %d size: %lu type: %s\n", allocationFile, allocationLineNumber, (unsigned long) allocationSize, allocator->alloc_name());
+}
+
+void MemoryLeakOutputStringBuffer::addDeallocationLocation(const char* freeFile, int freeLineNumber, TestMemoryAllocator* allocator)
+{
+	outputBuffer_.add("   deallocated at file: %s line: %d type: %s\n", freeFile, freeLineNumber, allocator->free_name());
+}
+
+void MemoryLeakOutputStringBuffer::addNoMemoryLeaksMessage()
+{
+	outputBuffer_.add("No memory leaks were detected.");
+}
+
+void MemoryLeakOutputStringBuffer::startMemoryLeakReporting()
+{
+	giveWarningOnUsingMalloc_ = false;
+	total_leaks_ = 0;
+
+	size_t memory_leak_normal_footer_size = sizeof(MEM_LEAK_FOOTER) + 10 + sizeof(MEM_LEAK_TOO_MUCH); /* the number of leaks */
+	size_t memory_leak_foot_size_with_malloc_warning = memory_leak_normal_footer_size + sizeof(MEM_LEAK_ADDITION_MALLOC_WARNING);
+
+	outputBuffer_.setWriteLimit(SimpleStringBuffer::SIMPLE_STRING_BUFFER_LEN - memory_leak_foot_size_with_malloc_warning);
+}
+
+void MemoryLeakOutputStringBuffer::reportMemoryLeak(MemoryLeakDetectorNode* leak)
+{
+	if (total_leaks_ == 0) {
+		addMemoryLeakHeader();
+	}
+
+	total_leaks_++;
+	outputBuffer_.add("Alloc num (%u) Leak size: %lu Allocated at: %s and line: %d. Type: \"%s\"\n\t Memory: <%p> Content: \"%.15s\"\n",
+			leak->number_, (unsigned long) leak->size_, leak->file_, leak->line_, leak->allocator_->alloc_name(), leak->memory_, leak->memory_);
+
+	if (PlatformSpecificStrCmp(leak->allocator_->alloc_name(), "malloc") == 0)
+		giveWarningOnUsingMalloc_ = true;
+}
+
+void MemoryLeakOutputStringBuffer::stopMemoryLeakReporting()
+{
+	if (total_leaks_ == 0) {
+		addNoMemoryLeaksMessage();
+		return;
+	}
+
+	bool buffer_reached_its_capacity = outputBuffer_.reachedItsCapacity();
+	outputBuffer_.resetWriteLimit();
+
+	if (buffer_reached_its_capacity)
+		addErrorMessageForTooMuchLeaks();
+
+	addMemoryLeakFooter(total_leaks_);
+
+	if (giveWarningOnUsingMalloc_)
+		addWarningForUsingMalloc();
+
+}
+
+void MemoryLeakOutputStringBuffer::addMemoryLeakHeader()
+{
+	outputBuffer_.add("Memory leak(s) found.\n");
+}
+
+void MemoryLeakOutputStringBuffer::addErrorMessageForTooMuchLeaks()
+{
+	outputBuffer_.add(MEM_LEAK_TOO_MUCH);
+}
+
+void MemoryLeakOutputStringBuffer::addMemoryLeakFooter(int amountOfLeaks)
+{
+	outputBuffer_.add("%s %d\n", MEM_LEAK_FOOTER, amountOfLeaks);
+}
+
+void MemoryLeakOutputStringBuffer::addWarningForUsingMalloc()
+{
+	outputBuffer_.add(MEM_LEAK_ADDITION_MALLOC_WARNING);
+}
+
+void MemoryLeakOutputStringBuffer::reportDeallocateNonAllocatedMemoryFailure(const char* freeFile, int freeLine, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
+{
+	reportFailure("Deallocating non-allocated memory\n", "<unknown>", 0, 0, NullUnknownAllocator::defaultAllocator(), freeFile, freeLine, freeAllocator, reporter);
+}
+
+void MemoryLeakOutputStringBuffer::reportAllocationDeallocationMismatchFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
+{
+	reportFailure("Allocation/deallocation type mismatch\n", node->file_, node->line_, node->size_, node->allocator_, freeFile, freeLineNumber, freeAllocator, reporter);
+}
+
+void MemoryLeakOutputStringBuffer::reportMemoryCorruptionFailure(MemoryLeakDetectorNode* node, const char* freeFile, int freeLineNumber, TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
+{
+		reportFailure("Memory corruption (written out of bounds?)\n", node->file_, node->line_, node->size_, node->allocator_, freeFile, freeLineNumber, freeAllocator, reporter);
+}
+
+void MemoryLeakOutputStringBuffer::reportFailure(const char* message, const char* allocFile, int allocLine, size_t allocSize, TestMemoryAllocator* allocAllocator, const char* freeFile, int freeLine,
+		TestMemoryAllocator* freeAllocator, MemoryLeakFailure* reporter)
+{
+	outputBuffer_.add("%s", message);
+	addAllocationLocation(allocFile, allocLine, allocSize, allocAllocator);
+	addDeallocationLocation(freeFile, freeLine, freeAllocator);
+	reporter->fail(toString());
+}
+
+
+char* MemoryLeakOutputStringBuffer::toString()
+{
+	return outputBuffer_.toString();
+}
+
+void MemoryLeakOutputStringBuffer::clear()
+{
+	outputBuffer_.clear();
+}
+
+////////////////////////
+
+void MemoryLeakDetectorNode::init(char* memory, unsigned number, size_t size, TestMemoryAllocator* allocator, MemLeakPeriod period, const char* file, int line)
+{
+	number_ = number;
+	memory_ = memory;
+	size_ = size;
+	allocator_ = allocator;
+	period_ = period;
+	file_ = file;
+	line_ = line;
+}
+
+///////////////////////
+
+bool MemoryLeakDetectorList::isInPeriod(MemoryLeakDetectorNode* node, MemLeakPeriod period)
+{
+	return period == mem_leak_period_all || node->period_ == period || (node->period_ != mem_leak_period_disabled && period == mem_leak_period_enabled);
+}
+
+void MemoryLeakDetectorList::clearAllAccounting(MemLeakPeriod period)
+{
+	MemoryLeakDetectorNode* cur = head_;
+	MemoryLeakDetectorNode* prev = 0;
+
+	while (cur) {
+		if (isInPeriod(cur, period)) {
+			if (prev) {
+				prev->next_ = cur->next_;
+				cur = prev;
+			}
+			else {
+				head_ = cur->next_;
+				cur = head_;
+				continue;
+			}
+		}
+		prev = cur;
+		cur = cur->next_;
+	}
+}
+
+void MemoryLeakDetectorList::addNewNode(MemoryLeakDetectorNode* node)
+{
+	node->next_ = head_;
+	head_ = node;
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorList::removeNode(char* memory)
+{
+	MemoryLeakDetectorNode* cur = head_;
+	MemoryLeakDetectorNode* prev = 0;
+	while (cur) {
+		if (cur->memory_ == memory) {
+			if (prev) {
+				prev->next_ = cur->next_;
+				return cur;
+			}
+			else {
+				head_ = cur->next_;
+				return cur;
+			}
+		}
+		prev = cur;
+		cur = cur->next_;
+	}
+	return 0;
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorList::retrieveNode(char* memory)
+{
+  MemoryLeakDetectorNode* cur = head_;
+  while (cur) {
+    if (cur->memory_ == memory)
+      return cur;
+    cur = cur->next_;
+  }
+  return NULL;
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorList::getLeakFrom(MemoryLeakDetectorNode* node, MemLeakPeriod period)
+{
+	for (MemoryLeakDetectorNode* cur = node; cur; cur = cur->next_)
+		if (isInPeriod(cur, period)) return cur;
+	return 0;
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorList::getFirstLeak(MemLeakPeriod period)
+{
+	return getLeakFrom(head_, period);
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorList::getNextLeak(MemoryLeakDetectorNode* node, MemLeakPeriod period)
+{
+	return getLeakFrom(node->next_, period);
+}
+
+int MemoryLeakDetectorList::getTotalLeaks(MemLeakPeriod period)
+{
+	int total_leaks = 0;
+	for (MemoryLeakDetectorNode* node = head_; node; node = node->next_) {
+		if (isInPeriod(node, period)) total_leaks++;
+	}
+	return total_leaks;
+}
+
+bool MemoryLeakDetectorList::hasLeaks(MemLeakPeriod period)
+{
+	for (MemoryLeakDetectorNode* node = head_; node; node = node->next_)
+		if (isInPeriod(node, period)) return true;
+	return false;
+}
+
+/////////////////////////////////////////////////////////////
+
+unsigned long MemoryLeakDetectorTable::hash(char* memory)
+{
+	return (unsigned long)((size_t)memory % hash_prime);
+}
+
+void MemoryLeakDetectorTable::clearAllAccounting(MemLeakPeriod period)
+{
+	for (int i = 0; i < hash_prime; i++)
+		table_[i].clearAllAccounting(period);
+}
+
+void MemoryLeakDetectorTable::addNewNode(MemoryLeakDetectorNode* node)
+{
+	table_[hash(node->memory_)].addNewNode(node);
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorTable::removeNode(char* memory)
+{
+	return table_[hash(memory)].removeNode(memory);
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorTable::retrieveNode(char* memory)
+{
+  return table_[hash(memory)].retrieveNode(memory);
+}
+
+bool MemoryLeakDetectorTable::hasLeaks(MemLeakPeriod period)
+{
+	for (int i = 0; i < hash_prime; i++)
+		if (table_[i].hasLeaks(period)) return true;
+	return false;
+}
+
+int MemoryLeakDetectorTable::getTotalLeaks(MemLeakPeriod period)
+{
+	int total_leaks = 0;
+	for (int i = 0; i < hash_prime; i++)
+		total_leaks += table_[i].getTotalLeaks(period);
+	return total_leaks;
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorTable::getFirstLeak(MemLeakPeriod period)
+{
+	for (int i = 0; i < hash_prime; i++) {
+		MemoryLeakDetectorNode* node = table_[i].getFirstLeak(period);
+		if (node) return node;
+	}
+	return 0;
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetectorTable::getNextLeak(MemoryLeakDetectorNode* leak, MemLeakPeriod period)
+{
+	unsigned long i = hash(leak->memory_);
+	MemoryLeakDetectorNode* node = table_[i].getNextLeak(leak, period);
+	if (node) return node;
+
+	for (++i; i < hash_prime; i++) {
+		node = table_[i].getFirstLeak(period);
+		if (node) return node;
+	}
+	return 0;
+}
+
+/////////////////////////////////////////////////////////////
+
+MemoryLeakDetector::MemoryLeakDetector(MemoryLeakFailure* reporter)
+{
+	doAllocationTypeChecking_ = true;
+	allocationSequenceNumber_ = 1;
+	current_period_ = mem_leak_period_disabled;
+	reporter_ = reporter;
+	outputBuffer_ = MemoryLeakOutputStringBuffer();
+	memoryTable_ = MemoryLeakDetectorTable();
+}
+
+void MemoryLeakDetector::clearAllAccounting(MemLeakPeriod period)
+{
+	memoryTable_.clearAllAccounting(period);
+}
+
+void MemoryLeakDetector::startChecking()
+{
+	outputBuffer_.clear();
+	current_period_ = mem_leak_period_checking;
+}
+
+void MemoryLeakDetector::stopChecking()
+{
+	current_period_ = mem_leak_period_enabled;
+}
+
+void MemoryLeakDetector::enable()
+{
+	current_period_ = mem_leak_period_enabled;
+}
+
+void MemoryLeakDetector::disable()
+{
+	current_period_ = mem_leak_period_disabled;
+}
+
+void MemoryLeakDetector::disableAllocationTypeChecking()
+{
+	doAllocationTypeChecking_ = false;
+}
+
+void MemoryLeakDetector::enableAllocationTypeChecking()
+{
+	doAllocationTypeChecking_ = true;
+}
+
+unsigned MemoryLeakDetector::getCurrentAllocationNumber()
+{
+	return allocationSequenceNumber_;
+}
+
+static size_t calculateVoidPointerAlignedSize(size_t size)
+{
+	return (sizeof(void*) - (size % sizeof(void*))) + size;
+}
+
+size_t MemoryLeakDetector::sizeOfMemoryWithCorruptionInfo(size_t size)
+{
+	return calculateVoidPointerAlignedSize(size + memory_corruption_buffer_size);
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetector::getNodeFromMemoryPointer(char* memory, size_t memory_size)
+{
+	return (MemoryLeakDetectorNode*) (void*) (memory + sizeOfMemoryWithCorruptionInfo(memory_size));
+}
+
+void MemoryLeakDetector::storeLeakInformation(MemoryLeakDetectorNode * node, char *new_memory, size_t size, TestMemoryAllocator *allocator, const char *file, int line)
+{
+	node->init(new_memory, allocationSequenceNumber_++, size, allocator, current_period_, file, line);
+	addMemoryCorruptionInformation(node->memory_ + node->size_);
+	memoryTable_.addNewNode(node);
+}
+
+char* MemoryLeakDetector::reallocateMemoryAndLeakInformation(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately)
+{
+	char* new_memory = reallocateMemoryWithAccountingInformation(allocator, memory, size, file, line, allocatNodesSeperately);
+	if (new_memory == NULL) return NULL;
+
+	MemoryLeakDetectorNode *node = createMemoryLeakAccountingInformation(allocator, size, new_memory, allocatNodesSeperately);
+	storeLeakInformation(node, new_memory, size, allocator, file, line);
+	return node->memory_;
+}
+
+void MemoryLeakDetector::invalidateMemory(char* memory)
+{
+  MemoryLeakDetectorNode* node = memoryTable_.retrieveNode(memory);
+  if (node)
+    PlatformSpecificMemset(memory, 0xCD, node->size_);
+}
+
+void MemoryLeakDetector::addMemoryCorruptionInformation(char* memory)
+{
+	memory[0] = 'B';
+	memory[1] = 'A';
+	memory[2] = 'S';
+}
+
+bool MemoryLeakDetector::validMemoryCorruptionInformation(char* memory)
+{
+	return memory[0] == 'B' && memory[1] == 'A' && memory[2] == 'S';
+}
+
+bool MemoryLeakDetector::matchingAllocation(TestMemoryAllocator *alloc_allocator, TestMemoryAllocator *free_allocator)
+{
+	if (alloc_allocator == free_allocator) return true;
+	if (!doAllocationTypeChecking_) return true;
+	return free_allocator->isOfEqualType(alloc_allocator);
+}
+
+void MemoryLeakDetector::checkForCorruption(MemoryLeakDetectorNode* node, const char* file, int line, TestMemoryAllocator* allocator, bool allocateNodesSeperately)
+{
+	if (!matchingAllocation(node->allocator_, allocator))
+		outputBuffer_.reportAllocationDeallocationMismatchFailure(node, file, line, allocator, reporter_);
+	else if (!validMemoryCorruptionInformation(node->memory_ + node->size_))
+		outputBuffer_.reportMemoryCorruptionFailure(node, file, line, allocator, reporter_);
+	else if (allocateNodesSeperately)
+		allocator->freeMemoryLeakNode((char*) node);
+}
+
+char* MemoryLeakDetector::allocMemory(TestMemoryAllocator* allocator, size_t size, bool allocatNodesSeperately)
+{
+	return allocMemory(allocator, size, UNKNOWN, 0, allocatNodesSeperately);
+}
+
+char* MemoryLeakDetector::allocateMemoryWithAccountingInformation(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately)
+{
+	if (allocatNodesSeperately) return allocator->alloc_memory(sizeOfMemoryWithCorruptionInfo(size), file, line);
+	else return allocator->alloc_memory(sizeOfMemoryWithCorruptionInfo(size) + sizeof(MemoryLeakDetectorNode), file, line);
+}
+
+char* MemoryLeakDetector::reallocateMemoryWithAccountingInformation(TestMemoryAllocator* /*allocator*/, char* memory, size_t size, const char* /*file*/, int /*line*/, bool allocatNodesSeperately)
+{
+	if (allocatNodesSeperately) return (char*) PlatformSpecificRealloc(memory, sizeOfMemoryWithCorruptionInfo(size));
+	else return (char*) PlatformSpecificRealloc(memory, sizeOfMemoryWithCorruptionInfo(size) + sizeof(MemoryLeakDetectorNode));
+}
+
+MemoryLeakDetectorNode* MemoryLeakDetector::createMemoryLeakAccountingInformation(TestMemoryAllocator* allocator, size_t size, char* memory, bool allocatNodesSeperately)
+{
+	if (allocatNodesSeperately) return (MemoryLeakDetectorNode*) (void*) allocator->allocMemoryLeakNode(sizeof(MemoryLeakDetectorNode));
+	else return getNodeFromMemoryPointer(memory, size);
+}
+
+char* MemoryLeakDetector::allocMemory(TestMemoryAllocator* allocator, size_t size, const char* file, int line, bool allocatNodesSeperately)
+{
+	/* With malloc, it is harder to guarantee that the allocator free is called.
+	 * This is because operator new is overloaded via linker symbols, but malloc just via #defines.
+	 * If the same allocation is used and the wrong free is called, it will deallocate the memory leak information
+	 * without the memory leak detector ever noticing it!
+	 * So, for malloc, we'll allocate the memory separately so we can detect this and give a proper error.
+	 */
+
+	char* memory = allocateMemoryWithAccountingInformation(allocator, size, file, line, allocatNodesSeperately);
+	if (memory == NULL) return NULL;
+	MemoryLeakDetectorNode* node = createMemoryLeakAccountingInformation(allocator, size, memory, allocatNodesSeperately);
+
+	storeLeakInformation(node, memory, size, allocator, file, line);
+	return node->memory_;
+}
+
+void MemoryLeakDetector::removeMemoryLeakInformationWithoutCheckingOrDeallocatingTheMemoryButDeallocatingTheAccountInformation(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately)
+{
+	MemoryLeakDetectorNode* node = memoryTable_.removeNode((char*) memory);
+	if (allocatNodesSeperately) allocator->freeMemoryLeakNode( (char*) node);
+}
+
+void MemoryLeakDetector::deallocMemory(TestMemoryAllocator* allocator, void* memory, const char* file, int line, bool allocatNodesSeperately)
+{
+	if (memory == 0) return;
+
+	MemoryLeakDetectorNode* node = memoryTable_.removeNode((char*) memory);
+	if (node == NULL) {
+		outputBuffer_.reportDeallocateNonAllocatedMemoryFailure(file, line, allocator, reporter_);
+		return;
+	}
+	if (!allocator->hasBeenDestroyed()) {
+		checkForCorruption(node, file, line, allocator, allocatNodesSeperately);
+		allocator->free_memory((char*) memory, file, line);
+	}
+}
+
+void MemoryLeakDetector::deallocMemory(TestMemoryAllocator* allocator, void* memory, bool allocatNodesSeperately)
+{
+	deallocMemory(allocator, (char*) memory, UNKNOWN, 0, allocatNodesSeperately);
+}
+
+char* MemoryLeakDetector::reallocMemory(TestMemoryAllocator* allocator, char* memory, size_t size, const char* file, int line, bool allocatNodesSeperately)
+{
+	if (memory) {
+		MemoryLeakDetectorNode* node = memoryTable_.removeNode(memory);
+		if (node == NULL) {
+			outputBuffer_.reportDeallocateNonAllocatedMemoryFailure(file, line, allocator, reporter_);
+			return NULL;
+		}
+		checkForCorruption(node, file, line, allocator, allocatNodesSeperately);
+	}
+	return reallocateMemoryAndLeakInformation(allocator, memory, size, file, line, allocatNodesSeperately);
+}
+
+void MemoryLeakDetector::ConstructMemoryLeakReport(MemLeakPeriod period)
+{
+	MemoryLeakDetectorNode* leak = memoryTable_.getFirstLeak(period);
+
+	outputBuffer_.startMemoryLeakReporting();
+
+	while (leak) {
+		outputBuffer_.reportMemoryLeak(leak);
+		leak = memoryTable_.getNextLeak(leak, period);
+	}
+
+	outputBuffer_.stopMemoryLeakReporting();
+}
+
+const char* MemoryLeakDetector::report(MemLeakPeriod period)
+{
+	outputBuffer_.clear();
+	ConstructMemoryLeakReport(period);
+
+	return outputBuffer_.toString();
+}
+
+void MemoryLeakDetector::markCheckingPeriodLeaksAsNonCheckingPeriod()
+{
+	MemoryLeakDetectorNode* leak = memoryTable_.getFirstLeak(mem_leak_period_checking);
+	while (leak) {
+		if (leak->period_ == mem_leak_period_checking) leak->period_ = mem_leak_period_enabled;
+		leak = memoryTable_.getNextLeak(leak, mem_leak_period_checking);
+	}
+}
+
+int MemoryLeakDetector::totalMemoryLeaks(MemLeakPeriod period)
+{
+	return memoryTable_.getTotalLeaks(period);
+}
--- a/src/CppUTest/MemoryLeakWarningPlugin.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/MemoryLeakWarningPlugin.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,454 +1,464 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/MemoryLeakWarningPlugin.h"
-#include "CppUTest/MemoryLeakDetector.h"
-#include "CppUTest/TestMemoryAllocator.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-/********** Enabling and disabling for C also *********/
-
-#if CPPUTEST_USE_MEM_LEAK_DETECTION
-
-static void* mem_leak_malloc(size_t size, const char* file, int line)
-{
-	return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentMallocAllocator(), size, file, line, true);
-}
-
-static void mem_leak_free(void* buffer, const char* file, int line)
-{
-	MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) buffer);
-	MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentMallocAllocator(), (char*) buffer, file, line, true);
-}
-
-static void* mem_leak_realloc(void* memory, size_t size, const char* file, int line)
-{
-	return MemoryLeakWarningPlugin::getGlobalDetector()->reallocMemory(getCurrentMallocAllocator(), (char*) memory, size, file, line, true);
-}
-
-#endif
-
-static void* normal_malloc(size_t size, const char*, int)
-{
-	return PlatformSpecificMalloc(size);
-}
-
-static void* normal_realloc(void* memory, size_t size, const char*, int)
-{
-	return PlatformSpecificRealloc(memory, size);
-}
-
-static void normal_free(void* buffer, const char*, int)
-{
-	PlatformSpecificFree(buffer);
-}
-
-#if CPPUTEST_USE_MEM_LEAK_DETECTION
-static void *(*malloc_fptr)(size_t size, const char* file, int line) = mem_leak_malloc;
-static void (*free_fptr)(void* mem, const char* file, int line) = mem_leak_free;
-static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = mem_leak_realloc;
-#else
-static void *(*malloc_fptr)(size_t size, const char* file, int line) = normal_malloc;
-static void (*free_fptr)(void* mem, const char* file, int line) = normal_free;
-static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = normal_realloc;
-#endif
-
-void* cpputest_malloc_location_with_leak_detection(size_t size, const char* file, int line)
-{
-	return malloc_fptr(size, file, line);
-}
-
-void* cpputest_realloc_location_with_leak_detection(void* memory, size_t size, const char* file, int line)
-{
-	return realloc_fptr(memory, size, file, line);
-}
-
-void cpputest_free_location_with_leak_detection(void* buffer, const char* file, int line)
-{
-	free_fptr(buffer, file, line);
-}
-
-/********** C++ *************/
-
-#if CPPUTEST_USE_MEM_LEAK_DETECTION
-#undef new
-
-#if CPPUTEST_USE_STD_CPP_LIB
-#define UT_THROW_BAD_ALLOC_WHEN_NULL(memory) if (memory == NULL) throw std::bad_alloc();
-#else
-#define UT_THROW_BAD_ALLOC_WHEN_NULL(memory)
-#endif
-
-static void* mem_leak_operator_new (size_t size) UT_THROW(std::bad_alloc)
-{
-	void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void* mem_leak_operator_new_nothrow (size_t size) UT_NOTHROW
-{
-	return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
-}
-
-static void* mem_leak_operator_new_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
-{
-	void *memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size, (char*) file, line);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void* mem_leak_operator_new_array (size_t size) UT_THROW(std::bad_alloc)
-{
-	void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void* mem_leak_operator_new_array_nothrow (size_t size) UT_NOTHROW
-{
-	return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
-}
-
-static void* mem_leak_operator_new_array_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
-{
-	void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size, (char*) file, line);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void mem_leak_operator_delete (void* mem) UT_NOTHROW
-{
-	MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
-	MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewAllocator(), (char*) mem);
-}
-
-static void mem_leak_operator_delete_array (void* mem) UT_NOTHROW
-{
-	MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
-	MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewArrayAllocator(), (char*) mem);
-}
-
-static void* normal_operator_new (size_t size) UT_THROW(std::bad_alloc)
-{
-	void* memory = PlatformSpecificMalloc(size);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void* normal_operator_new_nothrow (size_t size) UT_NOTHROW
-{
-	return PlatformSpecificMalloc(size);
-}
-
-static void* normal_operator_new_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc)
-{
-	void* memory = PlatformSpecificMalloc(size);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void* normal_operator_new_array (size_t size) UT_THROW(std::bad_alloc)
-{
-	void* memory = PlatformSpecificMalloc(size);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void* normal_operator_new_array_nothrow (size_t size) UT_NOTHROW
-{
-	return PlatformSpecificMalloc(size);
-}
-
-static void* normal_operator_new_array_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc)
-{
-	void* memory = PlatformSpecificMalloc(size);
-	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
-	return memory;
-}
-
-static void normal_operator_delete (void* mem) UT_NOTHROW
-{
-	PlatformSpecificFree(mem);
-}
-
-static void normal_operator_delete_array (void* mem) UT_NOTHROW
-{
-	PlatformSpecificFree(mem);
-}
-
-static void *(*operator_new_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new;
-static void *(*operator_new_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_nothrow;
-static void *(*operator_new_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_debug;
-static void *(*operator_new_array_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array;
-static void *(*operator_new_array_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_array_nothrow;
-static void *(*operator_new_array_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array_debug;
-static void (*operator_delete_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete;
-static void (*operator_delete_array_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete_array;
-
-void* operator new(size_t size) UT_THROW(std::bad_alloc)
-{
-	return operator_new_fptr(size);
-}
-
-void* operator new(size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
-{
-	return operator_new_debug_fptr(size, file, line);
-}
-
-void operator delete(void* mem) UT_NOTHROW
-{
-	operator_delete_fptr(mem);
-}
-
-void operator delete(void* mem, const char*, int) UT_NOTHROW
-{
-	operator_delete_fptr(mem);
-}
-
-void* operator new[](size_t size) UT_THROW(std::bad_alloc)
-{
-	return operator_new_array_fptr(size);
-}
-
-void* operator new [](size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
-{
-	return operator_new_array_debug_fptr(size, file, line);
-}
-
-void operator delete[](void* mem) UT_NOTHROW
-{
-	 operator_delete_array_fptr(mem);
-}
-
-void operator delete[](void* mem, const char*, int) UT_NOTHROW
-{
-	 operator_delete_array_fptr(mem);
-}
-
-
-#if CPPUTEST_USE_STD_CPP_LIB
-
-void* operator new(size_t size, const std::nothrow_t&) UT_NOTHROW
-{
-	return operator_new_nothrow_fptr(size);
-}
-
-void* operator new[](size_t size, const std::nothrow_t&) UT_NOTHROW
-{
-	return operator_new_array_nothrow_fptr(size);
-}
-
-#else
-
-/* Have a similar method. This avoid unused operator_new_nothrow_fptr warning */
-
-extern void* operator_new_nothrow(size_t size) UT_NOTHROW;
-extern void* operator_new_array_nothrow(size_t size) UT_NOTHROW;
-
-void* operator_new_nothrow(size_t size) UT_NOTHROW
-{
-	return operator_new_nothrow_fptr(size);
-}
-
-void* operator_new_array_nothrow(size_t size) UT_NOTHROW
-{
-	return operator_new_array_nothrow_fptr(size);
-}
-
-#endif
-#endif
-
-void MemoryLeakWarningPlugin::turnOffNewDeleteOverloads()
-{
-#if CPPUTEST_USE_MEM_LEAK_DETECTION
-	operator_new_fptr = normal_operator_new;
-	operator_new_nothrow_fptr = normal_operator_new_nothrow;
-	operator_new_debug_fptr = normal_operator_new_debug;
-	operator_new_array_fptr = normal_operator_new_array;
-	operator_new_array_nothrow_fptr = normal_operator_new_array_nothrow;
-	operator_new_array_debug_fptr = normal_operator_new_array_debug;
-	operator_delete_fptr = normal_operator_delete;
-	operator_delete_array_fptr = normal_operator_delete_array;
-	malloc_fptr = normal_malloc;
-	realloc_fptr = normal_realloc;
-	free_fptr = normal_free;
-
-#endif
-}
-
-void MemoryLeakWarningPlugin::turnOnNewDeleteOverloads()
-{
-#if CPPUTEST_USE_MEM_LEAK_DETECTION
-	operator_new_fptr = mem_leak_operator_new;
-	operator_new_nothrow_fptr = mem_leak_operator_new_nothrow;
-	operator_new_debug_fptr = mem_leak_operator_new_debug;
-	operator_new_array_fptr = mem_leak_operator_new_array;
-	operator_new_array_nothrow_fptr = mem_leak_operator_new_array_nothrow;
-	operator_new_array_debug_fptr = mem_leak_operator_new_array_debug;
-	operator_delete_fptr = mem_leak_operator_delete;
-	operator_delete_array_fptr = mem_leak_operator_delete_array;
-	malloc_fptr = mem_leak_malloc;
-	realloc_fptr = mem_leak_realloc;
-	free_fptr = mem_leak_free;
-#endif
-}
-
-void crash_on_allocation_number(unsigned alloc_number)
-{
-	static CrashOnAllocationAllocator crashAllocator;
-	crashAllocator.setNumberToCrashOn(alloc_number);
-	setCurrentMallocAllocator(&crashAllocator);
-	setCurrentNewAllocator(&crashAllocator);
-	setCurrentNewArrayAllocator(&crashAllocator);
-}
-
-class MemoryLeakWarningReporter: public MemoryLeakFailure
-{
-public:
-	virtual ~MemoryLeakWarningReporter()
-	{
-	}
-
-	virtual void fail(char* fail_string)
-	{
-		UtestShell* currentTest = UtestShell::getCurrent();
-		currentTest->failWith(FailFailure(currentTest, currentTest->getName().asCharString(), currentTest->getLineNumber(), fail_string), TestTerminatorWithoutExceptions());
-	}
-};
-
-static MemoryLeakFailure* globalReporter = 0;
-static MemoryLeakDetector* globalDetector = 0;
-
-MemoryLeakDetector* MemoryLeakWarningPlugin::getGlobalDetector()
-{
-	if (globalDetector == 0) {
-		turnOffNewDeleteOverloads();
-
-		globalReporter = new MemoryLeakWarningReporter;
-		globalDetector = new MemoryLeakDetector(globalReporter);
-
-		turnOnNewDeleteOverloads();
-	}
-	return globalDetector;
-}
-
-MemoryLeakFailure* MemoryLeakWarningPlugin::getGlobalFailureReporter()
-{
-	return globalReporter;
-}
-
-void MemoryLeakWarningPlugin::destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(bool des)
-{
-	destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_ = des;
-}
-
-void MemoryLeakWarningPlugin::setGlobalDetector(MemoryLeakDetector* detector, MemoryLeakFailure* reporter)
-{
-	globalDetector = detector;
-	globalReporter = reporter;
-}
-
-void MemoryLeakWarningPlugin::destroyGlobalDetector()
-{
-	turnOffNewDeleteOverloads();
-	delete globalDetector;
-	delete globalReporter;
-	globalDetector = NULL;
-}
-
-
-MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::firstPlugin_ = 0;
-
-MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::getFirstPlugin()
-{
-	return firstPlugin_;
-}
-
-MemoryLeakDetector* MemoryLeakWarningPlugin::getMemoryLeakDetector()
-{
-	return memLeakDetector_;
-}
-
-void MemoryLeakWarningPlugin::ignoreAllLeaksInTest()
-{
-	ignoreAllWarnings_ = true;
-}
-
-void MemoryLeakWarningPlugin::expectLeaksInTest(int n)
-{
-	expectedLeaks_ = n;
-}
-
-MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector) :
-	TestPlugin(name), ignoreAllWarnings_(false), destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_(false), expectedLeaks_(0)
-{
-	if (firstPlugin_ == 0) firstPlugin_ = this;
-
-	if (localDetector) memLeakDetector_ = localDetector;
-	else memLeakDetector_ = getGlobalDetector();
-
-	memLeakDetector_->enable();
-}
-
-MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin()
-{
-	if (destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_) {
-		MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
-		MemoryLeakWarningPlugin::destroyGlobalDetector();
-	}
-}
-
-void MemoryLeakWarningPlugin::preTestAction(UtestShell& /*test*/, TestResult& result)
-{
-	memLeakDetector_->startChecking();
-	failureCount_ = result.getFailureCount();
-}
-
-void MemoryLeakWarningPlugin::postTestAction(UtestShell& test, TestResult& result)
-{
-	memLeakDetector_->stopChecking();
-	int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_checking);
-
-	if (!ignoreAllWarnings_ && expectedLeaks_ != leaks && failureCount_ == result.getFailureCount()) {
-		TestFailure f(&test, memLeakDetector_->report(mem_leak_period_checking));
-		result.addFailure(f);
-	}
-	memLeakDetector_->markCheckingPeriodLeaksAsNonCheckingPeriod();
-	ignoreAllWarnings_ = false;
-	expectedLeaks_ = 0;
-}
-
-const char* MemoryLeakWarningPlugin::FinalReport(int toBeDeletedLeaks)
-{
-	int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_enabled);
-	if (leaks != toBeDeletedLeaks) return memLeakDetector_->report(mem_leak_period_enabled);
-	return "";
-}
-
-
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/MemoryLeakWarningPlugin.h"
+#include "CppUTest/MemoryLeakDetector.h"
+#include "CppUTest/TestMemoryAllocator.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+/********** Enabling and disabling for C also *********/
+
+#if CPPUTEST_USE_MEM_LEAK_DETECTION
+
+static void* mem_leak_malloc(size_t size, const char* file, int line)
+{
+	return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentMallocAllocator(), size, file, line, true);
+}
+
+static void mem_leak_free(void* buffer, const char* file, int line)
+{
+	MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) buffer);
+	MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentMallocAllocator(), (char*) buffer, file, line, true);
+}
+
+static void* mem_leak_realloc(void* memory, size_t size, const char* file, int line)
+{
+	return MemoryLeakWarningPlugin::getGlobalDetector()->reallocMemory(getCurrentMallocAllocator(), (char*) memory, size, file, line, true);
+}
+
+#endif
+
+static void* normal_malloc(size_t size, const char*, int)
+{
+	return PlatformSpecificMalloc(size);
+}
+
+static void* normal_realloc(void* memory, size_t size, const char*, int)
+{
+	return PlatformSpecificRealloc(memory, size);
+}
+
+static void normal_free(void* buffer, const char*, int)
+{
+	PlatformSpecificFree(buffer);
+}
+
+#if CPPUTEST_USE_MEM_LEAK_DETECTION
+static void *(*malloc_fptr)(size_t size, const char* file, int line) = mem_leak_malloc;
+static void (*free_fptr)(void* mem, const char* file, int line) = mem_leak_free;
+static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = mem_leak_realloc;
+#else
+static void *(*malloc_fptr)(size_t size, const char* file, int line) = normal_malloc;
+static void (*free_fptr)(void* mem, const char* file, int line) = normal_free;
+static void*(*realloc_fptr)(void* memory, size_t size, const char* file, int line) = normal_realloc;
+#endif
+
+void* cpputest_malloc_location_with_leak_detection(size_t size, const char* file, int line)
+{
+	return malloc_fptr(size, file, line);
+}
+
+void* cpputest_realloc_location_with_leak_detection(void* memory, size_t size, const char* file, int line)
+{
+	return realloc_fptr(memory, size, file, line);
+}
+
+void cpputest_free_location_with_leak_detection(void* buffer, const char* file, int line)
+{
+	free_fptr(buffer, file, line);
+}
+
+/********** C++ *************/
+
+#if CPPUTEST_USE_MEM_LEAK_DETECTION
+#undef new
+
+#if CPPUTEST_USE_STD_CPP_LIB
+#define UT_THROW_BAD_ALLOC_WHEN_NULL(memory) if (memory == NULL) throw std::bad_alloc();
+#else
+#define UT_THROW_BAD_ALLOC_WHEN_NULL(memory)
+#endif
+
+static void* mem_leak_operator_new (size_t size) UT_THROW(std::bad_alloc)
+{
+	void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void* mem_leak_operator_new_nothrow (size_t size) UT_NOTHROW
+{
+	return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size);
+}
+
+static void* mem_leak_operator_new_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
+{
+	void *memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewAllocator(), size, (char*) file, line);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void* mem_leak_operator_new_array (size_t size) UT_THROW(std::bad_alloc)
+{
+	void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void* mem_leak_operator_new_array_nothrow (size_t size) UT_NOTHROW
+{
+	return MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size);
+}
+
+static void* mem_leak_operator_new_array_debug (size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
+{
+	void* memory = MemoryLeakWarningPlugin::getGlobalDetector()->allocMemory(getCurrentNewArrayAllocator(), size, (char*) file, line);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void mem_leak_operator_delete (void* mem) UT_NOTHROW
+{
+	MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
+	MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewAllocator(), (char*) mem);
+}
+
+static void mem_leak_operator_delete_array (void* mem) UT_NOTHROW
+{
+	MemoryLeakWarningPlugin::getGlobalDetector()->invalidateMemory((char*) mem);
+	MemoryLeakWarningPlugin::getGlobalDetector()->deallocMemory(getCurrentNewArrayAllocator(), (char*) mem);
+}
+
+static void* normal_operator_new (size_t size) UT_THROW(std::bad_alloc)
+{
+	void* memory = PlatformSpecificMalloc(size);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void* normal_operator_new_nothrow (size_t size) UT_NOTHROW
+{
+	return PlatformSpecificMalloc(size);
+}
+
+static void* normal_operator_new_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc)
+{
+	void* memory = PlatformSpecificMalloc(size);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void* normal_operator_new_array (size_t size) UT_THROW(std::bad_alloc)
+{
+	void* memory = PlatformSpecificMalloc(size);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void* normal_operator_new_array_nothrow (size_t size) UT_NOTHROW
+{
+	return PlatformSpecificMalloc(size);
+}
+
+static void* normal_operator_new_array_debug (size_t size, const char* /*file*/, int /*line*/) UT_THROW(std::bad_alloc)
+{
+	void* memory = PlatformSpecificMalloc(size);
+	UT_THROW_BAD_ALLOC_WHEN_NULL(memory);
+	return memory;
+}
+
+static void normal_operator_delete (void* mem) UT_NOTHROW
+{
+	PlatformSpecificFree(mem);
+}
+
+static void normal_operator_delete_array (void* mem) UT_NOTHROW
+{
+	PlatformSpecificFree(mem);
+}
+
+static void *(*operator_new_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new;
+static void *(*operator_new_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_nothrow;
+static void *(*operator_new_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_debug;
+static void *(*operator_new_array_fptr)(size_t size) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array;
+static void *(*operator_new_array_nothrow_fptr)(size_t size) UT_NOTHROW = mem_leak_operator_new_array_nothrow;
+static void *(*operator_new_array_debug_fptr)(size_t size, const char* file, int line) UT_THROW(std::bad_alloc) = mem_leak_operator_new_array_debug;
+static void (*operator_delete_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete;
+static void (*operator_delete_array_fptr)(void* mem) UT_NOTHROW = mem_leak_operator_delete_array;
+
+void* operator new(size_t size) UT_THROW(std::bad_alloc)
+{
+	return operator_new_fptr(size);
+}
+
+void* operator new(size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
+{
+	return operator_new_debug_fptr(size, file, line);
+}
+
+void operator delete(void* mem) UT_NOTHROW
+{
+	operator_delete_fptr(mem);
+}
+
+void operator delete(void* mem, const char*, int) UT_NOTHROW
+{
+	operator_delete_fptr(mem);
+}
+
+void* operator new[](size_t size) UT_THROW(std::bad_alloc)
+{
+	return operator_new_array_fptr(size);
+}
+
+void* operator new [](size_t size, const char* file, int line) UT_THROW(std::bad_alloc)
+{
+	return operator_new_array_debug_fptr(size, file, line);
+}
+
+void operator delete[](void* mem) UT_NOTHROW
+{
+	 operator_delete_array_fptr(mem);
+}
+
+void operator delete[](void* mem, const char*, int) UT_NOTHROW
+{
+	 operator_delete_array_fptr(mem);
+}
+
+
+#if CPPUTEST_USE_STD_CPP_LIB
+
+void* operator new(size_t size, const std::nothrow_t&) UT_NOTHROW
+{
+	return operator_new_nothrow_fptr(size);
+}
+
+void* operator new[](size_t size, const std::nothrow_t&) UT_NOTHROW
+{
+	return operator_new_array_nothrow_fptr(size);
+}
+
+#else
+
+/* Have a similar method. This avoid unused operator_new_nothrow_fptr warning */
+
+extern void* operator_new_nothrow(size_t size) UT_NOTHROW;
+extern void* operator_new_array_nothrow(size_t size) UT_NOTHROW;
+
+void* operator_new_nothrow(size_t size) UT_NOTHROW
+{
+	return operator_new_nothrow_fptr(size);
+}
+
+void* operator_new_array_nothrow(size_t size) UT_NOTHROW
+{
+	return operator_new_array_nothrow_fptr(size);
+}
+
+#endif
+#endif
+
+void MemoryLeakWarningPlugin::turnOffNewDeleteOverloads()
+{
+#if CPPUTEST_USE_MEM_LEAK_DETECTION
+	operator_new_fptr = normal_operator_new;
+	operator_new_nothrow_fptr = normal_operator_new_nothrow;
+	operator_new_debug_fptr = normal_operator_new_debug;
+	operator_new_array_fptr = normal_operator_new_array;
+	operator_new_array_nothrow_fptr = normal_operator_new_array_nothrow;
+	operator_new_array_debug_fptr = normal_operator_new_array_debug;
+	operator_delete_fptr = normal_operator_delete;
+	operator_delete_array_fptr = normal_operator_delete_array;
+	malloc_fptr = normal_malloc;
+	realloc_fptr = normal_realloc;
+	free_fptr = normal_free;
+
+#endif
+}
+
+void MemoryLeakWarningPlugin::turnOnNewDeleteOverloads()
+{
+#if CPPUTEST_USE_MEM_LEAK_DETECTION
+	operator_new_fptr = mem_leak_operator_new;
+	operator_new_nothrow_fptr = mem_leak_operator_new_nothrow;
+	operator_new_debug_fptr = mem_leak_operator_new_debug;
+	operator_new_array_fptr = mem_leak_operator_new_array;
+	operator_new_array_nothrow_fptr = mem_leak_operator_new_array_nothrow;
+	operator_new_array_debug_fptr = mem_leak_operator_new_array_debug;
+	operator_delete_fptr = mem_leak_operator_delete;
+	operator_delete_array_fptr = mem_leak_operator_delete_array;
+	malloc_fptr = mem_leak_malloc;
+	realloc_fptr = mem_leak_realloc;
+	free_fptr = mem_leak_free;
+#endif
+}
+
+bool MemoryLeakWarningPlugin::areNewDeleteOverloaded()
+{
+#if CPPUTEST_USE_MEM_LEAK_DETECTION
+	return operator_new_fptr == mem_leak_operator_new;
+#else
+	return false;
+#endif
+}
+
+void crash_on_allocation_number(unsigned alloc_number)
+{
+	static CrashOnAllocationAllocator crashAllocator;
+	crashAllocator.setNumberToCrashOn(alloc_number);
+	setCurrentMallocAllocator(&crashAllocator);
+	setCurrentNewAllocator(&crashAllocator);
+	setCurrentNewArrayAllocator(&crashAllocator);
+}
+
+class MemoryLeakWarningReporter: public MemoryLeakFailure
+{
+public:
+	virtual ~MemoryLeakWarningReporter()
+	{
+	}
+
+	virtual void fail(char* fail_string)
+	{
+		UtestShell* currentTest = UtestShell::getCurrent();
+		currentTest->failWith(FailFailure(currentTest, currentTest->getName().asCharString(), currentTest->getLineNumber(), fail_string), TestTerminatorWithoutExceptions());
+	}
+};
+
+static MemoryLeakFailure* globalReporter = 0;
+static MemoryLeakDetector* globalDetector = 0;
+
+MemoryLeakDetector* MemoryLeakWarningPlugin::getGlobalDetector()
+{
+	if (globalDetector == 0) {
+		bool newDeleteOverloaded = areNewDeleteOverloaded();
+		turnOffNewDeleteOverloads();
+
+		globalReporter = new MemoryLeakWarningReporter;
+		globalDetector = new MemoryLeakDetector(globalReporter);
+
+		if (newDeleteOverloaded) turnOnNewDeleteOverloads();
+	}
+	return globalDetector;
+}
+
+MemoryLeakFailure* MemoryLeakWarningPlugin::getGlobalFailureReporter()
+{
+	return globalReporter;
+}
+
+void MemoryLeakWarningPlugin::destroyGlobalDetectorAndTurnOffMemoryLeakDetectionInDestructor(bool des)
+{
+	destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_ = des;
+}
+
+void MemoryLeakWarningPlugin::setGlobalDetector(MemoryLeakDetector* detector, MemoryLeakFailure* reporter)
+{
+	globalDetector = detector;
+	globalReporter = reporter;
+}
+
+void MemoryLeakWarningPlugin::destroyGlobalDetector()
+{
+	turnOffNewDeleteOverloads();
+	delete globalDetector;
+	delete globalReporter;
+	globalDetector = NULL;
+}
+
+
+MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::firstPlugin_ = 0;
+
+MemoryLeakWarningPlugin* MemoryLeakWarningPlugin::getFirstPlugin()
+{
+	return firstPlugin_;
+}
+
+MemoryLeakDetector* MemoryLeakWarningPlugin::getMemoryLeakDetector()
+{
+	return memLeakDetector_;
+}
+
+void MemoryLeakWarningPlugin::ignoreAllLeaksInTest()
+{
+	ignoreAllWarnings_ = true;
+}
+
+void MemoryLeakWarningPlugin::expectLeaksInTest(int n)
+{
+	expectedLeaks_ = n;
+}
+
+MemoryLeakWarningPlugin::MemoryLeakWarningPlugin(const SimpleString& name, MemoryLeakDetector* localDetector) :
+	TestPlugin(name), ignoreAllWarnings_(false), destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_(false), expectedLeaks_(0)
+{
+	if (firstPlugin_ == 0) firstPlugin_ = this;
+
+	if (localDetector) memLeakDetector_ = localDetector;
+	else memLeakDetector_ = getGlobalDetector();
+
+	memLeakDetector_->enable();
+}
+
+MemoryLeakWarningPlugin::~MemoryLeakWarningPlugin()
+{
+	if (destroyGlobalDetectorAndTurnOfMemoryLeakDetectionInDestructor_) {
+		MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
+		MemoryLeakWarningPlugin::destroyGlobalDetector();
+	}
+}
+
+void MemoryLeakWarningPlugin::preTestAction(UtestShell& /*test*/, TestResult& result)
+{
+	memLeakDetector_->startChecking();
+	failureCount_ = result.getFailureCount();
+}
+
+void MemoryLeakWarningPlugin::postTestAction(UtestShell& test, TestResult& result)
+{
+	memLeakDetector_->stopChecking();
+	int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_checking);
+
+	if (!ignoreAllWarnings_ && expectedLeaks_ != leaks && failureCount_ == result.getFailureCount()) {
+		TestFailure f(&test, memLeakDetector_->report(mem_leak_period_checking));
+		result.addFailure(f);
+	}
+	memLeakDetector_->markCheckingPeriodLeaksAsNonCheckingPeriod();
+	ignoreAllWarnings_ = false;
+	expectedLeaks_ = 0;
+}
+
+const char* MemoryLeakWarningPlugin::FinalReport(int toBeDeletedLeaks)
+{
+	int leaks = memLeakDetector_->totalMemoryLeaks(mem_leak_period_enabled);
+	if (leaks != toBeDeletedLeaks) return memLeakDetector_->report(mem_leak_period_enabled);
+	return "";
+}
+
+
--- a/src/CppUTest/SimpleString.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/SimpleString.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,515 +1,538 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/SimpleString.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-#include "CppUTest/TestMemoryAllocator.h"
-
-
-TestMemoryAllocator* SimpleString::stringAllocator_ = NULL;
-
-TestMemoryAllocator* SimpleString::getStringAllocator()
-{
-	if (stringAllocator_ == NULL)
-		return defaultNewArrayAllocator();
-	return stringAllocator_;
-}
-
-void SimpleString::setStringAllocator(TestMemoryAllocator* allocator)
-{
-	stringAllocator_ = allocator;
-}
-
-/* Avoid using the memory leak detector INSIDE SimpleString as its used inside the detector */
-char* SimpleString::allocStringBuffer(size_t _size)
-{
-	return getStringAllocator()->alloc_memory(_size, __FILE__, __LINE__);
-}
-
-void SimpleString::deallocStringBuffer(char* str)
-{
-	getStringAllocator()->free_memory(str, __FILE__, __LINE__);
-}
-
-char* SimpleString::getEmptyString() const
-{
-	char* empty = allocStringBuffer(1);
-	empty[0] = '\0';
-	return empty;
-}
-SimpleString::SimpleString(const char *otherBuffer)
-{
-	if (otherBuffer == 0) {
-		buffer_ = getEmptyString();
-	}
-	else {
-		size_t len = PlatformSpecificStrLen(otherBuffer) + 1;
-		buffer_ = allocStringBuffer(len);
-		PlatformSpecificStrCpy(buffer_, otherBuffer);
-	}
-}
-
-SimpleString::SimpleString(const char *other, size_t repeatCount)
-{
-	size_t len = PlatformSpecificStrLen(other) * repeatCount + 1;
-	buffer_ = allocStringBuffer(len);
-	char* next = buffer_;
-	for (size_t i = 0; i < repeatCount; i++) {
-		PlatformSpecificStrCpy(next, other);
-		next += PlatformSpecificStrLen(other);
-	}
-	*next = 0;
-
-}
-SimpleString::SimpleString(const SimpleString& other)
-{
-	size_t len = other.size() + 1;
-	buffer_ = allocStringBuffer(len);
-	PlatformSpecificStrCpy(buffer_, other.buffer_);
-}
-
-SimpleString& SimpleString::operator=(const SimpleString& other)
-{
-	if (this != &other) {
-		deallocStringBuffer(buffer_);
-		size_t len = other.size() + 1;
-		buffer_ = allocStringBuffer(len);
-		PlatformSpecificStrCpy(buffer_, other.buffer_);
-	}
-	return *this;
-}
-
-bool SimpleString::contains(const SimpleString& other) const
-{
-	//strstr on some machines does not handle ""
-	//the right way.  "" should be found in any string
-	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
-	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
-	else return PlatformSpecificStrStr(buffer_, other.buffer_) != 0;
-}
-
-bool SimpleString::containsNoCase(const SimpleString& other) const
-{
-	return toLower().contains(other.toLower());
-}
-
-
-bool SimpleString::startsWith(const SimpleString& other) const
-{
-	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
-	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
-	else return PlatformSpecificStrStr(buffer_, other.buffer_) == buffer_;
-}
-
-bool SimpleString::endsWith(const SimpleString& other) const
-{
-	size_t buffer_length = PlatformSpecificStrLen(buffer_);
-	size_t other_buffer_length = PlatformSpecificStrLen(other.buffer_);
-	if (other_buffer_length == 0) return true;
-	if (buffer_length == 0) return false;
-	if (buffer_length < other_buffer_length) return false;
-	return PlatformSpecificStrCmp(buffer_ + buffer_length - other_buffer_length, other.buffer_) == 0;
-}
-
-size_t SimpleString::count(const SimpleString& substr) const
-{
-	size_t num = 0;
-	char* str = buffer_;
-	while ((str = PlatformSpecificStrStr(str, substr.buffer_))) {
-		num++;
-		str++;
-	}
-	return num;
-}
-
-void SimpleString::split(const SimpleString& delimiter, SimpleStringCollection& col) const
-{
-	size_t num = count(delimiter);
-	size_t extraEndToken = (endsWith(delimiter)) ? 0 : 1U;
-	col.allocate(num + extraEndToken);
-
-	char* str = buffer_;
-	char* prev;
-	for (size_t i = 0; i < num; ++i) {
-		prev = str;
-		str = PlatformSpecificStrStr(str, delimiter.buffer_) + 1;
-		size_t len = (size_t) (str - prev);
-		char* sub = allocStringBuffer(len + 1);
-		PlatformSpecificStrNCpy(sub, prev, len);
-		sub[len] = '\0';
-		col[i] = sub;
-		deallocStringBuffer(sub);
-	}
-	if (extraEndToken) {
-		col[num] = str;
-	}
-}
-
-void SimpleString::replace(char to, char with)
-{
-	size_t s = size();
-	for (size_t i = 0; i < s; i++) {
-		if (buffer_[i] == to) buffer_[i] = with;
-	}
-}
-
-void SimpleString::replace(const char* to, const char* with)
-{
-	size_t c = count(to);
-	size_t len = size();
-	size_t tolen = PlatformSpecificStrLen(to);
-	size_t withlen = PlatformSpecificStrLen(with);
-
-	size_t newsize = len + (withlen * c) - (tolen * c) + 1;
-
-	if (newsize) {
-		char* newbuf = allocStringBuffer(newsize);
-		for (size_t i = 0, j = 0; i < len;) {
-			if (PlatformSpecificStrNCmp(&buffer_[i], to, tolen) == 0) {
-				PlatformSpecificStrNCpy(&newbuf[j], with, withlen);
-				j += withlen;
-				i += tolen;
-			}
-			else {
-				newbuf[j] = buffer_[i];
-				j++;
-				i++;
-			}
-		}
-		deallocStringBuffer(buffer_);
-		buffer_ = newbuf;
-		buffer_[newsize - 1] = '\0';
-	}
-	else {
-		buffer_ = getEmptyString();
-		buffer_[0] = '\0';
-	}
-}
-
-SimpleString SimpleString::toLower() const
-{
-	SimpleString str(*this);
-
-	size_t str_size = str.size();
-	for (size_t i = 0; i < str_size; i++)
-		str.buffer_[i] = PlatformSpecificToLower(str.buffer_[i]);
-
-	return str;
-}
-
-const char *SimpleString::asCharString() const
-{
-	return buffer_;
-}
-
-size_t SimpleString::size() const
-{
-	return PlatformSpecificStrLen(buffer_);
-}
-
-bool SimpleString::isEmpty() const
-{
-	return size() == 0;
-}
-
-
-
-SimpleString::~SimpleString()
-{
-	deallocStringBuffer(buffer_);
-}
-
-bool operator==(const SimpleString& left, const SimpleString& right)
-{
-	return 0 == PlatformSpecificStrCmp(left.asCharString(), right.asCharString());
-}
-
-bool SimpleString::equalsNoCase(const SimpleString& str) const
-{
-	return toLower() == str.toLower();
-}
-
-
-bool operator!=(const SimpleString& left, const SimpleString& right)
-{
-	return !(left == right);
-}
-
-SimpleString SimpleString::operator+(const SimpleString& rhs)
-{
-	SimpleString t(buffer_);
-	t += rhs.buffer_;
-	return t;
-}
-
-SimpleString& SimpleString::operator+=(const SimpleString& rhs)
-{
-	return operator+=(rhs.buffer_);
-}
-
-SimpleString& SimpleString::operator+=(const char* rhs)
-{
-	size_t len = this->size() + PlatformSpecificStrLen(rhs) + 1;
-	char* tbuffer = allocStringBuffer(len);
-	PlatformSpecificStrCpy(tbuffer, this->buffer_);
-	PlatformSpecificStrCat(tbuffer, rhs);
-	deallocStringBuffer(buffer_);
-	buffer_ = tbuffer;
-	return *this;
-}
-
-void SimpleString::padStringsToSameLength(SimpleString& str1, SimpleString& str2, char padCharacter)
-{
-	if (str1.size() > str2.size()) {
-		padStringsToSameLength(str2, str1, padCharacter);
-		return;
-	}
-
-	char pad[2];
-	pad[0] = padCharacter;
-	pad[1] = 0;
-	str1 = SimpleString(pad, str2.size() - str1.size()) + str1;
-}
-
-SimpleString SimpleString::subString(size_t beginPos, size_t amount) const
-{
-	if (beginPos > size()-1) return "";
-
-	SimpleString newString = buffer_ + beginPos;
-
-	if (newString.size() > amount)
-		newString.buffer_[amount] = '\0';
-
-	return newString;
-}
-
-char SimpleString::at(int pos) const
-{
-	return buffer_[pos];
-}
-
-int SimpleString::find(char ch) const
-{
-	return findFrom(0, ch);
-}
-
-int SimpleString::findFrom(size_t starting_position, char ch) const
-{
-	size_t length = size();
-	for (size_t i = starting_position; i < length; i++)
-		if (buffer_[i] == ch) return (int) i;
-	return -1;
-}
-
-SimpleString SimpleString::subStringFromTill(char startChar, char lastExcludedChar) const
-{
-	int beginPos = find(startChar);
-	if (beginPos < 0) return "";
-
-	int endPos = findFrom((size_t)beginPos, lastExcludedChar);
-	if (endPos == -1) return subString((size_t)beginPos, size());
-
-	return subString((size_t)beginPos, (size_t) (endPos - beginPos));
-}
-
-
-void SimpleString::copyToBuffer(char* bufferToCopy, size_t bufferSize) const
-{
-	if (bufferToCopy == NULL || bufferSize == 0) return;
-
-	size_t sizeToCopy = (bufferSize-1 < size()) ? bufferSize-1 : size();
-
-	PlatformSpecificStrNCpy(bufferToCopy, buffer_, sizeToCopy);
-	bufferToCopy[sizeToCopy] = '\0';
-
-}
-
-SimpleString StringFrom(bool value)
-{
-	return SimpleString(StringFromFormat("%s", value ? "true" : "false"));
-}
-
-SimpleString StringFrom(const char *value)
-{
-	return SimpleString(value);
-}
-
-SimpleString StringFromOrNull(const char * expected)
-{
-    return (expected) ? StringFrom(expected) : "(null)";
-}
-
-SimpleString StringFrom(int value)
-{
-	return StringFromFormat("%d", value);
-}
-
-SimpleString StringFrom(long value)
-{
-	return StringFromFormat("%ld", value);
-}
-
-SimpleString StringFrom(const void* value)
-{
-	return SimpleString("0x") + HexStringFrom(value);
-}
-
-SimpleString HexStringFrom(long value)
-{
-	return StringFromFormat("%lx", value);
-}
-
-static long convertPointerToLongValue(const void* value)
-{
-	/*
-	 * This way of converting also can convert a 64bit pointer in a 32bit integer by truncating.
-	 * This isn't the right way to convert pointers values and need to change by implementing a
-	 * proper portable way to convert pointers to strings.
-	 */
-	long* long_value = (long*) &value;
-	return *long_value;
-}
-
-SimpleString HexStringFrom(const void* value)
-{
-	return StringFromFormat("%lx", convertPointerToLongValue(value));
-}
-
-SimpleString StringFrom(double value, int precision)
-{
-	return StringFromFormat("%.*g", precision, value);
-}
-
-SimpleString StringFrom(char value)
-{
-	return StringFromFormat("%c", value);
-}
-
-SimpleString StringFrom(const SimpleString& value)
-{
-	return SimpleString(value);
-}
-
-SimpleString StringFromFormat(const char* format, ...)
-{
-	SimpleString resultString;
-	va_list arguments;
-	va_start(arguments, format);
-
-	resultString = VStringFromFormat(format, arguments);
-	va_end(arguments);
-	return resultString;
-}
-
-SimpleString StringFrom(unsigned int i)
-{
-	return StringFromFormat("%10u (0x%08x)", i, i);
-}
-
-#if CPPUTEST_USE_STD_CPP_LIB
-
-#include <string>
-
-SimpleString StringFrom(const std::string& value)
-{
-	return SimpleString(value.c_str());
-}
-
-SimpleString StringFrom(unsigned long i)
-{
-	return StringFromFormat("%lu (0x%lx)", i, i);
-}
-
-#endif
-
-//Kludge to get a va_copy in VC++ V6
-#ifndef va_copy
-#define va_copy(copy, original) copy = original;
-#endif
-
-SimpleString VStringFromFormat(const char* format, va_list args)
-{
-	va_list argsCopy;
-	va_copy(argsCopy, args);
-	enum
-	{
-		sizeOfdefaultBuffer = 100
-	};
-	char defaultBuffer[sizeOfdefaultBuffer];
-	SimpleString resultString;
-
-	size_t size = (size_t)PlatformSpecificVSNprintf(defaultBuffer, sizeOfdefaultBuffer, format, args);
-	if (size < sizeOfdefaultBuffer) {
-		resultString = SimpleString(defaultBuffer);
-	}
-	else {
-		size_t newBufferSize = size + 1;
-		char* newBuffer = SimpleString::allocStringBuffer(newBufferSize);
-		PlatformSpecificVSNprintf(newBuffer, newBufferSize, format, argsCopy);
-		resultString = SimpleString(newBuffer);
-
-		SimpleString::deallocStringBuffer(newBuffer);
-	}
-	va_end(argsCopy);
-	return resultString;
-}
-
-SimpleStringCollection::SimpleStringCollection()
-{
-	collection_ = 0;
-	size_ = 0;
-}
-
-void SimpleStringCollection::allocate(size_t _size)
-{
-	if (collection_) delete[] collection_;
-
-	size_ = _size;
-	collection_ = new SimpleString[size_];
-}
-
-SimpleStringCollection::~SimpleStringCollection()
-{
-	delete[] (collection_);
-}
-
-size_t SimpleStringCollection::size() const
-{
-	return size_;
-}
-
-SimpleString& SimpleStringCollection::operator[](size_t index)
-{
-	if (index >= size_) {
-		empty_ = "";
-		return empty_;
-	}
-
-	return collection_[index];
-}
-
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/SimpleString.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+#include "CppUTest/TestMemoryAllocator.h"
+
+
+TestMemoryAllocator* SimpleString::stringAllocator_ = NULL;
+
+TestMemoryAllocator* SimpleString::getStringAllocator()
+{
+	if (stringAllocator_ == NULL)
+		return defaultNewArrayAllocator();
+	return stringAllocator_;
+}
+
+void SimpleString::setStringAllocator(TestMemoryAllocator* allocator)
+{
+	stringAllocator_ = allocator;
+}
+
+/* Avoid using the memory leak detector INSIDE SimpleString as its used inside the detector */
+char* SimpleString::allocStringBuffer(size_t _size)
+{
+	return getStringAllocator()->alloc_memory(_size, __FILE__, __LINE__);
+}
+
+void SimpleString::deallocStringBuffer(char* str)
+{
+	getStringAllocator()->free_memory(str, __FILE__, __LINE__);
+}
+
+char* SimpleString::getEmptyString() const
+{
+	char* empty = allocStringBuffer(1);
+	empty[0] = '\0';
+	return empty;
+}
+
+char* SimpleString::StrNCpy(char* s1, const char* s2, size_t n)
+{
+	char* result = s1;
+
+	if((NULL == s1) || (0 == n)) return result;
+
+	while ((*s1++ = *s2++) && --n != 0)
+		;
+	return result;
+}
+
+SimpleString::SimpleString(const char *otherBuffer)
+{
+	if (otherBuffer == 0) {
+		buffer_ = getEmptyString();
+	}
+	else {
+		buffer_ = copyToNewBuffer(otherBuffer);
+	}
+}
+
+SimpleString::SimpleString(const char *other, size_t repeatCount)
+{
+	size_t otherStringLength = PlatformSpecificStrLen(other);
+	size_t len = otherStringLength * repeatCount + 1;
+	buffer_ = allocStringBuffer(len);
+	char* next = buffer_;
+	for (size_t i = 0; i < repeatCount; i++) {
+		StrNCpy(next, other, otherStringLength + 1);
+		next += otherStringLength;
+	}
+	*next = 0;
+}
+
+SimpleString::SimpleString(const SimpleString& other)
+{
+	buffer_ = copyToNewBuffer(other.buffer_);
+}
+
+SimpleString& SimpleString::operator=(const SimpleString& other)
+{
+	if (this != &other) {
+		deallocStringBuffer(buffer_);
+		buffer_ = copyToNewBuffer(other.buffer_);
+	}
+	return *this;
+}
+
+bool SimpleString::contains(const SimpleString& other) const
+{
+	//strstr on some machines does not handle ""
+	//the right way.  "" should be found in any string
+	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
+	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
+	else return PlatformSpecificStrStr(buffer_, other.buffer_) != 0;
+}
+
+bool SimpleString::containsNoCase(const SimpleString& other) const
+{
+	return toLower().contains(other.toLower());
+}
+
+
+bool SimpleString::startsWith(const SimpleString& other) const
+{
+	if (PlatformSpecificStrLen(other.buffer_) == 0) return true;
+	else if (PlatformSpecificStrLen(buffer_) == 0) return false;
+	else return PlatformSpecificStrStr(buffer_, other.buffer_) == buffer_;
+}
+
+bool SimpleString::endsWith(const SimpleString& other) const
+{
+	size_t buffer_length = PlatformSpecificStrLen(buffer_);
+	size_t other_buffer_length = PlatformSpecificStrLen(other.buffer_);
+	if (other_buffer_length == 0) return true;
+	if (buffer_length == 0) return false;
+	if (buffer_length < other_buffer_length) return false;
+	return PlatformSpecificStrCmp(buffer_ + buffer_length - other_buffer_length, other.buffer_) == 0;
+}
+
+size_t SimpleString::count(const SimpleString& substr) const
+{
+	size_t num = 0;
+	char* str = buffer_;
+	while ((str = PlatformSpecificStrStr(str, substr.buffer_))) {
+		num++;
+		str++;
+	}
+	return num;
+}
+
+void SimpleString::split(const SimpleString& delimiter, SimpleStringCollection& col) const
+{
+	size_t num = count(delimiter);
+	size_t extraEndToken = (endsWith(delimiter)) ? 0 : 1U;
+	col.allocate(num + extraEndToken);
+
+	char* str = buffer_;
+	char* prev;
+	for (size_t i = 0; i < num; ++i) {
+		prev = str;
+		str = PlatformSpecificStrStr(str, delimiter.buffer_) + 1;
+		size_t len = (size_t) (str - prev) + 1;
+		col[i].buffer_ = copyToNewBuffer(prev, len);
+	}
+	if (extraEndToken) {
+		col[num] = str;
+	}
+}
+
+void SimpleString::replace(char to, char with)
+{
+	size_t s = size();
+	for (size_t i = 0; i < s; i++) {
+		if (buffer_[i] == to) buffer_[i] = with;
+	}
+}
+
+void SimpleString::replace(const char* to, const char* with)
+{
+	size_t c = count(to);
+	size_t len = size();
+	size_t tolen = PlatformSpecificStrLen(to);
+	size_t withlen = PlatformSpecificStrLen(with);
+
+	size_t newsize = len + (withlen * c) - (tolen * c) + 1;
+
+	if (newsize) {
+		char* newbuf = allocStringBuffer(newsize);
+		for (size_t i = 0, j = 0; i < len;) {
+			if (PlatformSpecificStrNCmp(&buffer_[i], to, tolen) == 0) {
+				StrNCpy(&newbuf[j], with, withlen + 1);
+				j += withlen;
+				i += tolen;
+			}
+			else {
+				newbuf[j] = buffer_[i];
+				j++;
+				i++;
+			}
+		}
+		deallocStringBuffer(buffer_);
+		buffer_ = newbuf;
+		buffer_[newsize - 1] = '\0';
+	}
+	else {
+		buffer_ = getEmptyString();
+		buffer_[0] = '\0';
+	}
+}
+
+SimpleString SimpleString::toLower() const
+{
+	SimpleString str(*this);
+
+	size_t str_size = str.size();
+	for (size_t i = 0; i < str_size; i++)
+		str.buffer_[i] = PlatformSpecificToLower(str.buffer_[i]);
+
+	return str;
+}
+
+const char *SimpleString::asCharString() const
+{
+	return buffer_;
+}
+
+size_t SimpleString::size() const
+{
+	return PlatformSpecificStrLen(buffer_);
+}
+
+bool SimpleString::isEmpty() const
+{
+	return size() == 0;
+}
+
+
+
+SimpleString::~SimpleString()
+{
+	deallocStringBuffer(buffer_);
+}
+
+bool operator==(const SimpleString& left, const SimpleString& right)
+{
+	return 0 == PlatformSpecificStrCmp(left.asCharString(), right.asCharString());
+}
+
+bool SimpleString::equalsNoCase(const SimpleString& str) const
+{
+	return toLower() == str.toLower();
+}
+
+
+bool operator!=(const SimpleString& left, const SimpleString& right)
+{
+	return !(left == right);
+}
+
+SimpleString SimpleString::operator+(const SimpleString& rhs)
+{
+	SimpleString t(buffer_);
+	t += rhs.buffer_;
+	return t;
+}
+
+SimpleString& SimpleString::operator+=(const SimpleString& rhs)
+{
+	return operator+=(rhs.buffer_);
+}
+
+SimpleString& SimpleString::operator+=(const char* rhs)
+{
+	size_t originalSize = this->size();
+	size_t additionalStringSize = PlatformSpecificStrLen(rhs) + 1;
+	size_t sizeOfNewString = originalSize + additionalStringSize;
+	char* tbuffer = copyToNewBuffer(this->buffer_, sizeOfNewString);
+	StrNCpy(tbuffer + originalSize, rhs, additionalStringSize);
+	deallocStringBuffer(this->buffer_);
+	this->buffer_ = tbuffer;
+	return *this;
+}
+
+void SimpleString::padStringsToSameLength(SimpleString& str1, SimpleString& str2, char padCharacter)
+{
+	if (str1.size() > str2.size()) {
+		padStringsToSameLength(str2, str1, padCharacter);
+		return;
+	}
+
+	char pad[2];
+	pad[0] = padCharacter;
+	pad[1] = 0;
+	str1 = SimpleString(pad, str2.size() - str1.size()) + str1;
+}
+
+SimpleString SimpleString::subString(size_t beginPos, size_t amount) const
+{
+	if (beginPos > size()-1) return "";
+
+	SimpleString newString = buffer_ + beginPos;
+
+	if (newString.size() > amount)
+		newString.buffer_[amount] = '\0';
+
+	return newString;
+}
+
+char SimpleString::at(int pos) const
+{
+	return buffer_[pos];
+}
+
+int SimpleString::find(char ch) const
+{
+	return findFrom(0, ch);
+}
+
+int SimpleString::findFrom(size_t starting_position, char ch) const
+{
+	size_t length = size();
+	for (size_t i = starting_position; i < length; i++)
+		if (buffer_[i] == ch) return (int) i;
+	return -1;
+}
+
+SimpleString SimpleString::subStringFromTill(char startChar, char lastExcludedChar) const
+{
+	int beginPos = find(startChar);
+	if (beginPos < 0) return "";
+
+	int endPos = findFrom((size_t)beginPos, lastExcludedChar);
+	if (endPos == -1) return subString((size_t)beginPos, size());
+
+	return subString((size_t)beginPos, (size_t) (endPos - beginPos));
+}
+
+char* SimpleString::copyToNewBuffer(const char* bufferToCopy, size_t bufferSize)
+{
+	if(bufferSize == 0) bufferSize = PlatformSpecificStrLen(bufferToCopy) + 1;
+
+	char* newBuffer = allocStringBuffer(bufferSize);
+	StrNCpy(newBuffer, bufferToCopy, bufferSize);
+	newBuffer[bufferSize-1] = '\0';
+	return newBuffer;
+}
+
+void SimpleString::copyToBuffer(char* bufferToCopy, size_t bufferSize) const
+{
+	if (bufferToCopy == NULL || bufferSize == 0) return;
+
+	size_t sizeToCopy = (bufferSize-1 < size()) ? bufferSize : size();
+
+	StrNCpy(bufferToCopy, buffer_, sizeToCopy);
+	bufferToCopy[sizeToCopy] = '\0';
+}
+
+SimpleString StringFrom(bool value)
+{
+	return SimpleString(StringFromFormat("%s", value ? "true" : "false"));
+}
+
+SimpleString StringFrom(const char *value)
+{
+	return SimpleString(value);
+}
+
+SimpleString StringFromOrNull(const char * expected)
+{
+    return (expected) ? StringFrom(expected) : "(null)";
+}
+
+SimpleString StringFrom(int value)
+{
+	return StringFromFormat("%d", value);
+}
+
+SimpleString StringFrom(long value)
+{
+	return StringFromFormat("%ld", value);
+}
+
+SimpleString StringFrom(const void* value)
+{
+	return SimpleString("0x") + HexStringFrom(value);
+}
+
+SimpleString HexStringFrom(long value)
+{
+	return StringFromFormat("%lx", value);
+}
+
+SimpleString HexStringFrom(unsigned long value)
+{
+	return StringFromFormat("%lx", value);
+}
+
+static long convertPointerToLongValue(const void* value)
+{
+	/*
+	 * This way of converting also can convert a 64bit pointer in a 32bit integer by truncating.
+	 * This isn't the right way to convert pointers values and need to change by implementing a
+	 * proper portable way to convert pointers to strings.
+	 */
+	long* long_value = (long*) &value;
+	return *long_value;
+}
+
+SimpleString HexStringFrom(const void* value)
+{
+	return StringFromFormat("%lx", convertPointerToLongValue(value));
+}
+
+SimpleString StringFrom(double value, int precision)
+{
+	return StringFromFormat("%.*g", precision, value);
+}
+
+SimpleString StringFrom(char value)
+{
+	return StringFromFormat("%c", value);
+}
+
+SimpleString StringFrom(const SimpleString& value)
+{
+	return SimpleString(value);
+}
+
+SimpleString StringFromFormat(const char* format, ...)
+{
+	SimpleString resultString;
+	va_list arguments;
+	va_start(arguments, format);
+
+	resultString = VStringFromFormat(format, arguments);
+	va_end(arguments);
+	return resultString;
+}
+
+SimpleString StringFrom(unsigned int i)
+{
+	return StringFromFormat("%10u (0x%08x)", i, i);
+}
+
+#if CPPUTEST_USE_STD_CPP_LIB
+
+#include <string>
+
+SimpleString StringFrom(const std::string& value)
+{
+	return SimpleString(value.c_str());
+}
+
+SimpleString StringFrom(unsigned long i)
+{
+	return StringFromFormat("%lu (0x%lx)", i, i);
+}
+
+#else
+
+SimpleString StringFrom(unsigned long value)
+{
+	return StringFromFormat("%lu", value);
+}
+
+#endif
+
+//Kludge to get a va_copy in VC++ V6
+#ifndef va_copy
+#define va_copy(copy, original) copy = original;
+#endif
+
+SimpleString VStringFromFormat(const char* format, va_list args)
+{
+	va_list argsCopy;
+	va_copy(argsCopy, args);
+	enum
+	{
+		sizeOfdefaultBuffer = 100
+	};
+	char defaultBuffer[sizeOfdefaultBuffer];
+	SimpleString resultString;
+
+	size_t size = (size_t)PlatformSpecificVSNprintf(defaultBuffer, sizeOfdefaultBuffer, format, args);
+	if (size < sizeOfdefaultBuffer) {
+		resultString = SimpleString(defaultBuffer);
+	}
+	else {
+		size_t newBufferSize = size + 1;
+		char* newBuffer = SimpleString::allocStringBuffer(newBufferSize);
+		PlatformSpecificVSNprintf(newBuffer, newBufferSize, format, argsCopy);
+		resultString = SimpleString(newBuffer);
+
+		SimpleString::deallocStringBuffer(newBuffer);
+	}
+	va_end(argsCopy);
+	return resultString;
+}
+
+SimpleStringCollection::SimpleStringCollection()
+{
+	collection_ = 0;
+	size_ = 0;
+}
+
+void SimpleStringCollection::allocate(size_t _size)
+{
+	delete[] collection_;
+
+	size_ = _size;
+	collection_ = new SimpleString[size_];
+}
+
+SimpleStringCollection::~SimpleStringCollection()
+{
+	delete[] (collection_);
+}
+
+size_t SimpleStringCollection::size() const
+{
+	return size_;
+}
+
+SimpleString& SimpleStringCollection::operator[](size_t index)
+{
+	if (index >= size_) {
+		empty_ = "";
+		return empty_;
+	}
+
+	return collection_[index];
+}
--- a/src/CppUTest/TestFailure.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestFailure.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,252 +1,267 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestFailure.h"
-#include "CppUTest/TestOutput.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-static SimpleString removeAllPrintableCharactersFrom(const SimpleString& str)
-{
-	size_t bufferSize = str.size()+1;
-	char* buffer = (char*) PlatformSpecificMalloc(bufferSize);
-	str.copyToBuffer(buffer, bufferSize);
-
-	for (size_t i = 0; i < bufferSize-1; i++)
-		if (buffer[i] != '\t' && buffer[i] != '\n')
-			buffer[i] = ' ';
-
-	SimpleString result(buffer);
-	PlatformSpecificFree(buffer);
-	return result;
-}
-
-static SimpleString addMarkerToString(const SimpleString& str, int markerPos)
-{
-	size_t bufferSize = str.size()+1;
-	char* buffer = (char*) PlatformSpecificMalloc(bufferSize);
-	str.copyToBuffer(buffer, bufferSize);
-
-	buffer[markerPos] = '^';
-
-	SimpleString result(buffer);
-	PlatformSpecificFree(buffer);
-	return result;
-
-}
-
-TestFailure::TestFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& theMessage) :
-	testName_(test->getFormattedName()), fileName_(fileName), lineNumber_(lineNumber), testFileName_(test->getFile()), testLineNumber_(test->getLineNumber()), message_(theMessage)
-{
-}
-
-TestFailure::TestFailure(UtestShell* test, const SimpleString& theMessage) :
-    testName_(test->getFormattedName()), fileName_(test->getFile()), lineNumber_(test->getLineNumber()), testFileName_(test->getFile()), testLineNumber_(test->getLineNumber()), message_(theMessage)
-{
-}
-
-TestFailure::TestFailure(UtestShell* test, const char* fileName, int lineNum) :
-	testName_(test->getFormattedName()), fileName_(fileName), lineNumber_(lineNum), testFileName_(test->getFile()), testLineNumber_(test->getLineNumber()), message_("no message")
-{
-}
-
-TestFailure::TestFailure(const TestFailure& f) :
-	testName_(f.testName_), fileName_(f.fileName_), lineNumber_(f.lineNumber_), testFileName_(f.testFileName_), testLineNumber_(f.testLineNumber_), message_(f.message_)
-{
-}
-
-
-TestFailure::~TestFailure()
-{
-}
-
-SimpleString TestFailure::getFileName() const
-{
-	return fileName_;
-}
-
-SimpleString TestFailure::getTestFileName() const
-{
-	return testFileName_;
-}
-
-SimpleString TestFailure::getTestName() const
-{
-	return testName_;
-}
-
-int TestFailure::getFailureLineNumber() const
-{
-	return lineNumber_;
-}
-
-int TestFailure::getTestLineNumber() const
-{
-	return testLineNumber_;
-}
-
-SimpleString TestFailure::getMessage() const
-{
-	return message_;
-}
-
-bool TestFailure::isOutsideTestFile() const
-{
-	return testFileName_ != fileName_;
-}
-
-bool TestFailure::isInHelperFunction() const
-{
-	return lineNumber_ < testLineNumber_;
-}
-
-SimpleString TestFailure::createButWasString(const SimpleString& expected, const SimpleString& actual)
-{
-	return StringFromFormat("expected <%s>\n\tbut was  <%s>", expected.asCharString(), actual.asCharString());
-}
-
-SimpleString TestFailure::createDifferenceAtPosString(const SimpleString& actual, size_t position)
-{
-	SimpleString result;
-	const size_t extraCharactersWindow = 20;
-	const size_t halfOfExtraCharactersWindow = extraCharactersWindow / 2;
-
-	SimpleString paddingForPreventingOutOfBounds (" ", halfOfExtraCharactersWindow);
-	SimpleString actualString = paddingForPreventingOutOfBounds + actual + paddingForPreventingOutOfBounds;
-	SimpleString differentString = StringFromFormat("difference starts at position %lu at: <", (unsigned long) position);
-
-	result += "\n";
-	result += StringFromFormat("\t%s%s>\n", differentString.asCharString(), actualString.subString(position, extraCharactersWindow).asCharString());
-
-	SimpleString markString = actualString.subString(position, halfOfExtraCharactersWindow+1);
-	markString = removeAllPrintableCharactersFrom(markString);
-	markString = addMarkerToString(markString, halfOfExtraCharactersWindow);
-
-	result += StringFromFormat("\t%s%s", SimpleString(" ", differentString.size()).asCharString(), markString.asCharString());
-	return result;
-}
-
-EqualsFailure::EqualsFailure(UtestShell* test, const char* fileName, int lineNumber, const char* expected, const char* actual) :
-	TestFailure(test, fileName, lineNumber)
-{
-	message_ = createButWasString(StringFromOrNull(expected), StringFromOrNull(actual));
-}
-
-EqualsFailure::EqualsFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& expected, const SimpleString& actual)
-	: TestFailure(test, fileName, lineNumber)
-{
-	message_ = createButWasString(expected, actual);
-}
-
-static SimpleString StringFromOrNan(double d)
-{
-	if (PlatformSpecificIsNan(d))
-		return "Nan - Not a number";
-	return StringFrom(d);
-}
-
-DoublesEqualFailure::DoublesEqualFailure(UtestShell* test, const char* fileName, int lineNumber, double expected, double actual, double threshold)  : TestFailure(test, fileName, lineNumber)
-{
-	message_ = createButWasString(StringFromOrNan(expected), StringFromOrNan(actual));
-	message_ += " threshold used was <";
-	message_ += StringFromOrNan(threshold);
-	message_ += ">";
-
-	if (PlatformSpecificIsNan(expected) || PlatformSpecificIsNan(actual) || PlatformSpecificIsNan(threshold))
-		message_ += "\n\tCannot make comparisons with Nan";
-}
-
-CheckEqualFailure::CheckEqualFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& expected, const SimpleString& actual) : TestFailure(test, fileName, lineNumber)
-{
-	size_t failStart;
-	for (failStart = 0; actual.asCharString()[failStart] == expected.asCharString()[failStart]; failStart++)
-		;
-	message_ = createButWasString(expected, actual);
-	message_ += createDifferenceAtPosString(actual, failStart);
-
-}
-
-ContainsFailure::ContainsFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& expected, const SimpleString& actual) :
-	TestFailure(test, fileName, lineNumber)
-{
-	message_ = StringFromFormat("actual <%s>\n\tdid not contain  <%s>", actual.asCharString(), expected.asCharString());
-}
-
-CheckFailure::CheckFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& checkString, const SimpleString& conditionString, const SimpleString& text) : TestFailure(test, fileName, lineNumber)
-{
-	message_ = "";
-	if (!text.isEmpty()) {
-		message_ += "Message: ";
-		message_ += text;
-		message_ += "\n\t";
-	}
-	message_ += checkString;
-	message_ += "(";
-	message_ += conditionString;
-	message_ += ") failed";
-}
-
-FailFailure::FailFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& message) : TestFailure(test, fileName, lineNumber)
-{
-	message_ = message;
-}
-
-LongsEqualFailure::LongsEqualFailure(UtestShell* test, const char* fileName, int lineNumber, long expected, long actual) : TestFailure(test, fileName, lineNumber)
-{
-	SimpleString aDecimal = StringFrom(actual);
-	SimpleString aHex = HexStringFrom(actual);
-	SimpleString eDecimal = StringFrom(expected);
-	SimpleString eHex = HexStringFrom(expected);
-
-	SimpleString::padStringsToSameLength(aDecimal, eDecimal, ' ');
-	SimpleString::padStringsToSameLength(aHex, eHex, '0');
-
-	SimpleString actualReported = aDecimal + " 0x" + aHex;
-	SimpleString expectedReported = eDecimal + " 0x" + eHex;
-	message_ = createButWasString(expectedReported, actualReported);
-}
-
-
-StringEqualFailure::StringEqualFailure(UtestShell* test, const char* fileName, int lineNumber, const char* expected, const char* actual) : TestFailure(test, fileName, lineNumber)
-{
-	size_t failStart;
-	for (failStart = 0; actual[failStart] == expected[failStart]; failStart++)
-		;
-	message_ = createButWasString(expected, actual);
-	message_ += createDifferenceAtPosString(actual, failStart);
-}
-
-StringEqualNoCaseFailure::StringEqualNoCaseFailure(UtestShell* test, const char* fileName, int lineNumber, const char* expected, const char* actual) : TestFailure(test, fileName, lineNumber)
-{
-	size_t failStart;
-    for (failStart = 0; PlatformSpecificToLower(actual[failStart]) == PlatformSpecificToLower(expected[failStart]); failStart++)
-    	;
-	message_ = createButWasString(expected, actual);
-	message_ += createDifferenceAtPosString(actual, failStart);
-}
-
-
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/TestFailure.h"
+#include "CppUTest/TestOutput.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+static SimpleString removeAllPrintableCharactersFrom(const SimpleString& str)
+{
+	size_t bufferSize = str.size()+1;
+	char* buffer = (char*) PlatformSpecificMalloc(bufferSize);
+	str.copyToBuffer(buffer, bufferSize);
+
+	for (size_t i = 0; i < bufferSize-1; i++)
+		if (buffer[i] != '\t' && buffer[i] != '\n')
+			buffer[i] = ' ';
+
+	SimpleString result(buffer);
+	PlatformSpecificFree(buffer);
+	return result;
+}
+
+static SimpleString addMarkerToString(const SimpleString& str, int markerPos)
+{
+	size_t bufferSize = str.size()+1;
+	char* buffer = (char*) PlatformSpecificMalloc(bufferSize);
+	str.copyToBuffer(buffer, bufferSize);
+
+	buffer[markerPos] = '^';
+
+	SimpleString result(buffer);
+	PlatformSpecificFree(buffer);
+	return result;
+
+}
+
+TestFailure::TestFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& theMessage) :
+	testName_(test->getFormattedName()), fileName_(fileName), lineNumber_(lineNumber), testFileName_(test->getFile()), testLineNumber_(test->getLineNumber()), message_(theMessage)
+{
+}
+
+TestFailure::TestFailure(UtestShell* test, const SimpleString& theMessage) :
+    testName_(test->getFormattedName()), fileName_(test->getFile()), lineNumber_(test->getLineNumber()), testFileName_(test->getFile()), testLineNumber_(test->getLineNumber()), message_(theMessage)
+{
+}
+
+TestFailure::TestFailure(UtestShell* test, const char* fileName, int lineNum) :
+	testName_(test->getFormattedName()), fileName_(fileName), lineNumber_(lineNum), testFileName_(test->getFile()), testLineNumber_(test->getLineNumber()), message_("no message")
+{
+}
+
+TestFailure::TestFailure(const TestFailure& f) :
+	testName_(f.testName_), fileName_(f.fileName_), lineNumber_(f.lineNumber_), testFileName_(f.testFileName_), testLineNumber_(f.testLineNumber_), message_(f.message_)
+{
+}
+
+
+TestFailure::~TestFailure()
+{
+}
+
+SimpleString TestFailure::getFileName() const
+{
+	return fileName_;
+}
+
+SimpleString TestFailure::getTestFileName() const
+{
+	return testFileName_;
+}
+
+SimpleString TestFailure::getTestName() const
+{
+	return testName_;
+}
+
+int TestFailure::getFailureLineNumber() const
+{
+	return lineNumber_;
+}
+
+int TestFailure::getTestLineNumber() const
+{
+	return testLineNumber_;
+}
+
+SimpleString TestFailure::getMessage() const
+{
+	return message_;
+}
+
+bool TestFailure::isOutsideTestFile() const
+{
+	return testFileName_ != fileName_;
+}
+
+bool TestFailure::isInHelperFunction() const
+{
+	return lineNumber_ < testLineNumber_;
+}
+
+SimpleString TestFailure::createButWasString(const SimpleString& expected, const SimpleString& actual)
+{
+	return StringFromFormat("expected <%s>\n\tbut was  <%s>", expected.asCharString(), actual.asCharString());
+}
+
+SimpleString TestFailure::createDifferenceAtPosString(const SimpleString& actual, size_t position)
+{
+	SimpleString result;
+	const size_t extraCharactersWindow = 20;
+	const size_t halfOfExtraCharactersWindow = extraCharactersWindow / 2;
+
+	SimpleString paddingForPreventingOutOfBounds (" ", halfOfExtraCharactersWindow);
+	SimpleString actualString = paddingForPreventingOutOfBounds + actual + paddingForPreventingOutOfBounds;
+	SimpleString differentString = StringFromFormat("difference starts at position %lu at: <", (unsigned long) position);
+
+	result += "\n";
+	result += StringFromFormat("\t%s%s>\n", differentString.asCharString(), actualString.subString(position, extraCharactersWindow).asCharString());
+
+	SimpleString markString = actualString.subString(position, halfOfExtraCharactersWindow+1);
+	markString = removeAllPrintableCharactersFrom(markString);
+	markString = addMarkerToString(markString, halfOfExtraCharactersWindow);
+
+	result += StringFromFormat("\t%s%s", SimpleString(" ", differentString.size()).asCharString(), markString.asCharString());
+	return result;
+}
+
+EqualsFailure::EqualsFailure(UtestShell* test, const char* fileName, int lineNumber, const char* expected, const char* actual) :
+	TestFailure(test, fileName, lineNumber)
+{
+	message_ = createButWasString(StringFromOrNull(expected), StringFromOrNull(actual));
+}
+
+EqualsFailure::EqualsFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& expected, const SimpleString& actual)
+	: TestFailure(test, fileName, lineNumber)
+{
+	message_ = createButWasString(expected, actual);
+}
+
+static SimpleString StringFromOrNan(double d)
+{
+	if (PlatformSpecificIsNan(d))
+		return "Nan - Not a number";
+	return StringFrom(d);
+}
+
+DoublesEqualFailure::DoublesEqualFailure(UtestShell* test, const char* fileName, int lineNumber, double expected, double actual, double threshold)  : TestFailure(test, fileName, lineNumber)
+{
+	message_ = createButWasString(StringFromOrNan(expected), StringFromOrNan(actual));
+	message_ += " threshold used was <";
+	message_ += StringFromOrNan(threshold);
+	message_ += ">";
+
+	if (PlatformSpecificIsNan(expected) || PlatformSpecificIsNan(actual) || PlatformSpecificIsNan(threshold))
+		message_ += "\n\tCannot make comparisons with Nan";
+}
+
+CheckEqualFailure::CheckEqualFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& expected, const SimpleString& actual) : TestFailure(test, fileName, lineNumber)
+{
+	size_t failStart;
+	for (failStart = 0; actual.asCharString()[failStart] == expected.asCharString()[failStart]; failStart++)
+		;
+	message_ = createButWasString(expected, actual);
+	message_ += createDifferenceAtPosString(actual, failStart);
+
+}
+
+ContainsFailure::ContainsFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& expected, const SimpleString& actual) :
+	TestFailure(test, fileName, lineNumber)
+{
+	message_ = StringFromFormat("actual <%s>\n\tdid not contain  <%s>", actual.asCharString(), expected.asCharString());
+}
+
+CheckFailure::CheckFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& checkString, const SimpleString& conditionString, const SimpleString& text) : TestFailure(test, fileName, lineNumber)
+{
+	message_ = "";
+	if (!text.isEmpty()) {
+		message_ += "Message: ";
+		message_ += text;
+		message_ += "\n\t";
+	}
+	message_ += checkString;
+	message_ += "(";
+	message_ += conditionString;
+	message_ += ") failed";
+}
+
+FailFailure::FailFailure(UtestShell* test, const char* fileName, int lineNumber, const SimpleString& message) : TestFailure(test, fileName, lineNumber)
+{
+	message_ = message;
+}
+
+LongsEqualFailure::LongsEqualFailure(UtestShell* test, const char* fileName, int lineNumber, long expected, long actual) : TestFailure(test, fileName, lineNumber)
+{
+	SimpleString aDecimal = StringFrom(actual);
+	SimpleString aHex = HexStringFrom(actual);
+	SimpleString eDecimal = StringFrom(expected);
+	SimpleString eHex = HexStringFrom(expected);
+
+	SimpleString::padStringsToSameLength(aDecimal, eDecimal, ' ');
+	SimpleString::padStringsToSameLength(aHex, eHex, '0');
+
+	SimpleString actualReported = aDecimal + " 0x" + aHex;
+	SimpleString expectedReported = eDecimal + " 0x" + eHex;
+	message_ = createButWasString(expectedReported, actualReported);
+}
+
+UnsignedLongsEqualFailure::UnsignedLongsEqualFailure(UtestShell* test, const char* fileName, int lineNumber, unsigned long expected, unsigned long actual) : TestFailure(test, fileName, lineNumber)
+{
+	SimpleString aDecimal = StringFrom(actual);
+	SimpleString aHex = HexStringFrom(actual);
+	SimpleString eDecimal = StringFrom(expected);
+	SimpleString eHex = HexStringFrom(expected);
+
+	SimpleString::padStringsToSameLength(aDecimal, eDecimal, ' ');
+	SimpleString::padStringsToSameLength(aHex, eHex, '0');
+
+	SimpleString actualReported = aDecimal + " 0x" + aHex;
+	SimpleString expectedReported = eDecimal + " 0x" + eHex;
+	message_ = createButWasString(expectedReported, actualReported);
+}
+
+
+StringEqualFailure::StringEqualFailure(UtestShell* test, const char* fileName, int lineNumber, const char* expected, const char* actual) : TestFailure(test, fileName, lineNumber)
+{
+	size_t failStart;
+	for (failStart = 0; actual[failStart] == expected[failStart]; failStart++)
+		;
+	message_ = createButWasString(expected, actual);
+	message_ += createDifferenceAtPosString(actual, failStart);
+}
+
+StringEqualNoCaseFailure::StringEqualNoCaseFailure(UtestShell* test, const char* fileName, int lineNumber, const char* expected, const char* actual) : TestFailure(test, fileName, lineNumber)
+{
+	size_t failStart;
+    for (failStart = 0; PlatformSpecificToLower(actual[failStart]) == PlatformSpecificToLower(expected[failStart]); failStart++)
+    	;
+	message_ = createButWasString(expected, actual);
+	message_ += createDifferenceAtPosString(actual, failStart);
+}
+
+
--- a/src/CppUTest/TestHarness_c.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestHarness_c.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,164 +1,164 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/MemoryLeakDetector.h"
-#include "CppUTest/TestMemoryAllocator.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-#include "CppUTest/TestHarness_c.h"
-
-extern "C"
-{
-
-
-void CHECK_EQUAL_C_INT_LOCATION(int expected, int actual, const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->assertLongsEqual((long)expected, (long)actual,  fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-void CHECK_EQUAL_C_REAL_LOCATION(double expected, double actual, double threshold, const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->assertDoublesEqual(expected, actual, threshold,  fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-void CHECK_EQUAL_C_CHAR_LOCATION(char expected, char actual, const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->assertEquals(((expected) != (actual)), StringFrom(expected).asCharString(), StringFrom(actual).asCharString(), fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-void CHECK_EQUAL_C_STRING_LOCATION(const char* expected, const char* actual, const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->assertCstrEqual(expected, actual, fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-void FAIL_TEXT_C_LOCATION(const char* text, const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->fail(text,  fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-void FAIL_C_LOCATION(const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->fail("",  fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-void CHECK_C_LOCATION(int condition, const char* conditionString, const char* fileName, int lineNumber)
-{
-	UtestShell::getCurrent()->assertTrue(condition != 0, "CHECK_C", conditionString, fileName, lineNumber, TestTerminatorWithoutExceptions());
-}
-
-enum { NO_COUNTDOWN = -1, OUT_OF_MEMORRY = 0 };
-static int malloc_out_of_memory_counter = NO_COUNTDOWN;
-static int malloc_count = 0;
-
-void cpputest_malloc_count_reset(void)
-{
-	malloc_count = 0;
-}
-
-int cpputest_malloc_get_count()
-{
-	return malloc_count;
-}
-
-void cpputest_malloc_set_out_of_memory()
-{
-	setCurrentMallocAllocator(NullUnknownAllocator::defaultAllocator());
-}
-
-void cpputest_malloc_set_not_out_of_memory()
-{
-	malloc_out_of_memory_counter = NO_COUNTDOWN;
-	setCurrentMallocAllocatorToDefault();
-}
-
-void cpputest_malloc_set_out_of_memory_countdown(int count)
-{
-	malloc_out_of_memory_counter = count;
-	if (malloc_out_of_memory_counter == OUT_OF_MEMORRY)
-		cpputest_malloc_set_out_of_memory();
-}
-
-void* cpputest_malloc(size_t size)
-{
-	return cpputest_malloc_location(size, "<unknown>", 0);
-}
-
-void* cpputest_calloc(size_t num, size_t size)
-{
-	return cpputest_calloc_location(num, size, "<unknown>", 0);
-}
-
-void* cpputest_realloc(void* ptr, size_t size)
-{
-	return cpputest_realloc_location(ptr, size, "<unknown>", 0);
-}
-
-void cpputest_free(void* buffer)
-{
-	cpputest_free_location(buffer, "<unknown>", 0);
-}
-
-static void countdown()
-{
-	if (malloc_out_of_memory_counter <= NO_COUNTDOWN)
-		return;
-
-	if (malloc_out_of_memory_counter == OUT_OF_MEMORRY)
-		return;
-
-	malloc_out_of_memory_counter--;
-
-	if (malloc_out_of_memory_counter == OUT_OF_MEMORRY)
-		cpputest_malloc_set_out_of_memory();
-}
-
-void* cpputest_malloc_location(size_t size, const char* file, int line)
-{
-	countdown();
-	malloc_count++;
-	return cpputest_malloc_location_with_leak_detection(size, file, line);
-}
-
-void* cpputest_calloc_location(size_t num, size_t size, const char* file, int line)
-{
-	void* mem = cpputest_malloc_location(num * size, file, line);
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/MemoryLeakDetector.h"
+#include "CppUTest/TestMemoryAllocator.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+#include "CppUTest/TestHarness_c.h"
+
+extern "C"
+{
+
+
+void CHECK_EQUAL_C_INT_LOCATION(int expected, int actual, const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->assertLongsEqual((long)expected, (long)actual,  fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+void CHECK_EQUAL_C_REAL_LOCATION(double expected, double actual, double threshold, const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->assertDoublesEqual(expected, actual, threshold,  fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+void CHECK_EQUAL_C_CHAR_LOCATION(char expected, char actual, const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->assertEquals(((expected) != (actual)), StringFrom(expected).asCharString(), StringFrom(actual).asCharString(), fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+void CHECK_EQUAL_C_STRING_LOCATION(const char* expected, const char* actual, const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->assertCstrEqual(expected, actual, fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+void FAIL_TEXT_C_LOCATION(const char* text, const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->fail(text,  fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+void FAIL_C_LOCATION(const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->fail("",  fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+void CHECK_C_LOCATION(int condition, const char* conditionString, const char* fileName, int lineNumber)
+{
+	UtestShell::getCurrent()->assertTrue(condition != 0, "CHECK_C", conditionString, fileName, lineNumber, TestTerminatorWithoutExceptions());
+}
+
+enum { NO_COUNTDOWN = -1, OUT_OF_MEMORRY = 0 };
+static int malloc_out_of_memory_counter = NO_COUNTDOWN;
+static int malloc_count = 0;
+
+void cpputest_malloc_count_reset(void)
+{
+	malloc_count = 0;
+}
+
+int cpputest_malloc_get_count()
+{
+	return malloc_count;
+}
+
+void cpputest_malloc_set_out_of_memory()
+{
+	setCurrentMallocAllocator(NullUnknownAllocator::defaultAllocator());
+}
+
+void cpputest_malloc_set_not_out_of_memory()
+{
+	malloc_out_of_memory_counter = NO_COUNTDOWN;
+	setCurrentMallocAllocatorToDefault();
+}
+
+void cpputest_malloc_set_out_of_memory_countdown(int count)
+{
+	malloc_out_of_memory_counter = count;
+	if (malloc_out_of_memory_counter == OUT_OF_MEMORRY)
+		cpputest_malloc_set_out_of_memory();
+}
+
+void* cpputest_malloc(size_t size)
+{
+	return cpputest_malloc_location(size, "<unknown>", 0);
+}
+
+void* cpputest_calloc(size_t num, size_t size)
+{
+	return cpputest_calloc_location(num, size, "<unknown>", 0);
+}
+
+void* cpputest_realloc(void* ptr, size_t size)
+{
+	return cpputest_realloc_location(ptr, size, "<unknown>", 0);
+}
+
+void cpputest_free(void* buffer)
+{
+	cpputest_free_location(buffer, "<unknown>", 0);
+}
+
+static void countdown()
+{
+	if (malloc_out_of_memory_counter <= NO_COUNTDOWN)
+		return;
+
+	if (malloc_out_of_memory_counter == OUT_OF_MEMORRY)
+		return;
+
+	malloc_out_of_memory_counter--;
+
+	if (malloc_out_of_memory_counter == OUT_OF_MEMORRY)
+		cpputest_malloc_set_out_of_memory();
+}
+
+void* cpputest_malloc_location(size_t size, const char* file, int line)
+{
+	countdown();
+	malloc_count++;
+	return cpputest_malloc_location_with_leak_detection(size, file, line);
+}
+
+void* cpputest_calloc_location(size_t num, size_t size, const char* file, int line)
+{
+	void* mem = cpputest_malloc_location(num * size, file, line);
 	if (mem)    
-	    PlatformSpecificMemset(mem, 0, num*size);
-	return mem;
-}
-
-void* cpputest_realloc_location(void* memory, size_t size, const char* file, int line)
-{
-	return cpputest_realloc_location_with_leak_detection(memory, size, file, line);
-}
-
-void cpputest_free_location(void* buffer, const char* file, int line)
-{
-	cpputest_free_location_with_leak_detection(buffer, file, line);
-}
-
-}
+	    PlatformSpecificMemset(mem, 0, num*size);
+	return mem;
+}
+
+void* cpputest_realloc_location(void* memory, size_t size, const char* file, int line)
+{
+	return cpputest_realloc_location_with_leak_detection(memory, size, file, line);
+}
+
+void cpputest_free_location(void* buffer, const char* file, int line)
+{
+	cpputest_free_location_with_leak_detection(buffer, file, line);
+}
+
+}
--- a/src/CppUTest/TestMemoryAllocator.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestMemoryAllocator.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,204 +1,204 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestMemoryAllocator.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-#include "CppUTest/MemoryLeakDetector.h"
-
-static char* checkedMalloc(size_t size)
-{
-	char* mem = (char*) PlatformSpecificMalloc(size);
-	if (mem == 0)
-	FAIL("malloc returned null pointer");
-	return mem;
-}
-
-static TestMemoryAllocator* currentNewAllocator = 0;
-static TestMemoryAllocator* currentNewArrayAllocator = 0;
-static TestMemoryAllocator* currentMallocAllocator = 0;
-
-void setCurrentNewAllocator(TestMemoryAllocator* allocator)
-{
-	currentNewAllocator = allocator;
-}
-
-TestMemoryAllocator* getCurrentNewAllocator()
-{
-	if (currentNewAllocator == 0) setCurrentNewAllocatorToDefault();
-	return currentNewAllocator;
-}
-
-void setCurrentNewAllocatorToDefault()
-{
-	currentNewAllocator = defaultNewAllocator();
-}
-
-TestMemoryAllocator* defaultNewAllocator()
-{
-	static TestMemoryAllocator allocator("Standard New Allocator", "new", "delete");
-	return &allocator;
-}
-
-void setCurrentNewArrayAllocator(TestMemoryAllocator* allocator)
-{
-	currentNewArrayAllocator = allocator;
-}
-
-TestMemoryAllocator* getCurrentNewArrayAllocator()
-{
-	if (currentNewArrayAllocator == 0) setCurrentNewArrayAllocatorToDefault();
-	return currentNewArrayAllocator;
-}
-
-void setCurrentNewArrayAllocatorToDefault()
-{
-	currentNewArrayAllocator = defaultNewArrayAllocator();
-}
-
-TestMemoryAllocator* defaultNewArrayAllocator()
-{
-	static TestMemoryAllocator allocator("Standard New [] Allocator", "new []", "delete []");
-	return &allocator;
-}
-
-void setCurrentMallocAllocator(TestMemoryAllocator* allocator)
-{
-	currentMallocAllocator = allocator;
-}
-
-TestMemoryAllocator* getCurrentMallocAllocator()
-{
-	if (currentMallocAllocator == 0) setCurrentMallocAllocatorToDefault();
-	return currentMallocAllocator;
-}
-
-void setCurrentMallocAllocatorToDefault()
-{
-	currentMallocAllocator = defaultMallocAllocator();
-}
-
-TestMemoryAllocator* defaultMallocAllocator()
-{
-	static TestMemoryAllocator allocator("Standard Malloc Allocator", "malloc", "free");
-	return &allocator;
-}
-
-/////////////////////////////////////////////
-
-TestMemoryAllocator::TestMemoryAllocator(const char* name_str, const char* alloc_name_str, const char* free_name_str)
-	: name_(name_str), alloc_name_(alloc_name_str), free_name_(free_name_str), hasBeenDestroyed_(false)
-{
-}
-
-TestMemoryAllocator::~TestMemoryAllocator()
-{
-	hasBeenDestroyed_ = true;
-}
-
-bool TestMemoryAllocator::hasBeenDestroyed()
-{
-	return hasBeenDestroyed_;
-}
-
-bool TestMemoryAllocator::isOfEqualType(TestMemoryAllocator* allocator)
-{
-	return PlatformSpecificStrCmp(this->name(), allocator->name()) == 0;
-}
-
-char* TestMemoryAllocator::allocMemoryLeakNode(size_t size)
-{
-	return alloc_memory(size, "MemoryLeakNode", 1);
-}
-
-void TestMemoryAllocator::freeMemoryLeakNode(char* memory)
-{
-	free_memory(memory, "MemoryLeakNode", 1);
-}
-
-char* TestMemoryAllocator::alloc_memory(size_t size, const char*, int)
-{
-	return checkedMalloc(size);
-}
-
-void TestMemoryAllocator::free_memory(char* memory, const char*, int)
-{
-	PlatformSpecificFree(memory);
-}
-const char* TestMemoryAllocator::name()
-{
-	return name_;
-}
-
-const char* TestMemoryAllocator::alloc_name()
-{
-	return alloc_name_;
-}
-
-const char* TestMemoryAllocator::free_name()
-{
-	return free_name_;
-}
-
-CrashOnAllocationAllocator::CrashOnAllocationAllocator() : allocationToCrashOn_(0)
-{
-}
-
-void CrashOnAllocationAllocator::setNumberToCrashOn(unsigned allocationToCrashOn)
-{
-	allocationToCrashOn_ = allocationToCrashOn;
-}
-
-char* CrashOnAllocationAllocator::alloc_memory(size_t size, const char* file, int line)
-{
-	if (MemoryLeakWarningPlugin::getGlobalDetector()->getCurrentAllocationNumber() == allocationToCrashOn_)
-		UT_CRASH();
-
-	return TestMemoryAllocator::alloc_memory(size, file, line);
-}
-
-
-char* NullUnknownAllocator::alloc_memory(size_t /*size*/, const char*, int)
-{
-	return 0;
-}
-
-void NullUnknownAllocator::free_memory(char* /*memory*/, const char*, int)
-{
-}
-
-NullUnknownAllocator::NullUnknownAllocator()
-	: TestMemoryAllocator("Null Allocator", "unknown", "unknown")
-{
-}
-
-
-TestMemoryAllocator* NullUnknownAllocator::defaultAllocator()
-{
-	static NullUnknownAllocator allocator;
-	return &allocator;
-}
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/TestMemoryAllocator.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+#include "CppUTest/MemoryLeakDetector.h"
+
+static char* checkedMalloc(size_t size)
+{
+	char* mem = (char*) PlatformSpecificMalloc(size);
+	if (mem == 0)
+	FAIL("malloc returned null pointer");
+	return mem;
+}
+
+static TestMemoryAllocator* currentNewAllocator = 0;
+static TestMemoryAllocator* currentNewArrayAllocator = 0;
+static TestMemoryAllocator* currentMallocAllocator = 0;
+
+void setCurrentNewAllocator(TestMemoryAllocator* allocator)
+{
+	currentNewAllocator = allocator;
+}
+
+TestMemoryAllocator* getCurrentNewAllocator()
+{
+	if (currentNewAllocator == 0) setCurrentNewAllocatorToDefault();
+	return currentNewAllocator;
+}
+
+void setCurrentNewAllocatorToDefault()
+{
+	currentNewAllocator = defaultNewAllocator();
+}
+
+TestMemoryAllocator* defaultNewAllocator()
+{
+	static TestMemoryAllocator allocator("Standard New Allocator", "new", "delete");
+	return &allocator;
+}
+
+void setCurrentNewArrayAllocator(TestMemoryAllocator* allocator)
+{
+	currentNewArrayAllocator = allocator;
+}
+
+TestMemoryAllocator* getCurrentNewArrayAllocator()
+{
+	if (currentNewArrayAllocator == 0) setCurrentNewArrayAllocatorToDefault();
+	return currentNewArrayAllocator;
+}
+
+void setCurrentNewArrayAllocatorToDefault()
+{
+	currentNewArrayAllocator = defaultNewArrayAllocator();
+}
+
+TestMemoryAllocator* defaultNewArrayAllocator()
+{
+	static TestMemoryAllocator allocator("Standard New [] Allocator", "new []", "delete []");
+	return &allocator;
+}
+
+void setCurrentMallocAllocator(TestMemoryAllocator* allocator)
+{
+	currentMallocAllocator = allocator;
+}
+
+TestMemoryAllocator* getCurrentMallocAllocator()
+{
+	if (currentMallocAllocator == 0) setCurrentMallocAllocatorToDefault();
+	return currentMallocAllocator;
+}
+
+void setCurrentMallocAllocatorToDefault()
+{
+	currentMallocAllocator = defaultMallocAllocator();
+}
+
+TestMemoryAllocator* defaultMallocAllocator()
+{
+	static TestMemoryAllocator allocator("Standard Malloc Allocator", "malloc", "free");
+	return &allocator;
+}
+
+/////////////////////////////////////////////
+
+TestMemoryAllocator::TestMemoryAllocator(const char* name_str, const char* alloc_name_str, const char* free_name_str)
+	: name_(name_str), alloc_name_(alloc_name_str), free_name_(free_name_str), hasBeenDestroyed_(false)
+{
+}
+
+TestMemoryAllocator::~TestMemoryAllocator()
+{
+	hasBeenDestroyed_ = true;
+}
+
+bool TestMemoryAllocator::hasBeenDestroyed()
+{
+	return hasBeenDestroyed_;
+}
+
+bool TestMemoryAllocator::isOfEqualType(TestMemoryAllocator* allocator)
+{
+	return PlatformSpecificStrCmp(this->name(), allocator->name()) == 0;
+}
+
+char* TestMemoryAllocator::allocMemoryLeakNode(size_t size)
+{
+	return alloc_memory(size, "MemoryLeakNode", 1);
+}
+
+void TestMemoryAllocator::freeMemoryLeakNode(char* memory)
+{
+	free_memory(memory, "MemoryLeakNode", 1);
+}
+
+char* TestMemoryAllocator::alloc_memory(size_t size, const char*, int)
+{
+	return checkedMalloc(size);
+}
+
+void TestMemoryAllocator::free_memory(char* memory, const char*, int)
+{
+	PlatformSpecificFree(memory);
+}
+const char* TestMemoryAllocator::name()
+{
+	return name_;
+}
+
+const char* TestMemoryAllocator::alloc_name()
+{
+	return alloc_name_;
+}
+
+const char* TestMemoryAllocator::free_name()
+{
+	return free_name_;
+}
+
+CrashOnAllocationAllocator::CrashOnAllocationAllocator() : allocationToCrashOn_(0)
+{
+}
+
+void CrashOnAllocationAllocator::setNumberToCrashOn(unsigned allocationToCrashOn)
+{
+	allocationToCrashOn_ = allocationToCrashOn;
+}
+
+char* CrashOnAllocationAllocator::alloc_memory(size_t size, const char* file, int line)
+{
+	if (MemoryLeakWarningPlugin::getGlobalDetector()->getCurrentAllocationNumber() == allocationToCrashOn_)
+		UT_CRASH();
+
+	return TestMemoryAllocator::alloc_memory(size, file, line);
+}
+
+
+char* NullUnknownAllocator::alloc_memory(size_t /*size*/, const char*, int)
+{
+	return 0;
+}
+
+void NullUnknownAllocator::free_memory(char* /*memory*/, const char*, int)
+{
+}
+
+NullUnknownAllocator::NullUnknownAllocator()
+	: TestMemoryAllocator("Null Allocator", "unknown", "unknown")
+{
+}
+
+
+TestMemoryAllocator* NullUnknownAllocator::defaultAllocator()
+{
+	static NullUnknownAllocator allocator;
+	return &allocator;
+}
--- a/src/CppUTest/TestOutput.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestOutput.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,253 +1,253 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestOutput.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-TestOutput::WorkingEnvironment TestOutput::workingEnvironment_ = TestOutput::detectEnvironment;
-
-void TestOutput::setWorkingEnvironment(TestOutput::WorkingEnvironment workEnvironment)
-{
-	workingEnvironment_ = workEnvironment;
-}
-
-TestOutput::WorkingEnvironment TestOutput::getWorkingEnvironment()
-{
-	if (workingEnvironment_ == TestOutput::detectEnvironment)
-		return PlatformSpecificGetWorkingEnvironment();
-	return workingEnvironment_;
-}
-
-
-TestOutput::TestOutput() :
-	dotCount_(0), verbose_(false), progressIndication_(".")
-{
-}
-
-TestOutput::~TestOutput()
-{
-}
-
-void TestOutput::verbose()
-{
-	verbose_ = true;
-}
-
-void TestOutput::print(const char* str)
-{
-	printBuffer(str);
-}
-
-void TestOutput::print(long n)
-{
-	print(StringFrom(n).asCharString());
-}
-
-void TestOutput::printDouble(double d)
-{
-	print(StringFrom(d).asCharString());
-}
-
-void TestOutput::printHex(long n)
-{
-	print(HexStringFrom(n).asCharString());
-}
-
-TestOutput& operator<<(TestOutput& p, const char* s)
-{
-	p.print(s);
-	return p;
-}
-
-TestOutput& operator<<(TestOutput& p, long int i)
-{
-	p.print(i);
-	return p;
-}
-
-void TestOutput::printCurrentTestStarted(const UtestShell& test)
-{
-	if (verbose_) print(test.getFormattedName().asCharString());
-}
-
-void TestOutput::printCurrentTestEnded(const TestResult& res)
-{
-	if (verbose_) {
-		print(" - ");
-		print(res.getCurrentTestTotalExecutionTime());
-		print(" ms\n");
-	}
-	else {
-		printProgressIndicator();
-	}
-}
-
-void TestOutput::printProgressIndicator()
-{
-	print(progressIndication_);
-	if (++dotCount_ % 50 == 0) print("\n");
-}
-
-void TestOutput::setProgressIndicator(const char* indicator)
-{
-	progressIndication_ = indicator;
-}
-
-void TestOutput::printTestsStarted()
-{
-}
-
-void TestOutput::printCurrentGroupStarted(const UtestShell& /*test*/)
-{
-}
-
-void TestOutput::printCurrentGroupEnded(const TestResult& /*res*/)
-{
-}
-
-void TestOutput::flush()
-{
-}
-
-void TestOutput::printTestsEnded(const TestResult& result)
-{
-	if (result.getFailureCount() > 0) {
-		print("\nErrors (");
-		print(result.getFailureCount());
-		print(" failures, ");
-	}
-	else {
-		print("\nOK (");
-	}
-	print(result.getTestCount());
-	print(" tests, ");
-	print(result.getRunCount());
-	print(" ran, ");
-	print(result.getCheckCount());
-	print(" checks, ");
-	print(result.getIgnoredCount());
-	print(" ignored, ");
-	print(result.getFilteredOutCount());
-	print(" filtered out, ");
-	print(result.getTotalExecutionTime());
-	print(" ms)\n\n");
-}
-
-void TestOutput::printTestRun(int number, int total)
-{
-	if (total > 1) {
-		print("Test run ");
-		print(number);
-		print(" of ");
-		print(total);
-		print("\n");
-	}
-}
-
-void TestOutput::print(const TestFailure& failure)
-{
-	if (failure.isOutsideTestFile() || failure.isInHelperFunction())
-		printFileAndLineForTestAndFailure(failure);
-	else
-		printFileAndLineForFailure(failure);
-
-	printFailureMessage(failure.getMessage());
-}
-
-void TestOutput::printFileAndLineForTestAndFailure(const TestFailure& failure)
-{
-	printErrorInFileOnLineFormattedForWorkingEnvironment(failure.getTestFileName(), failure.getTestLineNumber());
-	printFailureInTest(failure.getTestName());
-	printErrorInFileOnLineFormattedForWorkingEnvironment(failure.getFileName(), failure.getFailureLineNumber());
-}
-
-void TestOutput::printFileAndLineForFailure(const TestFailure& failure)
-{
-	printErrorInFileOnLineFormattedForWorkingEnvironment(failure.getFileName(), failure.getFailureLineNumber());
-	printFailureInTest(failure.getTestName());
-}
-
-void TestOutput::printFailureInTest(SimpleString testName)
-{
-	print(" Failure in ");
-	print(testName.asCharString());
-}
-
-void TestOutput::printFailureMessage(SimpleString reason)
-{
-	print("\n");
-	print("\t");
-	print(reason.asCharString());
-	print("\n\n");
-}
-
-void TestOutput::printErrorInFileOnLineFormattedForWorkingEnvironment(SimpleString file, int lineNumber)
-{
-	if (TestOutput::getWorkingEnvironment() == TestOutput::vistualStudio)
-		printVistualStudioErrorInFileOnLine(file, lineNumber);
-	else
-		printEclipseErrorInFileOnLine(file, lineNumber);
-}
-
-void TestOutput::printEclipseErrorInFileOnLine(SimpleString file, int lineNumber)
-{
-	print("\n");
-	print(file.asCharString());
-	print(":");
-	print(lineNumber);
-	print(":");
-	print(" error:");
-}
-
-void TestOutput::printVistualStudioErrorInFileOnLine(SimpleString file, int lineNumber)
-{
-	print("\n");
-	print(file.asCharString());
-	print("(");
-	print(lineNumber);
-	print("):");
-	print(" error:");
-}
-
-void ConsoleTestOutput::printBuffer(const char* s)
-{
-	while (*s) {
-		PlatformSpecificPutchar(*s);
-		s++;
-	}
-	flush();
-}
-
-void ConsoleTestOutput::flush()
-{
-	PlatformSpecificFlush();
-}
-
-StringBufferTestOutput::~StringBufferTestOutput()
-{
-}
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/TestOutput.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+TestOutput::WorkingEnvironment TestOutput::workingEnvironment_ = TestOutput::detectEnvironment;
+
+void TestOutput::setWorkingEnvironment(TestOutput::WorkingEnvironment workEnvironment)
+{
+	workingEnvironment_ = workEnvironment;
+}
+
+TestOutput::WorkingEnvironment TestOutput::getWorkingEnvironment()
+{
+	if (workingEnvironment_ == TestOutput::detectEnvironment)
+		return PlatformSpecificGetWorkingEnvironment();
+	return workingEnvironment_;
+}
+
+
+TestOutput::TestOutput() :
+	dotCount_(0), verbose_(false), progressIndication_(".")
+{
+}
+
+TestOutput::~TestOutput()
+{
+}
+
+void TestOutput::verbose()
+{
+	verbose_ = true;
+}
+
+void TestOutput::print(const char* str)
+{
+	printBuffer(str);
+}
+
+void TestOutput::print(long n)
+{
+	print(StringFrom(n).asCharString());
+}
+
+void TestOutput::printDouble(double d)
+{
+	print(StringFrom(d).asCharString());
+}
+
+void TestOutput::printHex(long n)
+{
+	print(HexStringFrom(n).asCharString());
+}
+
+TestOutput& operator<<(TestOutput& p, const char* s)
+{
+	p.print(s);
+	return p;
+}
+
+TestOutput& operator<<(TestOutput& p, long int i)
+{
+	p.print(i);
+	return p;
+}
+
+void TestOutput::printCurrentTestStarted(const UtestShell& test)
+{
+	if (verbose_) print(test.getFormattedName().asCharString());
+}
+
+void TestOutput::printCurrentTestEnded(const TestResult& res)
+{
+	if (verbose_) {
+		print(" - ");
+		print(res.getCurrentTestTotalExecutionTime());
+		print(" ms\n");
+	}
+	else {
+		printProgressIndicator();
+	}
+}
+
+void TestOutput::printProgressIndicator()
+{
+	print(progressIndication_);
+	if (++dotCount_ % 50 == 0) print("\n");
+}
+
+void TestOutput::setProgressIndicator(const char* indicator)
+{
+	progressIndication_ = indicator;
+}
+
+void TestOutput::printTestsStarted()
+{
+}
+
+void TestOutput::printCurrentGroupStarted(const UtestShell& /*test*/)
+{
+}
+
+void TestOutput::printCurrentGroupEnded(const TestResult& /*res*/)
+{
+}
+
+void TestOutput::flush()
+{
+}
+
+void TestOutput::printTestsEnded(const TestResult& result)
+{
+	if (result.getFailureCount() > 0) {
+		print("\nErrors (");
+		print(result.getFailureCount());
+		print(" failures, ");
+	}
+	else {
+		print("\nOK (");
+	}
+	print(result.getTestCount());
+	print(" tests, ");
+	print(result.getRunCount());
+	print(" ran, ");
+	print(result.getCheckCount());
+	print(" checks, ");
+	print(result.getIgnoredCount());
+	print(" ignored, ");
+	print(result.getFilteredOutCount());
+	print(" filtered out, ");
+	print(result.getTotalExecutionTime());
+	print(" ms)\n\n");
+}
+
+void TestOutput::printTestRun(int number, int total)
+{
+	if (total > 1) {
+		print("Test run ");
+		print(number);
+		print(" of ");
+		print(total);
+		print("\n");
+	}
+}
+
+void TestOutput::print(const TestFailure& failure)
+{
+	if (failure.isOutsideTestFile() || failure.isInHelperFunction())
+		printFileAndLineForTestAndFailure(failure);
+	else
+		printFileAndLineForFailure(failure);
+
+	printFailureMessage(failure.getMessage());
+}
+
+void TestOutput::printFileAndLineForTestAndFailure(const TestFailure& failure)
+{
+	printErrorInFileOnLineFormattedForWorkingEnvironment(failure.getTestFileName(), failure.getTestLineNumber());
+	printFailureInTest(failure.getTestName());
+	printErrorInFileOnLineFormattedForWorkingEnvironment(failure.getFileName(), failure.getFailureLineNumber());
+}
+
+void TestOutput::printFileAndLineForFailure(const TestFailure& failure)
+{
+	printErrorInFileOnLineFormattedForWorkingEnvironment(failure.getFileName(), failure.getFailureLineNumber());
+	printFailureInTest(failure.getTestName());
+}
+
+void TestOutput::printFailureInTest(SimpleString testName)
+{
+	print(" Failure in ");
+	print(testName.asCharString());
+}
+
+void TestOutput::printFailureMessage(SimpleString reason)
+{
+	print("\n");
+	print("\t");
+	print(reason.asCharString());
+	print("\n\n");
+}
+
+void TestOutput::printErrorInFileOnLineFormattedForWorkingEnvironment(SimpleString file, int lineNumber)
+{
+	if (TestOutput::getWorkingEnvironment() == TestOutput::vistualStudio)
+		printVistualStudioErrorInFileOnLine(file, lineNumber);
+	else
+		printEclipseErrorInFileOnLine(file, lineNumber);
+}
+
+void TestOutput::printEclipseErrorInFileOnLine(SimpleString file, int lineNumber)
+{
+	print("\n");
+	print(file.asCharString());
+	print(":");
+	print(lineNumber);
+	print(":");
+	print(" error:");
+}
+
+void TestOutput::printVistualStudioErrorInFileOnLine(SimpleString file, int lineNumber)
+{
+	print("\n");
+	print(file.asCharString());
+	print("(");
+	print(lineNumber);
+	print("):");
+	print(" error:");
+}
+
+void ConsoleTestOutput::printBuffer(const char* s)
+{
+	while (*s) {
+		PlatformSpecificPutchar(*s);
+		s++;
+	}
+	flush();
+}
+
+void ConsoleTestOutput::flush()
+{
+	PlatformSpecificFlush();
+}
+
+StringBufferTestOutput::~StringBufferTestOutput()
+{
+}
--- a/src/CppUTest/TestPlugin.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestPlugin.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,173 +1,173 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestPlugin.h"
-
-TestPlugin::TestPlugin(const SimpleString& name) :
-	next_(NullTestPlugin::instance()), name_(name), enabled_(true)
-{
-}
-
-TestPlugin::TestPlugin(TestPlugin* next) :
-	next_(next), name_("null"), enabled_(true)
-{
-}
-
-TestPlugin::~TestPlugin()
-{
-}
-
-TestPlugin* TestPlugin::addPlugin(TestPlugin* plugin)
-{
-	next_ = plugin;
-	return this;
-}
-
-void TestPlugin::runAllPreTestAction(UtestShell& test, TestResult& result)
-{
-	if (enabled_) preTestAction(test, result);
-	next_->runAllPreTestAction(test, result);
-}
-
-void TestPlugin::runAllPostTestAction(UtestShell& test, TestResult& result)
-{
-	next_ ->runAllPostTestAction(test, result);
-	if (enabled_) postTestAction(test, result);
-}
-
-bool TestPlugin::parseAllArguments(int ac, char** av, int index)
-{
-	return parseAllArguments(ac, const_cast<const char**> (av), index);
-}
-
-bool TestPlugin::parseAllArguments(int ac, const char** av, int index)
-{
-	if (parseArguments(ac, av, index)) return true;
-	if (next_) return next_->parseAllArguments(ac, av, index);
-	return false;
-}
-
-const SimpleString& TestPlugin::getName()
-{
-	return name_;
-}
-
-TestPlugin* TestPlugin::getPluginByName(const SimpleString& name)
-{
-	if (name == name_) return this;
-	if (next_) return next_->getPluginByName(name);
-	return (next_);
-}
-
-TestPlugin* TestPlugin::getNext()
-{
-	return next_;
-}
-TestPlugin* TestPlugin::removePluginByName(const SimpleString& name)
-{
-	TestPlugin* removed = 0;
-	if (next_ && next_->getName() == name) {
-		removed = next_;
-		next_ = next_->next_;
-	}
-	return removed;
-}
-
-void TestPlugin::disable()
-{
-	enabled_ = false;
-}
-
-void TestPlugin::enable()
-{
-	enabled_ = true;
-}
-
-bool TestPlugin::isEnabled()
-{
-	return enabled_;
-}
-
-struct cpputest_pair
-{
-	void **orig;
-	void *orig_value;
-};
-
-//////// SetPlugin
-
-static int pointerTableIndex;
-static cpputest_pair setlist[SetPointerPlugin::MAX_SET];
-
-SetPointerPlugin::SetPointerPlugin(const SimpleString& name) :
-	TestPlugin(name)
-{
-	pointerTableIndex = 0;
-}
-
-SetPointerPlugin::~SetPointerPlugin()
-{
-}
-
-void CppUTestStore(void**function)
-{
-	if (pointerTableIndex >= SetPointerPlugin::MAX_SET) {
-		FAIL("Maximum number of function pointers installed!");
-	}
-	setlist[pointerTableIndex].orig_value = *function;
-	setlist[pointerTableIndex].orig = function;
-	pointerTableIndex++;
-}
-
-void SetPointerPlugin::postTestAction(UtestShell& /*test*/, TestResult& /*result*/)
-{
-	for (int i = pointerTableIndex - 1; i >= 0; i--)
-		*((void**) setlist[i].orig) = setlist[i].orig_value;
-	pointerTableIndex = 0;
-}
-
-//////// NullPlugin
-
-NullTestPlugin::NullTestPlugin() :
-	TestPlugin(0)
-{
-}
-
-NullTestPlugin* NullTestPlugin::instance()
-{
-	static NullTestPlugin _instance;
-	return &_instance;
-}
-
-void NullTestPlugin::runAllPreTestAction(UtestShell&, TestResult&)
-{
-}
-
-void NullTestPlugin::runAllPostTestAction(UtestShell&, TestResult&)
-{
-}
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/TestPlugin.h"
+
+TestPlugin::TestPlugin(const SimpleString& name) :
+	next_(NullTestPlugin::instance()), name_(name), enabled_(true)
+{
+}
+
+TestPlugin::TestPlugin(TestPlugin* next) :
+	next_(next), name_("null"), enabled_(true)
+{
+}
+
+TestPlugin::~TestPlugin()
+{
+}
+
+TestPlugin* TestPlugin::addPlugin(TestPlugin* plugin)
+{
+	next_ = plugin;
+	return this;
+}
+
+void TestPlugin::runAllPreTestAction(UtestShell& test, TestResult& result)
+{
+	if (enabled_) preTestAction(test, result);
+	next_->runAllPreTestAction(test, result);
+}
+
+void TestPlugin::runAllPostTestAction(UtestShell& test, TestResult& result)
+{
+	next_ ->runAllPostTestAction(test, result);
+	if (enabled_) postTestAction(test, result);
+}
+
+bool TestPlugin::parseAllArguments(int ac, char** av, int index)
+{
+	return parseAllArguments(ac, const_cast<const char**> (av), index);
+}
+
+bool TestPlugin::parseAllArguments(int ac, const char** av, int index)
+{
+	if (parseArguments(ac, av, index)) return true;
+	if (next_) return next_->parseAllArguments(ac, av, index);
+	return false;
+}
+
+const SimpleString& TestPlugin::getName()
+{
+	return name_;
+}
+
+TestPlugin* TestPlugin::getPluginByName(const SimpleString& name)
+{
+	if (name == name_) return this;
+	if (next_) return next_->getPluginByName(name);
+	return (next_);
+}
+
+TestPlugin* TestPlugin::getNext()
+{
+	return next_;
+}
+TestPlugin* TestPlugin::removePluginByName(const SimpleString& name)
+{
+	TestPlugin* removed = 0;
+	if (next_ && next_->getName() == name) {
+		removed = next_;
+		next_ = next_->next_;
+	}
+	return removed;
+}
+
+void TestPlugin::disable()
+{
+	enabled_ = false;
+}
+
+void TestPlugin::enable()
+{
+	enabled_ = true;
+}
+
+bool TestPlugin::isEnabled()
+{
+	return enabled_;
+}
+
+struct cpputest_pair
+{
+	void **orig;
+	void *orig_value;
+};
+
+//////// SetPlugin
+
+static int pointerTableIndex;
+static cpputest_pair setlist[SetPointerPlugin::MAX_SET];
+
+SetPointerPlugin::SetPointerPlugin(const SimpleString& name) :
+	TestPlugin(name)
+{
+	pointerTableIndex = 0;
+}
+
+SetPointerPlugin::~SetPointerPlugin()
+{
+}
+
+void CppUTestStore(void**function)
+{
+	if (pointerTableIndex >= SetPointerPlugin::MAX_SET) {
+		FAIL("Maximum number of function pointers installed!");
+	}
+	setlist[pointerTableIndex].orig_value = *function;
+	setlist[pointerTableIndex].orig = function;
+	pointerTableIndex++;
+}
+
+void SetPointerPlugin::postTestAction(UtestShell& /*test*/, TestResult& /*result*/)
+{
+	for (int i = pointerTableIndex - 1; i >= 0; i--)
+		*((void**) setlist[i].orig) = setlist[i].orig_value;
+	pointerTableIndex = 0;
+}
+
+//////// NullPlugin
+
+NullTestPlugin::NullTestPlugin() :
+	TestPlugin(0)
+{
+}
+
+NullTestPlugin* NullTestPlugin::instance()
+{
+	static NullTestPlugin _instance;
+	return &_instance;
+}
+
+void NullTestPlugin::runAllPreTestAction(UtestShell&, TestResult&)
+{
+}
+
+void NullTestPlugin::runAllPostTestAction(UtestShell&, TestResult&)
+{
+}
--- a/src/CppUTest/TestRegistry.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestRegistry.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,216 +1,216 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestRegistry.h"
-
-TestRegistry::TestRegistry() :
-	tests_(&NullTestShell::instance()), firstPlugin_(NullTestPlugin::instance()), runInSeperateProcess_(false)
-{
-}
-
-TestRegistry::~TestRegistry()
-{
-}
-
-void TestRegistry::addTest(UtestShell *test)
-{
-	tests_ = test->addTest(tests_);
-}
-
-void TestRegistry::runAllTests(TestResult& result)
-{
-	bool groupStart = true;
-
-	result.testsStarted();
-	for (UtestShell *test = tests_; !test->isNull(); test = test->getNext()) {
-		if (runInSeperateProcess_) test->setRunInSeperateProcess();
-
-		if (groupStart) {
-			result.currentGroupStarted(test);
-			groupStart = false;
-		}
-
-		result.setProgressIndicator(test->getProgressIndicator());
-		result.countTest();
-		if (testShouldRun(test, result)) {
-			result.currentTestStarted(test);
-			test->runOneTest(firstPlugin_, result);
-			result.currentTestEnded(test);
-		}
-
-		if (endOfGroup(test)) {
-			groupStart = true;
-			result.currentGroupEnded(test);
-		}
-	}
-	result.testsEnded();
-}
-
-bool TestRegistry::endOfGroup(UtestShell* test)
-{
-	return (test->isNull() || test->getGroup() != test->getNext()->getGroup());
-}
-
-int TestRegistry::countTests()
-{
-	return tests_->countTests();
-}
-
-TestRegistry* TestRegistry::currentRegistry_ = 0;
-
-TestRegistry* TestRegistry::getCurrentRegistry()
-{
-	static TestRegistry registry;
-	return (currentRegistry_ == 0) ? &registry : currentRegistry_;
-}
-
-void TestRegistry::setCurrentRegistry(TestRegistry* registry)
-{
-	currentRegistry_ = registry;
-}
-
-void TestRegistry::unDoLastAddTest()
-{
-	tests_ = tests_->getNext();
-
-}
-
-void TestRegistry::nameFilter(const TestFilter& f)
-{
-	nameFilter_ = f;
-}
-
-void TestRegistry::groupFilter(const TestFilter& f)
-{
-	groupFilter_ = f;
-}
-
-TestFilter TestRegistry::getGroupFilter()
-{
-	return groupFilter_;
-}
-
-TestFilter TestRegistry::getNameFilter()
-{
-	return nameFilter_;
-}
-
-void TestRegistry::setRunTestsInSeperateProcess()
-{
-	runInSeperateProcess_ = true;
-}
-
-
-bool TestRegistry::testShouldRun(UtestShell* test, TestResult& result)
-{
-	if (test->shouldRun(groupFilter_, nameFilter_)) return true;
-	else {
-		result.countFilteredOut();
-		return false;
-	}
-}
-
-void TestRegistry::resetPlugins()
-{
-	firstPlugin_ = NullTestPlugin::instance();
-}
-
-void TestRegistry::installPlugin(TestPlugin* plugin)
-{
-	firstPlugin_ = plugin->addPlugin(firstPlugin_);
-}
-
-TestPlugin* TestRegistry::getFirstPlugin()
-{
-	return firstPlugin_;
-}
-
-TestPlugin* TestRegistry::getPluginByName(const SimpleString& name)
-{
-	return firstPlugin_->getPluginByName(name);
-}
-
-void TestRegistry::removePluginByName(const SimpleString& name)
-{
-	if (firstPlugin_->removePluginByName(name) == firstPlugin_) firstPlugin_ = firstPlugin_->getNext();
-	if (firstPlugin_->getName() == name) firstPlugin_ = firstPlugin_->getNext();
-	firstPlugin_->removePluginByName(name);
-}
-
-int TestRegistry::countPlugins()
-{
-	int count = 0;
-	for (TestPlugin* plugin = firstPlugin_; plugin != NullTestPlugin::instance(); plugin = plugin->getNext())
-		count++;
-	return count;
-}
-
-
-UtestShell* TestRegistry::getFirstTest()
-{
-	return tests_;
-}
-
-UtestShell* TestRegistry::getLastTest()
-{
-	UtestShell* current = tests_;
-	while (!current->getNext()->isNull())
-		current = current->getNext();
-	return current;
-}
-
-UtestShell* TestRegistry::getTestWithNext(UtestShell* test)
-{
-	UtestShell* current = tests_;
-	while (!current->getNext()->isNull() && current->getNext() != test)
-		current = current->getNext();
-	return current;
-}
-
-UtestShell* TestRegistry::findTestWithName(const SimpleString& name)
-{
-	UtestShell* current = tests_;
-	while (!current->isNull()) {
-		if (current->getName() == name)
-			return current;
-		current = current->getNext();
-	}
-	return NULL;
-}
-
-UtestShell* TestRegistry::findTestWithGroup(const SimpleString& group)
-{
-	UtestShell* current = tests_;
-	while (!current->isNull()) {
-		if (current->getGroup() == group)
-			return current;
-		current = current->getNext();
-	}
-	return NULL;
-}
-
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/TestRegistry.h"
+
+TestRegistry::TestRegistry() :
+	tests_(&NullTestShell::instance()), firstPlugin_(NullTestPlugin::instance()), runInSeperateProcess_(false)
+{
+}
+
+TestRegistry::~TestRegistry()
+{
+}
+
+void TestRegistry::addTest(UtestShell *test)
+{
+	tests_ = test->addTest(tests_);
+}
+
+void TestRegistry::runAllTests(TestResult& result)
+{
+	bool groupStart = true;
+
+	result.testsStarted();
+	for (UtestShell *test = tests_; !test->isNull(); test = test->getNext()) {
+		if (runInSeperateProcess_) test->setRunInSeperateProcess();
+
+		if (groupStart) {
+			result.currentGroupStarted(test);
+			groupStart = false;
+		}
+
+		result.setProgressIndicator(test->getProgressIndicator());
+		result.countTest();
+		if (testShouldRun(test, result)) {
+			result.currentTestStarted(test);
+			test->runOneTest(firstPlugin_, result);
+			result.currentTestEnded(test);
+		}
+
+		if (endOfGroup(test)) {
+			groupStart = true;
+			result.currentGroupEnded(test);
+		}
+	}
+	result.testsEnded();
+}
+
+bool TestRegistry::endOfGroup(UtestShell* test)
+{
+	return (test->isNull() || test->getGroup() != test->getNext()->getGroup());
+}
+
+int TestRegistry::countTests()
+{
+	return tests_->countTests();
+}
+
+TestRegistry* TestRegistry::currentRegistry_ = 0;
+
+TestRegistry* TestRegistry::getCurrentRegistry()
+{
+	static TestRegistry registry;
+	return (currentRegistry_ == 0) ? &registry : currentRegistry_;
+}
+
+void TestRegistry::setCurrentRegistry(TestRegistry* registry)
+{
+	currentRegistry_ = registry;
+}
+
+void TestRegistry::unDoLastAddTest()
+{
+	tests_ = tests_->getNext();
+
+}
+
+void TestRegistry::nameFilter(const TestFilter& f)
+{
+	nameFilter_ = f;
+}
+
+void TestRegistry::groupFilter(const TestFilter& f)
+{
+	groupFilter_ = f;
+}
+
+TestFilter TestRegistry::getGroupFilter()
+{
+	return groupFilter_;
+}
+
+TestFilter TestRegistry::getNameFilter()
+{
+	return nameFilter_;
+}
+
+void TestRegistry::setRunTestsInSeperateProcess()
+{
+	runInSeperateProcess_ = true;
+}
+
+
+bool TestRegistry::testShouldRun(UtestShell* test, TestResult& result)
+{
+	if (test->shouldRun(groupFilter_, nameFilter_)) return true;
+	else {
+		result.countFilteredOut();
+		return false;
+	}
+}
+
+void TestRegistry::resetPlugins()
+{
+	firstPlugin_ = NullTestPlugin::instance();
+}
+
+void TestRegistry::installPlugin(TestPlugin* plugin)
+{
+	firstPlugin_ = plugin->addPlugin(firstPlugin_);
+}
+
+TestPlugin* TestRegistry::getFirstPlugin()
+{
+	return firstPlugin_;
+}
+
+TestPlugin* TestRegistry::getPluginByName(const SimpleString& name)
+{
+	return firstPlugin_->getPluginByName(name);
+}
+
+void TestRegistry::removePluginByName(const SimpleString& name)
+{
+	if (firstPlugin_->removePluginByName(name) == firstPlugin_) firstPlugin_ = firstPlugin_->getNext();
+	if (firstPlugin_->getName() == name) firstPlugin_ = firstPlugin_->getNext();
+	firstPlugin_->removePluginByName(name);
+}
+
+int TestRegistry::countPlugins()
+{
+	int count = 0;
+	for (TestPlugin* plugin = firstPlugin_; plugin != NullTestPlugin::instance(); plugin = plugin->getNext())
+		count++;
+	return count;
+}
+
+
+UtestShell* TestRegistry::getFirstTest()
+{
+	return tests_;
+}
+
+UtestShell* TestRegistry::getLastTest()
+{
+	UtestShell* current = tests_;
+	while (!current->getNext()->isNull())
+		current = current->getNext();
+	return current;
+}
+
+UtestShell* TestRegistry::getTestWithNext(UtestShell* test)
+{
+	UtestShell* current = tests_;
+	while (!current->getNext()->isNull() && current->getNext() != test)
+		current = current->getNext();
+	return current;
+}
+
+UtestShell* TestRegistry::findTestWithName(const SimpleString& name)
+{
+	UtestShell* current = tests_;
+	while (!current->isNull()) {
+		if (current->getName() == name)
+			return current;
+		current = current->getNext();
+	}
+	return NULL;
+}
+
+UtestShell* TestRegistry::findTestWithGroup(const SimpleString& group)
+{
+	UtestShell* current = tests_;
+	while (!current->isNull()) {
+		if (current->getGroup() == group)
+			return current;
+		current = current->getNext();
+	}
+	return NULL;
+}
+
--- a/src/CppUTest/TestResult.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/TestResult.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -1,142 +1,142 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestResult.h"
-#include "CppUTest/TestFailure.h"
-#include "CppUTest/TestOutput.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-TestResult::TestResult(TestOutput& p) :
-	output_(p), testCount_(0), runCount_(0), checkCount_(0), failureCount_(0), filteredOutCount_(0), ignoredCount_(0), totalExecutionTime_(0), timeStarted_(0), currentTestTimeStarted_(0),
-			currentTestTotalExecutionTime_(0), currentGroupTimeStarted_(0), currentGroupTotalExecutionTime_(0)
-{
-}
-
-void TestResult::setProgressIndicator(const char* indicator)
-{
-	output_.setProgressIndicator(indicator);
-}
-
-TestResult::~TestResult()
-{
-}
-
-void TestResult::currentGroupStarted(UtestShell* test)
-{
-	output_.printCurrentGroupStarted(*test);
-	currentGroupTimeStarted_ = GetPlatformSpecificTimeInMillis();
-}
-
-void TestResult::currentGroupEnded(UtestShell* /*test*/)
-{
-	currentGroupTotalExecutionTime_ = GetPlatformSpecificTimeInMillis() - currentGroupTimeStarted_;
-	output_.printCurrentGroupEnded(*this);
-}
-
-void TestResult::currentTestStarted(UtestShell* test)
-{
-	output_.printCurrentTestStarted(*test);
-	currentTestTimeStarted_ = GetPlatformSpecificTimeInMillis();
-}
-
-void TestResult::print(const char* text)
-{
-	output_.print(text);
-}
-
-void TestResult::currentTestEnded(UtestShell* /*test*/)
-{
-	currentTestTotalExecutionTime_ = GetPlatformSpecificTimeInMillis() - currentTestTimeStarted_;
-	output_.printCurrentTestEnded(*this);
-
-}
-
-void TestResult::addFailure(const TestFailure& failure)
-{
-	output_.print(failure);
-	failureCount_++;
-}
-
-void TestResult::countTest()
-{
-	testCount_++;
-}
-
-void TestResult::countRun()
-{
-	runCount_++;
-}
-
-void TestResult::countCheck()
-{
-	checkCount_++;
-}
-
-void TestResult::countFilteredOut()
-{
-	filteredOutCount_++;
-}
-
-void TestResult::countIgnored()
-{
-	ignoredCount_++;
-}
-
-void TestResult::testsStarted()
-{
-	timeStarted_ = GetPlatformSpecificTimeInMillis();
-	output_.printTestsStarted();
-}
-
-void TestResult::testsEnded()
-{
-	long timeEnded = GetPlatformSpecificTimeInMillis();
-	totalExecutionTime_ = timeEnded - timeStarted_;
-	output_.printTestsEnded(*this);
-}
-
-long TestResult::getTotalExecutionTime() const
-{
-	return totalExecutionTime_;
-}
-
-void TestResult::setTotalExecutionTime(long exTime)
-{
-	totalExecutionTime_ = exTime;
-}
-
-long TestResult::getCurrentTestTotalExecutionTime() const
-{
-	return currentTestTotalExecutionTime_;
-}
-
-long TestResult::getCurrentGroupTotalExecutionTime() const
-{
-	return currentGroupTotalExecutionTime_;
-}
-
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "CppUTest/TestHarness.h"
+#include "CppUTest/TestResult.h"
+#include "CppUTest/TestFailure.h"
+#include "CppUTest/TestOutput.h"
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+TestResult::TestResult(TestOutput& p) :
+	output_(p), testCount_(0), runCount_(0), checkCount_(0), failureCount_(0), filteredOutCount_(0), ignoredCount_(0), totalExecutionTime_(0), timeStarted_(0), currentTestTimeStarted_(0),
+			currentTestTotalExecutionTime_(0), currentGroupTimeStarted_(0), currentGroupTotalExecutionTime_(0)
+{
+}
+
+void TestResult::setProgressIndicator(const char* indicator)
+{
+	output_.setProgressIndicator(indicator);
+}
+
+TestResult::~TestResult()
+{
+}
+
+void TestResult::currentGroupStarted(UtestShell* test)
+{
+	output_.printCurrentGroupStarted(*test);
+	currentGroupTimeStarted_ = GetPlatformSpecificTimeInMillis();
+}
+
+void TestResult::currentGroupEnded(UtestShell* /*test*/)
+{
+	currentGroupTotalExecutionTime_ = GetPlatformSpecificTimeInMillis() - currentGroupTimeStarted_;
+	output_.printCurrentGroupEnded(*this);
+}
+
+void TestResult::currentTestStarted(UtestShell* test)
+{
+	output_.printCurrentTestStarted(*test);
+	currentTestTimeStarted_ = GetPlatformSpecificTimeInMillis();
+}
+
+void TestResult::print(const char* text)
+{
+	output_.print(text);
+}
+
+void TestResult::currentTestEnded(UtestShell* /*test*/)
+{
+	currentTestTotalExecutionTime_ = GetPlatformSpecificTimeInMillis() - currentTestTimeStarted_;
+	output_.printCurrentTestEnded(*this);
+
+}
+
+void TestResult::addFailure(const TestFailure& failure)
+{
+	output_.print(failure);
+	failureCount_++;
+}
+
+void TestResult::countTest()
+{
+	testCount_++;
+}
+
+void TestResult::countRun()
+{
+	runCount_++;
+}
+
+void TestResult::countCheck()
+{
+	checkCount_++;
+}
+
+void TestResult::countFilteredOut()
+{
+	filteredOutCount_++;
+}
+
+void TestResult::countIgnored()
+{
+	ignoredCount_++;
+}
+
+void TestResult::testsStarted()
+{
+	timeStarted_ = GetPlatformSpecificTimeInMillis();
+	output_.printTestsStarted();
+}
+
+void TestResult::testsEnded()
+{
+	long timeEnded = GetPlatformSpecificTimeInMillis();
+	totalExecutionTime_ = timeEnded - timeStarted_;
+	output_.printTestsEnded(*this);
+}
+
+long TestResult::getTotalExecutionTime() const
+{
+	return totalExecutionTime_;
+}
+
+void TestResult::setTotalExecutionTime(long exTime)
+{
+	totalExecutionTime_ = exTime;
+}
+
+long TestResult::getCurrentTestTotalExecutionTime() const
+{
+	return currentTestTotalExecutionTime_;
+}
+
+long TestResult::getCurrentGroupTotalExecutionTime() const
+{
+	return currentGroupTotalExecutionTime_;
+}
+
--- a/src/CppUTest/Utest.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ b/src/CppUTest/Utest.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -393,6 +393,13 @@
 		failWith(LongsEqualFailure (this, fileName, lineNumber, expected, actual), testTerminator);
 }
 
+void UtestShell::assertUnsignedLongsEqual(unsigned long expected, unsigned long actual, const char* fileName, int lineNumber, const TestTerminator& testTerminator)
+{
+	getTestResult()->countCheck();
+	if (expected != actual)
+		failWith(UnsignedLongsEqualFailure (this, fileName, lineNumber, expected, actual), testTerminator);
+}
+
 void UtestShell::assertPointersEqual(const void* expected, const void* actual, const char* fileName, int lineNumber)
 {
 	getTestResult()->countCheck();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Platforms/armcc/UtestPlatform.cpp	Tue Jun 17 15:52:54 2014 +0100
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the <organization> nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cstdlib>
+#include "CppUTest/TestHarness.h"
+#undef malloc
+#undef free
+#undef calloc
+#undef realloc
+
+#define  far  // eliminate "meaningless type qualifier" warning
+#include "CppUTest/TestRegistry.h"
+#include <time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+
+#include "CppUTest/PlatformSpecificFunctions.h"
+
+static jmp_buf test_exit_jmp_buf[2];
+static int jmp_buf_index = 0;
+
+/* The ARMCC compiler will compile this function with C++ linkage, unless
+ * we specifically tell it to use C linkage again, in the function definiton.
+ */
+extern "C" int PlatformSpecificSetJmp(void (*function) (void* data), void* data)
+{
+	if (0 == setjmp(test_exit_jmp_buf[jmp_buf_index])) {
+	    jmp_buf_index++;
+		function(data);
+	    jmp_buf_index--;
+		return 1;
+	}
+	return 0;
+}
+
+void PlatformSpecificLongJmp()
+{
+	jmp_buf_index--;
+	longjmp(test_exit_jmp_buf[jmp_buf_index], 1);
+}
+
+void PlatformSpecificRestoreJumpBuffer()
+{
+	jmp_buf_index--;
+}
+
+void PlatformSpecificRunTestInASeperateProcess(UtestShell* shell, TestPlugin* plugin, TestResult* result)
+{
+   printf("-p isn' implemented for armcc. Running inside the process\b");
+   shell->runOneTest(plugin, *result);
+}
+
+TestOutput::WorkingEnvironment PlatformSpecificGetWorkingEnvironment()
+{
+	return TestOutput::eclipse;
+}
+
+///////////// Time in millis
+/*
+*  In Keil MDK-ARM, clock() default implementation used semihosting.
+*  Resolutions is user adjustable (1 ms for now)
+*/
+static long TimeInMillisImplementation()
+{
+   clock_t t = clock();
+   return t;
+}
+
+static long (*timeInMillisFp) () = TimeInMillisImplementation;
+
+long GetPlatformSpecificTimeInMillis()
+{
+	return timeInMillisFp();
+}
+
+/* The ARMCC compiler will compile this function with C++ linkage, unless
+ * we specifically tell it to use C linkage again, in the function definiton.
+ */
+extern "C" void SetPlatformSpecificTimeInMillisMethod(long (*platformSpecific) ())
+{
+	timeInMillisFp = (platformSpecific == 0) ? TimeInMillisImplementation : platformSpecific;
+}
+
+///////////// Time in String
+
+static const char* TimeStringImplementation()
+{
+	time_t tm = time(NULL);
+	return ctime(&tm);
+}
+
+static const char* (*timeStringFp) () = TimeStringImplementation;
+
+const char* GetPlatformSpecificTimeString()
+{
+	return timeStringFp();
+}
+
+/* The ARMCC compiler will compile this function with C++ linkage, unless
+ * we specifically tell it to use C linkage again, in the function definiton.
+ */
+extern "C" void SetPlatformSpecificTimeStringMethod(const char* (*platformMethod) ())
+{
+	timeStringFp = (platformMethod == 0) ? TimeStringImplementation : platformMethod;
+}
+
+int PlatformSpecificAtoI(const char* str)
+{
+   return atoi(str);
+}
+
+size_t PlatformSpecificStrLen(const char* str)
+{
+   return strlen(str);
+}
+
+int PlatformSpecificStrCmp(const char* s1, const char* s2)
+{
+   return strcmp(s1, s2);
+}
+
+int PlatformSpecificStrNCmp(const char* s1, const char* s2, size_t size)
+{
+   return strncmp(s1, s2, size);
+}
+
+char* PlatformSpecificStrStr(const char* s1, const char* s2)
+{
+   return strstr((char*)s1, (char*)s2);
+}
+
+/* The ARMCC compiler will compile this function with C++ linkage, unless
+ * we specifically tell it to use C linkage again, in the function definiton.
+ */
+// extern "C" int PlatformSpecificVSNprintf(char *str, size_t size, const char* format, va_list args)
+int PlatformSpecificVSNprintf(char *str, size_t size, const char* format, va_list args)
+{
+   return vsnprintf( str, size, format, args);
+}
+
+char PlatformSpecificToLower(char c)
+{
+	return tolower(c);
+}
+
+PlatformSpecificFile PlatformSpecificFOpen(const char* filename, const char* flag)
+{
+   return fopen(filename, flag);
+}
+
+
+void PlatformSpecificFPuts(const char* str, PlatformSpecificFile file)
+{
+   fputs(str, (FILE*)file);
+}
+
+void PlatformSpecificFClose(PlatformSpecificFile file)
+{
+   fclose((FILE*)file);
+}
+
+void PlatformSpecificFlush()
+{
+  fflush(stdout);
+}
+
+#include "Serial.h"
+using namespace mbed;
+
+int PlatformSpecificPutchar(int c)
+{
+    /* Please modify this block for test results to be reported as
+     * console output. The following is a sample implementation using a
+     * Serial object connected to the console. */
+#define NEED_TEST_REPORT_AS_CONSOLE_OUTPUT 1
+#if NEED_TEST_REPORT_AS_CONSOLE_OUTPUT
+    extern Serial console;
+
+    #define NEED_LINE_FEED_IN_ADDITION_TO_NEWLINE 1
+    #if NEED_LINE_FEED_IN_ADDITION_TO_NEWLINE
+    /* CppUTest emits \n line terminators in its reports; some terminals
+     * need the linefeed (\r) in addition. */
+    if (c == '\n') {
+        console.putc('\r');
+    }
+    #endif /* #if NEED_LINE_FEED_IN_ADDITION_TO_NEWLINE */
+
+    return (console.putc(c));
+#else /* NEED_TEST_REPORT_AS_CONSOLE_OUTPUT */
+    return (0);
+#endif /* NEED_TEST_REPORT_AS_CONSOLE_OUTPUT */
+}
+
+void* PlatformSpecificMalloc(size_t size)
+{
+   return malloc(size);
+}
+
+void* PlatformSpecificRealloc (void* memory, size_t size)
+{
+   return realloc(memory, size);
+}
+
+void PlatformSpecificFree(void* memory)
+{
+   free(memory);
+}
+
+void* PlatformSpecificMemCpy(void* s1, const void* s2, size_t size)
+{
+   return memcpy(s1, s2, size);
+}
+
+void* PlatformSpecificMemset(void* mem, int c, size_t size)
+{
+	return memset(mem, c, size);
+}
+
+double PlatformSpecificFabs(double d)
+{
+   return fabs(d);
+}
+
+int PlatformSpecificIsNan(double d)
+{
+	return isnan(d);
+}
--- a/src/Platforms/mbed/UtestPlatform.cpp	Tue Jan 28 09:27:41 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,312 +0,0 @@
-/*
- * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <setjmp.h>
-#include <ctype.h>
-#include "platform.h"
-
-#include "mbed.h"
-#include "Serial.h"
-#include "error.h"
-
-#include "CppUTest/TestHarness.h"
-
-#include "CppUTest/TestRegistry.h"
-#include "CppUTest/PlatformSpecificFunctions.h"
-
-static jmp_buf test_exit_jmp_buf[10];
-static int     jmp_buf_index = 0;
-
-int
-PlatformSpecificSetJmp(void (* function) (void* data), void* data)
-{
-    if (0 == setjmp(test_exit_jmp_buf[jmp_buf_index])) {
-        jmp_buf_index++;
-        function(data);
-        jmp_buf_index--;
-        return (1);
-    }
-    return (0);
-}
-
-void
-PlatformSpecificLongJmp()
-{
-    jmp_buf_index--;
-    longjmp(test_exit_jmp_buf[jmp_buf_index], 1);
-}
-
-void
-PlatformSpecificRestoreJumpBuffer()
-{
-    jmp_buf_index = 0;
-    memset(test_exit_jmp_buf, 0, sizeof(test_exit_jmp_buf));
-}
-
-void
-PlatformSpecificRunTestInASeperateProcess(UtestShell* shell,
-                                          TestPlugin* plugin,
-                                          TestResult* result)
-{
-    (void) shell;
-    (void) plugin;
-    (void) result;
-
-    /* To be implemented */
-    error("PlatformSpecificRunTestInASeperateProcess not implemented, but called");
-}
-
-long
-GetPlatformSpecificTimeInMillis()
-{
-    /* To be implemented */
-    return (0);
-}
-
-void
-SetPlatformSpecificTimeInMillisMethod(long (* platformSpecific) ())
-{
-    (void) platformSpecific;
-
-    /* To be implemented */
-    error("SetPlatformSpecificTimeInMillisMethod not implemented, but called");
-}
-
-TestOutput::WorkingEnvironment
-PlatformSpecificGetWorkingEnvironment()
-{
-    return (TestOutput::eclipse);
-}
-
-///////////// Time in String
-
-const char*
-GetPlatformSpecificTimeString()
-{
-    /* To be implemented */
-    error("GetPlatformSpecificTimeString not implemented, but called");
-
-    return (NULL);
-}
-
-void
-SetPlatformSpecificTimeStringMethod(const char* (* platformMethod) ())
-{
-    (void) platformMethod;
-
-    /* To be implemented */
-    error("SetPlatformSpecificTimeStringMethod not implemented, but called");
-}
-
-int
-PlatformSpecificAtoI(const char* str)
-{
-    return (atoi(str));
-}
-
-size_t
-PlatformSpecificStrLen(const char* str)
-{
-    return (strlen(str));
-}
-
-char*
-PlatformSpecificStrCat(char* s1, const char* s2)
-{
-    return (strcat(s1, s2));
-}
-
-char*
-PlatformSpecificStrCpy(char* s1, const char* s2)
-{
-    return (strcpy(s1, s2));
-}
-
-char*
-PlatformSpecificStrNCpy(char* s1, const char* s2, size_t size)
-{
-    return (strncpy(s1, s2, size));
-}
-
-int
-PlatformSpecificStrCmp(const char* s1, const char* s2)
-{
-    return (strcmp(s1, s2));
-}
-
-int
-PlatformSpecificStrNCmp(const char* s1, const char* s2, size_t size)
-{
-    return (strncmp(s1, s2, size));
-}
-
-char*
-PlatformSpecificStrStr(const char* s1, const char* s2)
-{
-    return ((char*) strstr(s1, s2));
-}
-
-int
-PlatformSpecificVSNprintf(char*       str,
-                          size_t      size,
-                          const char* format,
-                          va_list     args)
-{
-    return (vsnprintf( str, size, format, args));
-}
-
-char
-PlatformSpecificToLower(char c)
-{
-    return ((char) tolower((char) c));
-}
-
-PlatformSpecificFile
-PlatformSpecificFOpen(const char* filename, const char* flag)
-{
-    (void) filename;
-    (void) flag;
-
-    /* To be implemented */
-    error("PlatformSpecificFOpen not implemented, but called");
-
-    return (NULL);
-}
-
-void
-PlatformSpecificFPuts(const char* str, PlatformSpecificFile file)
-{
-    (void) str;
-    (void) file;
-
-    /* To be implemented */
-    error("PlatformSpecificFPuts not implemented, but called");
-}
-
-void
-PlatformSpecificFClose(PlatformSpecificFile file)
-{
-    (void) file;
-
-    /* To be implemented */
-    error("PlatformSpecificFClose not implemented, but called");
-}
-
-void
-PlatformSpecificFlush()
-{
-}
-
-int
-PlatformSpecificPutchar(int c)
-{
-	/* Please modify this block for test results to be reported as
-	 * console output. The following is a sample implementation using a
-	 * Serial object connected to the console. */
-#define NEED_TEST_REPORT_AS_CONSOLE_OUTPUT 1
-#if NEED_TEST_REPORT_AS_CONSOLE_OUTPUT
-    extern Serial console;
-
-	#define NEED_LINE_FEED_IN_ADDITION_TO_NEWLINE 1
-	#if NEED_LINE_FEED_IN_ADDITION_TO_NEWLINE
-	/* CppUTest emits \n line terminators in its reports; some terminals
-	 * need the linefeed (\r) in addition. */
-	if (c == '\n') {
-	    console.putc('\r');
-	}
-	#endif /* #if NEED_LINE_FEED_IN_ADDITION_TO_NEWLINE */
-
-    return (console.putc(c));
-#else /* NEED_TEST_REPORT_AS_CONSOLE_OUTPUT */
-    return (0);
-#endif /* NEED_TEST_REPORT_AS_CONSOLE_OUTPUT */
-}
-
-void*
-PlatformSpecificMalloc(size_t size)
-{
-    return (malloc(size));
-}
-
-void*
-PlatformSpecificRealloc (void* memory, size_t size)
-{
-    (void) memory;
-    (void) size;
-
-    /* To be implemented */
-    error("PlatformSpecificRealloc not implemented, but called");
-    return (NULL);
-}
-
-void
-PlatformSpecificFree(void* memory)
-{
-    free(memory);
-}
-
-void*
-PlatformSpecificMemCpy(void* s1, const void* s2, size_t size)
-{
-    (void) size;
-    (void) s1;
-    (void) s2;
-
-    /* To be implemented */
-    error("PlatformSpecificMemCpy not implemented, but called");
-
-    return (NULL);
-}
-
-void*
-PlatformSpecificMemset(void* mem, int c, size_t size)
-{
-    return (memset(mem, c, size));
-}
-
-double
-PlatformSpecificFabs(double d)
-{
-    (void) d;
-
-    /* To be implemented */
-    error("PlatformSpecificFabs not implemented, but called");
-
-    return (0.0);
-}
-
-int
-PlatformSpecificIsNan(double d)
-{
-    (void) d;
-
-    /* To be implemented */
-    error("PlatformSpecificIsNan not implemented, but called");
-
-    return (0);
-}