fork

Fork of cpputest by Rohit Grover

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);
-}