Add small testing framework.
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/makefile
Added: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
Added: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
Added: branches/xmlbuildsystem/reactos/tools/rbuild/test.h
Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/
Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp
Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/makefile
--- branches/xmlbuildsystem/reactos/tools/rbuild/makefile	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/makefile	2005-01-03 23:04:52 UTC (rev 12767)
@@ -4,10 +4,14 @@
 
 all: $(TARGET)
 
-OBJECTS = rbuild.o
+BASE_OBJECTS = module.o
 
-CLEAN_FILES = *.o rbuild$(EXE_POSTFIX)
+OBJECTS = $(BASE_OBJECTS) rbuild.o
 
+TESTS = tests/moduletest.o
+
+TEST_OBJECTS = $(BASE_OBJECTS) $(TESTS) tests/alltests.o
+
 HOST_CFLAGS = -g -I. -Werror -Wall
 
 HOST_LFLAGS = -g
@@ -19,11 +23,15 @@
 clean:
 	-rm -f *.o
 	-rm -f rbuild$(EXE_POSTFIX)
+	-rm -f tests/*.o
+	-rm -f rbuild_tests$(EXE_POSTFIX)
 endif
 ifeq ($(HOST),mingw32-windows)
 clean:
 	-del *.o
 	-del rbuild$(EXE_POSTFIX)
+	-del tests\*.o
+	-del rbuild_tests$(EXE_POSTFIX)
 endif
 
 .phony: clean
@@ -32,4 +40,10 @@
 	$(HALFVERBOSEECHO) [CXX]     $<
 	$(HOST_CXX) $(HOST_CFLAGS) -c $< -o $@
 
+test: rbuild_tests$(EXE_POSTFIX)
+	$(EXE_PREFIX)rbuild_tests$(EXE_POSTFIX)
+
+rbuild_tests$(EXE_POSTFIX): $(TEST_OBJECTS)
+	$(HOST_CXX) $(TEST_OBJECTS) $(HOST_LFLAGS) -o rbuild_tests$(EXE_POSTFIX)
+
 include $(PATH_TO_TOP)/rules.mak

Added: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-01-03 23:04:52 UTC (rev 12767)
@@ -0,0 +1,5 @@
+#include "rbuild.h"
+
+Module::Module(XMLElement moduleNode)
+{	
+}

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.cpp	2005-01-03 23:04:52 UTC (rev 12767)
@@ -4,18 +4,11 @@
 #pragma warning ( disable : 4786 )
 #endif//_MSC_VER
 
-#include <string>
-#include <vector>
-
 #include <stdio.h>
 #include <io.h>
 #include <assert.h>
-//#include <sys/stat.h>
-//#include <sys/types.h>
+#include "rbuild.h"
 
-using std::string;
-using std::vector;
-
 #ifdef _MSC_VER
 unsigned __int64
 #else
@@ -36,218 +29,216 @@
 static const char* WS = " \t\r\n";
 static const char* WSEQ = " =\t\r\n";
 
-class XMLFile
+XMLFile::XMLFile()
 {
-	vector<FILE*> _f;
-	string _buf;
-	const char *_p, *_end;
-public:
-	XMLFile() {}
-	void close()
+}
+
+void XMLFile::close()
+{
+	while ( _f.size() )
 	{
-		while ( _f.size() )
-		{
-			fclose ( _f.back() );
-			_f.pop_back();
-		}
-		_buf.resize(0);
-		_p = _end = NULL;
+		fclose ( _f.back() );
+		_f.pop_back();
 	}
-	bool open ( const char* filename )
+	_buf.resize(0);
+	_p = _end = NULL;
+}
+
+bool XMLFile::open(const char* filename)
+{
+	close();
+	FILE* f = fopen ( filename, "r" );
+	if ( !f )
+		return false;
+	unsigned long len = (unsigned long)filelen(f);
+	_buf.resize ( len );
+	fread ( &_buf[0], 1, len, f );
+	_p = _buf.c_str();
+	_end = _p + len;
+	_f.push_back ( f );
+	next_token();
+	return true;
+}
+
+// next_token() moves the pointer to next token, which may be
+// an xml element or a text element, basically it's a glorified
+// skipspace, normally the user of this class won't need to call
+// this function
+void XMLFile::next_token()
+{
+	_p += strspn ( _p, WS );
+}
+
+bool XMLFile::next_is_text()
+{
+	return *_p != '<';
+}
+
+bool XMLFile::more_tokens()
+{
+	return _p != _end;
+}
+
+// get_token() is used to return a token, and move the pointer
+// past the token
+bool XMLFile::get_token(string& token)
+{
+	const char* tokend;
+	if ( *_p == '<' )
 	{
-		close();
-		FILE* f = fopen ( filename, "r" );
-		if ( !f )
-			return false;
-		unsigned long len = (unsigned long)filelen(f);
-		_buf.resize ( len );
-		fread ( &_buf[0], 1, len, f );
-		_p = _buf.c_str();
-		_end = _p + len;
-		_f.push_back ( f );
-		next_token();
-		return true;
+		tokend = strchr ( _p, '>' );
+		if ( !tokend )
+			tokend = _end;
+		else
+			++tokend;
 	}
-	// next_token() moves the pointer to next token, which may be
-	// an xml element or a text element, basically it's a glorified
-	// skipspace, normally the user of this class won't need to call
-	// this function
-	void next_token()
+	else
 	{
-		_p += strspn ( _p, WS );
+		tokend = strchr ( _p, '<' );
+		if ( !tokend )
+			tokend = _end;
+		while ( tokend > _p && isspace(tokend[-1]) )
+			--tokend;
 	}
-	bool next_is_text()
-	{
-		return *_p != '<';
-	}
-	bool more_tokens()
-	{
-		return _p != _end;
-	}
-	// get_token() is used to return a token, and move the pointer
-	// past the token
-	bool get_token ( string& token )
-	{
-		const char* tokend;
-		if ( *_p == '<' )
-		{
-			tokend = strchr ( _p, '>' );
-			if ( !tokend )
-				tokend = _end;
-			else
-				++tokend;
-		}
-		else
-		{
-			tokend = strchr ( _p, '<' );
-			if ( !tokend )
-				tokend = _end;
-			while ( tokend > _p && isspace(tokend[-1]) )
-				--tokend;
-		}
-		if ( tokend == _p )
-			return false;
-		token = string ( _p, tokend-_p );
-		_p = tokend;
-		next_token();
-		return true;
-	}
+	if ( tokend == _p )
+		return false;
+	token = string ( _p, tokend-_p );
+	_p = tokend;
+	next_token();
+	return true;
+}
+
 #if 0
-	bool getc ( char& c )
+bool XMLFile::getc(char& c)
+{
+	while ( _bufidx >= _buf.size() )
 	{
-		while ( _bufidx >= _buf.size() )
+		static buf[4096];
+		if ( !fgets ( buf, sizeof(buf), _f.back() ) )
 		{
-			static buf[4096];
-			if ( !fgets ( buf, sizeof(buf), _f.back() ) )
-			{
-				fclose ( _f.back() );
-				f.pop_back();
-				continue;
-			}
-			_buf = buf;
-			_bufidx = 0;
-			// REM TODO FIXME - check for and load includes here...
-			/*char* p = &_buf[0];
-			p += strspn ( p, " \t" );
-			if ( *p++ != '#' )
-				break;
-			p += strspn ( p, " \t" );
-			if ( strncmp ( p, "include", 7 ) )
-				break;
-			p += 7;
-			if ( !isspace(*p++) )
-				break;*/
-
+			fclose ( _f.back() );
+			f.pop_back();
+			continue;
 		}
-		c = _buf[_bufidx++];
-		return true;
+		_buf = buf;
+		_bufidx = 0;
+		// REM TODO FIXME - check for and load includes here...
+		/*char* p = &_buf[0];
+		p += strspn ( p, " \t" );
+		if ( *p++ != '#' )
+			break;
+		p += strspn ( p, " \t" );
+		if ( strncmp ( p, "include", 7 ) )
+			break;
+		p += 7;
+		if ( !isspace(*p++) )
+			break;*/
+
 	}
+	c = _buf[_bufidx++];
+	return true;
+}
 #endif
-};
 
-class XMLAttribute
+
+XMLAttribute::XMLAttribute()
 {
-public:
-	string name, value;
+}
 
-	XMLAttribute() {}
+XMLAttribute::XMLAttribute(const string& name_,
+                           const string& value_)
+: name(name_), value(value_)
+{
+}
 
-	XMLAttribute ( const string& name_, const string& value_ )
-		: name(name_), value(value_)
-	{
-	}
+XMLAttribute::XMLAttribute(const XMLAttribute& src)
+{
+	name = src.name;
+	value = src.value;
+}
 
-	XMLAttribute ( const XMLAttribute& src )
-	{
-		name = src.name;
-		value = src.value;
-	}
+XMLAttribute& XMLAttribute::operator=(const XMLAttribute& src)
+{
+	name = src.name;
+	value = src.value;
+	return *this;
+}
 
-	XMLAttribute& operator = ( const XMLAttribute& src )
-	{
-		name = src.name;
-		value = src.value;
-		return *this;
-	}
-};
 
-class XMLElement
+XMLElement::XMLElement()
 {
-public:
-	string name;
-	vector<XMLAttribute> attributes;
-	vector<XMLElement*> subElements;
-	string value;
+}
 
-	XMLElement() {}
-	// Parse() returns true if you need to look for a </tag> for
-	// this one...
-	bool Parse ( const string& token, bool& end_tag )
+// Parse() returns true if you need to look for a </tag> for
+// this one...
+bool XMLElement::Parse(const string& token,
+                       bool& end_tag)
+{
+	const char* p = token.c_str();
+	assert ( *p == '<' );
+	p++;
+	p += strspn ( p, WS );
+	end_tag = ( *p == '/' );
+	if ( end_tag )
 	{
-		const char* p = token.c_str();
-		assert ( *p == '<' );
-		p++;
+		++p;
 		p += strspn ( p, WS );
-		end_tag = ( *p == '/' );
-		if ( end_tag )
-		{
-			++p;
-			p += strspn ( p, WS );
-		}
-		const char* end = strpbrk ( p, WS );
+	}
+	const char* end = strpbrk ( p, WS );
+	if ( !end )
+	{
+		end = strpbrk ( p, "/>" );
+		assert ( end );
+	}
+	name = string ( p, end-p );
+	p = end;
+	p += strspn ( p, WS );
+	while ( *p != '>' && *p != '/' )
+	{
+		end = strpbrk ( p, WSEQ );
 		if ( !end )
 		{
 			end = strpbrk ( p, "/>" );
 			assert ( end );
 		}
-		name = string ( p, end-p );
+		string attribute ( p, end-p ), value;
 		p = end;
 		p += strspn ( p, WS );
-		while ( *p != '>' && *p != '/' )
+		if ( *p == '=' )
 		{
-			end = strpbrk ( p, WSEQ );
+			++p;
+			p += strspn ( p, WS );
+			char quote = 0;
+			if ( strchr ( "\"'", *p ) )
+			{
+				quote = *p++;
+				end = strchr ( p, quote );
+			}
+			else
+			{
+				end = strpbrk ( p, WS );
+			}
 			if ( !end )
 			{
-				end = strpbrk ( p, "/>" );
-				assert ( end );
+				end = strchr ( p, '>' );
+				assert(end);
+				if ( end[-1] == '/' )
+					end--;
 			}
-			string attribute ( p, end-p ), value;
+			value = string ( p, end-p );
 			p = end;
+			if ( quote && *p == quote )
+				p++;
 			p += strspn ( p, WS );
-			if ( *p == '=' )
-			{
-				++p;
-				p += strspn ( p, WS );
-				char quote = 0;
-				if ( strchr ( "\"'", *p ) )
-				{
-					quote = *p++;
-					end = strchr ( p, quote );
-				}
-				else
-				{
-					end = strpbrk ( p, WS );
-				}
-				if ( !end )
-				{
-					end = strchr ( p, '>' );
-					assert(end);
-					if ( end[-1] == '/' )
-						end--;
-				}
-				value = string ( p, end-p );
-				p = end;
-				if ( quote && *p == quote )
-					p++;
-				p += strspn ( p, WS );
-			}
-			attributes.push_back ( XMLAttribute ( attribute, value ) );
 		}
-		return !( *p == '/' ) && !end_tag;
+		attributes.push_back ( XMLAttribute ( attribute, value ) );
 	}
-};
+	return !( *p == '/' ) && !end_tag;
+}
 
-XMLElement* XMLParse ( XMLFile& f, bool* pend_tag = NULL )
+
+XMLElement* XMLParse(XMLFile& f,
+                     bool* pend_tag = NULL)
 {
 	string token;
 	if ( !f.get_token(token) )
@@ -310,11 +301,11 @@
 		return -1;
 	}
 
-	XMLElement* head = XMLParse ( f );
-  if (head)
-  {
-	  // REM TODO FIXME actually do something with the parsed info
-  }
+	XMLElement* head = XMLParse(f);
+	if (head)
+	{
+		// REM TODO FIXME actually do something with the parsed info
+	}
 
 	return 0;
 }

Added: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-01-03 23:04:52 UTC (rev 12767)
@@ -0,0 +1,64 @@
+#ifndef __RBUILD_H
+#define __RBUILD_H
+
+#include <string>
+#include <vector>
+
+using std::string;
+using std::vector;
+
+class XMLFile
+{
+	friend class XMLElement;
+public:
+	XMLFile();
+	void close();
+	bool open(const char* filename);
+	void next_token();
+	bool next_is_text();
+	bool more_tokens();
+	bool get_token(string& token);
+
+private:
+	vector<FILE*> _f;
+	string _buf;
+
+	const char *_p, *_end;
+};
+
+
+class XMLAttribute
+{
+public:
+	string name;
+	string value;
+
+	XMLAttribute();
+	XMLAttribute ( const string& name_, const string& value_ );
+//		: name(name_), value(value_);
+	XMLAttribute ( const XMLAttribute& src );
+	XMLAttribute& operator = ( const XMLAttribute& src );
+};
+
+
+class XMLElement
+{
+public:
+	string name;
+	vector<XMLAttribute> attributes;
+	vector<XMLElement*> subElements;
+	string value;
+
+	XMLElement();
+	bool Parse(const string& token,
+	           bool& end_tag);
+};
+
+
+class Module
+{
+public:
+	Module(XMLElement moduleNode);
+};
+
+#endif /* __RBUILD_H */

Added: branches/xmlbuildsystem/reactos/tools/rbuild/test.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/test.h	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/test.h	2005-01-03 23:04:52 UTC (rev 12767)
@@ -0,0 +1,30 @@
+#ifndef __TEST_H
+#define __TEST_H
+
+#include "rbuild.h"
+
+class BaseTest
+{
+public:
+	bool Failed;
+	BaseTest();
+	/*virtual void Run();*/
+protected:
+	void Assert(char *message);
+	void IsTrue(bool condition);
+	void IsFalse(bool condition);
+	void AreEqual(int expected,
+	              int actual);
+	void AreNotEqual(int expected,
+	                 int actual);
+private:
+	void Fail();
+};
+
+
+class ModuleTest : public BaseTest
+{
+	void Run();
+};
+
+#endif /* __TEST_H */

Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/alltests.cpp	2005-01-03 23:04:52 UTC (rev 12767)
@@ -0,0 +1,123 @@
+#include "rbuild.h"
+#include "test.h"
+
+BaseTest::BaseTest()
+{
+	Failed = true;
+}
+/*
+void BaseTest::Run()
+{
+}
+*/
+void BaseTest::Assert(char *message)
+{
+	printf(message);
+	Fail();
+}
+
+void BaseTest::IsTrue(bool condition)
+{
+	if (!condition)
+	{
+		char message[100];
+		sprintf(message,
+		        "Condition was not true at %s:%d",
+		        __FILE__,
+		        __LINE__);
+		Assert(message);
+	}
+}
+
+void BaseTest::IsFalse(bool condition)
+{
+	if (condition)
+	{
+		char message[100];
+		sprintf(message,
+		        "Condition was not false at %s:%d",
+		        __FILE__,
+		        __LINE__);
+		Assert(message);
+	}
+}
+
+void BaseTest::AreEqual(int expected,
+                        int actual)
+{
+	if (actual != expected)
+	{
+		char message[100];
+		sprintf(message,
+		        "Expected %d/0x%.08x was %d/0x%.08x at %s:%d",
+		        expected,
+		        expected,
+		        actual,
+		        actual,
+		        __FILE__,
+		        __LINE__);
+		Assert(message);
+	}
+}
+
+void BaseTest::AreNotEqual(int expected,
+                           int actual)
+{
+	if (actual == expected)
+	{
+		char message[100];
+		sprintf(message,
+		        "Actual value expected to be different from %d/0x%.08x at %s:%d",
+		        expected,
+		        expected,
+		        __FILE__,
+		        __LINE__);
+		Assert(message);
+	}
+}
+
+void BaseTest::Fail()
+{
+	Failed = true;
+}
+
+
+class TestDispatcher
+{
+public:
+	void Run()
+	{
+		int numberOfFailedTests = 0;
+		vector<BaseTest> tests = GetTests();
+		for (size_t i = 0; i < tests.size(); i++)
+		{
+			BaseTest& test = tests[i];
+			/*test.Run();*/
+			if (test.Failed)
+				numberOfFailedTests++;
+		}
+		
+		if (numberOfFailedTests > 0)
+			printf("%d tests failed",
+			       numberOfFailedTests);
+		else
+			printf("All tests succeeded");
+	}
+
+private:
+	vector<BaseTest> GetTests()
+	{
+		vector<BaseTest> tests;
+		tests.push_back(ModuleTest());
+		return tests;
+	}
+};
+
+
+int main(int argc,
+         char** argv)
+{
+	TestDispatcher testDispatcher = TestDispatcher();
+	testDispatcher.Run();
+	return 0;
+};

Added: branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp	2005-01-03 23:02:15 UTC (rev 12766)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/moduletest.cpp	2005-01-03 23:04:52 UTC (rev 12767)
@@ -0,0 +1,6 @@
+#include "test.h"
+
+void ModuleTest::Run()
+{
+	IsTrue(false);
+}