Build and run tests
Modified: branches/xmlbuildsystem/reactos/lib/kernel32/include/kernel32.h
Modified: branches/xmlbuildsystem/reactos/lib/kernel32/kernel32.xml
Modified: branches/xmlbuildsystem/reactos/lib/kernel32/mem/heap.c
Modified: branches/xmlbuildsystem/reactos/lib/kernel32/tests/Makefile
Modified: branches/xmlbuildsystem/reactos/lib/kernel32/tests/kernel32.xml
Modified: branches/xmlbuildsystem/reactos/lib/kernel32/tests/stubs.xml
Modified: branches/xmlbuildsystem/reactos/regtests/regtests/regtests.def
Modified: branches/xmlbuildsystem/reactos/regtests/shared/regtests.c
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/functiontest.cpp
Modified: branches/xmlbuildsystem/reactos/tools/rbuild/testsupportcode.cpp

Modified: branches/xmlbuildsystem/reactos/lib/kernel32/include/kernel32.h
--- branches/xmlbuildsystem/reactos/lib/kernel32/include/kernel32.h	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/lib/kernel32/include/kernel32.h	2005-05-15 22:07:07 UTC (rev 15324)
@@ -66,9 +66,8 @@
 DWORD FilenameW2A_FitOrFail(LPSTR  DestA, INT destLen, LPCWSTR SourceW, INT sourceLen);
 DWORD FilenameU2A_FitOrFail(LPSTR  DestA, INT destLen, PUNICODE_STRING SourceU);
 
+#define HeapAlloc RtlAllocateHeap
+#define HeapFree RtlFreeHeap
 
-
-
-
 #endif /* ndef _KERNEL32_INCLUDE_KERNEL32_H */
 

Modified: branches/xmlbuildsystem/reactos/lib/kernel32/kernel32.xml
--- branches/xmlbuildsystem/reactos/lib/kernel32/kernel32.xml	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/lib/kernel32/kernel32.xml	2005-05-15 22:07:07 UTC (rev 15324)
@@ -1,19 +1,3 @@
-<module name="kernel32" type="win32dll" baseaddress="${BASEADDRESS_KERNEL32}" installbase="system32" installname="kernel32.dll">
-	<importlibrary definition="kernel32.def" />
-	<include base="kernel32">.</include>
-	<include base="kernel32">include</include>
-	<define name="_DISABLE_TIDENTS" />
-	<define name="_SEH_NO_NATIVE_NLG" />
-	<define name="WINVER">0x0500</define>
-	<library>kernel32_base</library>
-	<library>pseh</library>
-	<library>rosrtl</library>
-	<library>ntdll</library>
-	<linkerflag>-lgcc</linkerflag>
-	<linkerflag>-nostartfiles</linkerflag>
-	<linkerflag>-nostdlib</linkerflag>
-	<file>kernel32.rc</file>
-</module>
 <module name="kernel32_base" type="objectlibrary">
 	<include base="kernel32_base">.</include>
 	<include base="kernel32_base">include</include>
@@ -120,8 +104,22 @@
 		<file>tls.c</file>
 	</directory>
 </module>
-<!--
+<module name="kernel32" type="win32dll" baseaddress="${BASEADDRESS_KERNEL32}" installbase="system32" installname="kernel32.dll">
+	<importlibrary definition="kernel32.def" />
+	<include base="kernel32">.</include>
+	<include base="kernel32">include</include>
+	<define name="_DISABLE_TIDENTS" />
+	<define name="_SEH_NO_NATIVE_NLG" />
+	<define name="WINVER">0x0500</define>
+	<library>kernel32_base</library>
+	<library>pseh</library>
+	<library>rosrtl</library>
+	<library>ntdll</library>
+	<linkerflag>-lgcc</linkerflag>
+	<linkerflag>-nostartfiles</linkerflag>
+	<linkerflag>-nostdlib</linkerflag>
+	<file>kernel32.rc</file>
+</module>
 <directory name="tests">
 	<xi:include href="tests/kernel32.xml" />
 </directory>
--->
\ No newline at end of file

Modified: branches/xmlbuildsystem/reactos/lib/kernel32/mem/heap.c
--- branches/xmlbuildsystem/reactos/lib/kernel32/mem/heap.c	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/lib/kernel32/mem/heap.c	2005-05-15 22:07:07 UTC (rev 15324)
@@ -32,17 +32,6 @@
 #define NDEBUG
 #include "../include/debug.h"
 
-PVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes)
-{
-   return RtlAllocateHeap(hHeap, dwFlags, dwBytes);
-}
-
-BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
-{
-   return RtlFreeHeap(hHeap, dwFlags, lpMem);
-}
-
-
 /*********************************************************************
 *                     HeapCreate -- KERNEL32                         *
 *********************************************************************/

Modified: branches/xmlbuildsystem/reactos/lib/kernel32/tests/Makefile
--- branches/xmlbuildsystem/reactos/lib/kernel32/tests/Makefile	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/lib/kernel32/tests/Makefile	2005-05-15 22:07:07 UTC (rev 15324)
@@ -1,23 +1,5 @@
-# $Id$
+# This file is automatically generated.
 
-PATH_TO_TOP = ../../..
-
-TARGET_TYPE = test
-
-TARGET_NAME = regtests
-
-TARGET_LIBPATH = .
-
-TARGET_CFLAGS = -I$(REGTESTS_PATH_INC)
-
-TARGET_LIBS = ../kernel32.a
-
--include Makefile.tests
-
-TARGET_OBJECTS = \
-  setup.o \
-  $(addprefix tests/, $(TESTS))
-
-include $(PATH_TO_TOP)/rules.mak
-
-include $(TOOLS_PATH)/helper.mk
+TOP = ..\..\..
+DEFAULT = kernel32_test
+include $(TOP)/proxy.mak

Modified: branches/xmlbuildsystem/reactos/lib/kernel32/tests/kernel32.xml
--- branches/xmlbuildsystem/reactos/lib/kernel32/tests/kernel32.xml	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/lib/kernel32/tests/kernel32.xml	2005-05-15 22:07:07 UTC (rev 15324)
@@ -3,11 +3,13 @@
 	<define name="_DISABLE_TIDENTS" />
 	<define name="_SEH_NO_NATIVE_NLG" />
 	<define name="WINVER">0x0500</define>
+	<library>rtshared</library>
+	<library>regtests</library>
 	<library>kernel32_base</library>
 	<library>pseh</library>
 	<library>rosrtl</library>
 	<library>ntdll</library>
-	<library>rtshared</library>
+	<library>msvcrt</library>
 	<linkerflag>-lgcc</linkerflag>
 	<linkerflag>-nostartfiles</linkerflag>
 	<linkerflag>-nostdlib</linkerflag>

Modified: branches/xmlbuildsystem/reactos/lib/kernel32/tests/stubs.xml
--- branches/xmlbuildsystem/reactos/lib/kernel32/tests/stubs.xml	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/lib/kernel32/tests/stubs.xml	2005-05-15 22:07:07 UTC (rev 15324)
@@ -8,7 +8,6 @@
 	<symbol newname="RtlFreeHeap">HeapFree@12</symbol>
 	<symbol>LdrAccessResource@16</symbol>
 	<symbol>LdrDisableThreadCalloutsForDll@4</symbol>
-	<symbol>LdrDisableThreadCalloutsForDll@4</symbol>
 	<symbol>LdrFindResource_U@16</symbol>
 	<symbol>LdrLoadDll@16</symbol>
 	<symbol>LdrShutdownProcess@0</symbol>

Modified: branches/xmlbuildsystem/reactos/regtests/regtests/regtests.def
--- branches/xmlbuildsystem/reactos/regtests/regtests/regtests.def	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/regtests/regtests/regtests.def	2005-05-15 22:07:07 UTC (rev 15324)
@@ -7,4 +7,3 @@
 _CreateThread@24
 _TerminateThread@8
 _WaitForSingleObject@8
-

Modified: branches/xmlbuildsystem/reactos/regtests/shared/regtests.c
--- branches/xmlbuildsystem/reactos/regtests/shared/regtests.c	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/regtests/shared/regtests.c	2005-05-15 22:07:07 UTC (rev 15324)
@@ -60,11 +60,11 @@
 
   if (_Result != TS_OK)
     {
-      sprintf(OutputBuffer, "ROSREGTEST: |%s| Status: Failed (%s)\n", TestName, Buffer);
+      sprintf(OutputBuffer, "[%s] Failed (%s)\n", TestName, Buffer);
     }
   else
     {
-      sprintf(OutputBuffer, "ROSREGTEST: |%s| Status: Success\n", TestName);
+      sprintf(OutputBuffer, "[%s] Success\n", TestName);
     }
   if (OutputRoutine != NULL)
     {
@@ -137,7 +137,7 @@
       if (hThread == NULL)
         {
           sprintf(OutputBuffer,
-                  "ROSREGTEST: |%s| Status: Failed (CreateThread failed: 0x%x)\n",
+                  "[%s] Failed (CreateThread failed: 0x%x)\n",
                   Name, (unsigned int)GetLastError());
         }
       else if (_WaitForSingleObject(hThread, TimeOut) == WAIT_TIMEOUT)
@@ -145,12 +145,12 @@
           if (!_TerminateThread(hThread, 0))
             {
               sprintf(OutputBuffer,
-                      "ROSREGTEST: |%s| Status: Failed (Test timed out - %d ms, TerminateThread failed: 0x%x)\n",
+                      "[%s] Failed (Test timed out - %d ms, TerminateThread failed: 0x%x)\n",
                       Name, (int)TimeOut, (unsigned int)GetLastError());
             }
           else
             {
-              sprintf(OutputBuffer, "ROSREGTEST: |%s| Status: Failed (Test timed out - %d ms)\n", Name, (int)TimeOut);
+              sprintf(OutputBuffer, "[%s] Failed (Test timed out - %d ms)\n", Name, (int)TimeOut);
             }
         }
       else

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.cpp	2005-05-15 22:07:07 UTC (rev 15324)
@@ -280,6 +280,7 @@
 
 	GenerateAllTarget ( v );
 	GenerateInitTarget ();
+	GenerateRegTestsRunTarget ();
 
 	for ( i = 0; i < iend; i++ )
 		v[i]->GenerateOtherMacros();
@@ -559,6 +560,18 @@
 }
 
 void
+MingwBackend::GenerateRegTestsRunTarget () const
+{
+	fprintf ( fMakefile,
+	          "REGTESTS_RUN_TARGET = regtests.dll\n" );
+	fprintf ( fMakefile,
+	          "$(REGTESTS_RUN_TARGET):\n" );
+	fprintf ( fMakefile,
+	          "\t$(cp) $(REGTESTS_TARGET) $(REGTESTS_RUN_TARGET)\n" );
+	fprintf ( fMakefile, "\n" );
+}
+
+void
 MingwBackend::GenerateXmlBuildFilesMacro() const
 {
 	fprintf ( fMakefile,

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/mingw.h	2005-05-15 22:07:07 UTC (rev 15324)
@@ -77,6 +77,7 @@
 	void GenerateAllTarget ( const std::vector<MingwModuleHandler*>& handlers ) const;
 	std::string GetBuildToolDependencies () const;
 	void GenerateInitTarget () const;
+	void GenerateRegTestsRunTarget () const;
 	void GenerateXmlBuildFilesMacro() const;
 	std::string GetBin2ResExecutable ();
 	void UnpackWineResources ();

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.cpp	2005-05-15 22:07:07 UTC (rev 15324)
@@ -349,16 +349,15 @@
 }
 
 void
-MingwModuleHandler::GetSourceFilenames (
-	string_list& list,
-	bool includeGeneratedFiles ) const
+MingwModuleHandler::GetSourceFilenames ( string_list& list,
+                                         bool includeGeneratedFiles ) const
 {
 	size_t i;
 
 	const vector<File*>& files = module.non_if_data.files;
 	for ( i = 0; i < files.size (); i++ )
 	{
-		if ( includeGeneratedFiles || !IsGeneratedFile ( *files[i] ) )
+		if ( includeGeneratedFiles || !files[i]->IsGeneratedFile () )
 		{
 			list.push_back (
 				GetActualSourceFilename ( files[i]->name ) );
@@ -379,7 +378,7 @@
 		for ( j = 0; j < files.size (); j++ )
 		{
 			File& file = *files[j];
-			if ( includeGeneratedFiles || !IsGeneratedFile ( file ) )
+			if ( includeGeneratedFiles || !file.IsGeneratedFile () )
 			{
 				list.push_back (
 					GetActualSourceFilename ( file.name ) );
@@ -737,6 +736,18 @@
 }
 
 void
+MingwModuleHandler::CleanupFileVector ( vector<File*>& sourceFiles )
+{
+	for (size_t i = 0; i < sourceFiles.size (); i++)
+		delete sourceFiles[i];
+}
+
+void
+MingwModuleHandler::GetModuleSpecificSourceFiles ( vector<File*>& sourceFiles )
+{
+}
+
+void
 MingwModuleHandler::GenerateObjectMacros (
 	const char* assignmentOperation,
 	const IfableData& data,
@@ -806,6 +817,19 @@
 				"endif\n\n" );
 		}
 	}
+
+	vector<File*> sourceFiles;
+	GetModuleSpecificSourceFiles ( sourceFiles );
+	for ( i = 0; i < sourceFiles.size (); i++ )
+	{
+		fprintf (
+			fMakefile,
+			"%s += %s\n",
+			objectsMacro.c_str(),
+			GetObjectFilename (
+				sourceFiles[i]->name, NULL ).c_str () );
+	}
+	CleanupFileVector ( sourceFiles );
 }
 
 void
@@ -1362,12 +1386,13 @@
 void
 MingwModuleHandler::GeneratePhonyTarget() const
 {
-	string targetMacro ( GetTargetMacro(module) );
-	fprintf ( fMakefile, ".PHONY: %s\n\n",
+	string targetMacro ( GetTargetMacro ( module ) );
+	fprintf ( fMakefile,
+	          ".PHONY: %s\n\n",
 	          targetMacro.c_str ());
 	fprintf ( fMakefile, "%s: | %s\n",
 	          targetMacro.c_str (),
-	          GetDirectory(GetTargetFilename(module,NULL)).c_str () );
+	          GetDirectory ( GetTargetFilename ( module, NULL ) ).c_str () );
 }
 
 void
@@ -1407,6 +1432,20 @@
 		                            windresflagsMacro,
 		                            widlflagsMacro );
 	}
+
+	vector<File*> sourceFiles;
+	GetModuleSpecificSourceFiles ( sourceFiles );
+	for ( i = 0; i < sourceFiles.size (); i++ )
+	{
+		GenerateCommands ( *sourceFiles[i],
+		                   cc,
+		                   cppc,
+		                   cflagsMacro,
+		                   nasmflagsMacro,
+		                   windresflagsMacro,
+		                   widlflagsMacro );
+	}
+	CleanupFileVector ( sourceFiles );
 }
 
 void
@@ -1665,25 +1704,32 @@
 	// generate phony target for module name
 	fprintf ( fMakefile, ".PHONY: %s\n",
 		module.name.c_str () );
+	string dependencies = GetTargetMacro ( module );
+	if ( module.type == Test )
+		dependencies += " $(REGTESTS_RUN_TARGET)";
 	fprintf ( fMakefile, "%s: %s\n\n",
 		module.name.c_str (),
-		GetTargetMacro ( module ).c_str () );
+		dependencies.c_str () );
+	if ( module.type == Test )
+	{
+		fprintf ( fMakefile,
+		          "\t%s\n",
+		          targetMacro.c_str ());
+	}
 
 	if ( !ReferenceObjects ( module ) )
 	{
 		string ar_target ( GenerateArchiveTarget ( ar, objectsMacro ) );
 		if ( targetMacro != ar_target )
-		{
 			CLEAN_FILE ( ar_target );
-		}
 	}
 
 	GenerateObjectFileTargets ( cc,
-								cppc,
-								cflagsMacro,
-								nasmflagsMacro,
-								windresflagsMacro,
-							    widlflagsMacro );
+	                            cppc,
+	                            cflagsMacro,
+	                            nasmflagsMacro,
+	                            windresflagsMacro,
+	                            widlflagsMacro );
 }
 
 void
@@ -2830,6 +2876,15 @@
 }
 
 void
+MingwTestModuleHandler::GetModuleSpecificSourceFiles ( vector<File*>& sourceFiles )
+{
+	string basePath = "$(INTERMEDIATE)" SSEP + module.GetBasePath ();
+	sourceFiles.push_back ( new File ( basePath + SSEP "_hooks.c", false, "" ) );
+	sourceFiles.push_back ( new File ( basePath + SSEP "_stubs.S", false, "" ) );
+	sourceFiles.push_back ( new File ( basePath + SSEP "_startup.c", false, "" ) );
+}
+
+void
 MingwTestModuleHandler::GenerateTestModuleTarget ()
 {
 	string targetMacro ( GetTargetMacro ( module ) );

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/backend/mingw/modulehandler.h	2005-05-15 22:07:07 UTC (rev 15324)
@@ -63,6 +63,7 @@
 	void GenerateInstallTarget () const;
 	static bool ReferenceObjects ( const Module& module );
 protected:
+	virtual void GetModuleSpecificSourceFiles ( std::vector<File*>& sourceFiles );
 	std::string GetWorkingDirectory () const;
 	std::string GetBasename ( const std::string& filename ) const;
 	std::string GetActualSourceFilename ( const std::string& filename ) const;
@@ -73,7 +74,8 @@
 	                  string_list& targets );
 	void GetModuleDependencies ( string_list& dependencies );
 	std::string GetAllDependencies () const;
-	void GetSourceFilenames ( string_list& list, bool includeGeneratedFiles = true ) const;
+	void GetSourceFilenames ( string_list& list,
+                                  bool includeGeneratedFiles ) const;
 	void GetSourceFilenamesWithoutGeneratedFiles ( string_list& list ) const;
 	std::string GetObjectFilename ( const std::string& sourceFilename,
 	                                string_list* pclean_files ) const;
@@ -174,6 +176,7 @@
 	static std::string RemoveVariables ( std::string path);
 	void GenerateBuildMapCode ();
 	void GenerateBuildNonSymbolStrippedCode ();
+	void CleanupFileVector ( std::vector<File*>& sourceFiles );
 public:
 	const Module& module;
 	string_list clean_files;
@@ -389,6 +392,8 @@
 	MingwTestModuleHandler ( const Module& module );
 	virtual HostType DefaultHost() { return HostFalse; }
 	virtual void Process ();
+protected:
+	virtual void GetModuleSpecificSourceFiles ( std::vector<File*>& sourceFiles );
 private:
 	void GenerateTestModuleTarget ();
 };

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/module.cpp	2005-05-15 22:07:07 UTC (rev 15324)
@@ -79,6 +79,16 @@
 }
 
 string
+GetFilename ( const string& filename )
+{
+	size_t index = filename.find_last_of ( CSEP );
+	if ( index == string::npos )
+		return filename;
+	else
+		return filename.substr ( index + 1, filename.length () - index );
+}
+
+string
 NormalizeFilename ( const string& filename )
 {
 	if ( filename == "" )
@@ -731,7 +741,14 @@
 {
 }
 
+bool
+File::IsGeneratedFile () const
+{
+	string extension = GetExtension ( name );
+	return ( extension == ".spec" || extension == ".SPEC" );
+}
 
+
 Library::Library ( const XMLElement& _node,
                    const Module& _module,
                    const string& _name )

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h
--- branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/rbuild.h	2005-05-15 22:07:07 UTC (rev 15324)
@@ -218,6 +218,8 @@
 	bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const;
 	void InvokeModule () const;
 	void ProcessXML ();
+	void GetSourceFilenames ( string_list& list,
+                                  bool includeGeneratedFiles ) const;
 private:
 	std::string GetDefaultModuleExtension () const;
 	std::string GetDefaultModuleEntrypoint () const;
@@ -282,6 +284,7 @@
 	       std::string _switches );
 
 	void ProcessXML();
+	bool IsGeneratedFile () const;
 };
 
 
@@ -468,6 +471,16 @@
                                                  const StubbedComponent& component,
 	                                         int* stubIndex );
 	void WriteStubsFile ( Module& module );
+	std::string GetStartupFilename ( Module& module );
+	std::string GetTestDispatcherName ( std::string filename );
+	bool IsTestFile ( std::string& filename ) const;
+	void GetSourceFilenames ( string_list& list,
+                                  Module& module ) const;
+	char* WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
+                                                           Module& module );
+	char* WriteRegisterTestsFunctionToStartupFile ( char* buffer,
+	                                                Module& module );
+	void WriteStartupFile ( Module& module );
 };
 
 
@@ -689,6 +702,9 @@
 GetDirectory ( const std::string& filename );
 
 extern std::string
+GetFilename ( const std::string& filename );
+
+extern std::string
 NormalizeFilename ( const std::string& filename );
 
 #endif /* __RBUILD_H */

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/tests/functiontest.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/tests/functiontest.cpp	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/tests/functiontest.cpp	2005-05-15 22:07:07 UTC (rev 15324)
@@ -6,4 +6,6 @@
 {
 	string fixedupFilename = NormalizeFilename ( "." SSEP "dir1" SSEP "dir2" SSEP ".." SSEP "filename.txt" );
 	ARE_EQUAL ( "dir1" SSEP "filename.txt", fixedupFilename );
+	ARE_EQUAL ( "file.txt", GetFilename ( "file.txt" ) );
+	ARE_EQUAL ( "file.txt", GetFilename ( "dir" SSEP "file.txt" ) );
 }

Modified: branches/xmlbuildsystem/reactos/tools/rbuild/testsupportcode.cpp
--- branches/xmlbuildsystem/reactos/tools/rbuild/testsupportcode.cpp	2005-05-15 21:41:22 UTC (rev 15323)
+++ branches/xmlbuildsystem/reactos/tools/rbuild/testsupportcode.cpp	2005-05-15 22:07:07 UTC (rev 15324)
@@ -46,6 +46,7 @@
 
 	WriteHooksFile ( module );
 	WriteStubsFile ( module );
+	WriteStartupFile ( module );
 }
 
 string
@@ -188,3 +189,160 @@
 
 	free ( buf );
 }
+
+string
+TestSupportCode::GetStartupFilename ( Module& module )
+{
+	return NormalizeFilename ( Environment::GetIntermediatePath () + SSEP + module.GetBasePath () + SSEP + "_startup.c" );
+}
+
+string
+TestSupportCode::GetTestDispatcherName ( string filename )
+{
+	string filenamePart = ReplaceExtension ( GetFilename ( filename ), "" );
+	if ( filenamePart.length () > 0 )
+		filenamePart[0] = toupper ( filenamePart[0] );
+	for ( size_t i = 1; i < filenamePart.length (); i++ )
+	{
+		filenamePart[i] = tolower ( filenamePart[i] );
+	}
+	return filenamePart + "Test";
+}
+
+bool
+TestSupportCode::IsTestFile ( string& filename ) const
+{
+	if ( stricmp ( GetFilename ( filename ).c_str (), "setup.c" ) == 0 )
+		return false;
+	return true;
+}
+
+void
+TestSupportCode::GetSourceFilenames ( string_list& list,
+                                      Module& module ) const
+{
+	size_t i;
+
+	const vector<File*>& files = module.non_if_data.files;
+	for ( i = 0; i < files.size (); i++ )
+	{
+		if ( !files[i]->IsGeneratedFile () && IsTestFile ( files[i]->name ) )
+			list.push_back ( files[i]->name );
+	}
+	// intentionally make a copy so that we can append more work in
+	// the middle of processing without having to go recursive
+	vector<If*> v = module.non_if_data.ifs;
+	for ( i = 0; i < v.size (); i++ )
+	{
+		size_t j;
+		If& rIf = *v[i];
+		// check for sub-ifs to add to list
+		const vector<If*>& ifs = rIf.data.ifs;
+		for ( j = 0; j < ifs.size (); j++ )
+			v.push_back ( ifs[j] );
+		const vector<File*>& files = rIf.data.files;
+		for ( j = 0; j < files.size (); j++ )
+		{
+			File& file = *files[j];
+			if ( !file.IsGeneratedFile () && IsTestFile ( file.name ) )
+			{
+				list.push_back ( file.name );
+			}
+		}
+	}
+}
+
+char*
+TestSupportCode::WriteTestDispatcherPrototypesToStartupFile ( char* buffer,
+                                                              Module& module )
+{
+	string_list files;
+	GetSourceFilenames ( files,
+	                     module );
+	for ( size_t i = 0; i < files.size (); i++ )
+	{
+		buffer = buffer + sprintf ( buffer,
+	                                    "extern void %s(int Command, char *Buffer);\n",
+		                            GetTestDispatcherName ( files[i] ).c_str () );
+	}
+	buffer = buffer + sprintf ( buffer, "\n" );
+	return buffer;
+}
+
+char*
+TestSupportCode::WriteRegisterTestsFunctionToStartupFile ( char* buffer,
+                                                           Module& module )
+{
+	buffer = buffer + sprintf ( buffer,
+	                            "extern void AddTest(TestRoutine Routine);\n" );
+	buffer = buffer + sprintf ( buffer,
+	                            "\n" );
+
+	buffer = buffer + sprintf ( buffer,
+	                            "void\n" );
+	buffer = buffer + sprintf ( buffer,
+	                            "RegisterTests()\n" );
+	buffer = buffer + sprintf ( buffer,
+	                            "{\n" );
+
+	string_list files;
+	GetSourceFilenames ( files,
+	                     module );
+	for ( size_t i = 0; i < files.size (); i++ )
+	{
+		buffer = buffer + sprintf ( buffer,
+		                            "AddTest((TestRoutine)%s);\n",
+		                            GetTestDispatcherName ( files[i]).c_str () );
+	}
+	buffer = buffer + sprintf ( buffer,
+	                            "}\n" );
+	buffer = buffer + sprintf ( buffer, "\n" );
+	return buffer;
+}
+
+void
+TestSupportCode::WriteStartupFile ( Module& module )
+{
+	char* buf;
+	char* s;
+
+	buf = (char*) malloc ( 50*1024 );
+	if ( buf == NULL )
+		throw OutOfMemoryException ();
+
+	s = buf;
+	s = s + sprintf ( s, "/* This file is automatically generated. */\n" );
+	s = s + sprintf ( s, "\n" );
+	s = s + sprintf ( s, "#include <windows.h>\n" );
+	s = s + sprintf ( s, "#include \"regtests.h\"\n" );
+	s = s + sprintf ( s, "\n" );
+	s = WriteTestDispatcherPrototypesToStartupFile ( s,
+	                                                 module );
+	s = WriteRegisterTestsFunctionToStartupFile ( s,
+	                                              module );
+	s = s + sprintf ( s, "\n" );
+	s = s + sprintf ( s, "void\n" );
+	s = s + sprintf ( s, "ConsoleWrite(char *Buffer)\n" );
+	s = s + sprintf ( s, "{\n" );
+	s = s + sprintf ( s, "  printf(Buffer);\n" );
+	s = s + sprintf ( s, "}\n" );
+	s = s + sprintf ( s, "\n" );
+	s = s + sprintf ( s, "int\n" );
+	s = s + sprintf ( s, "mainCRTStartup(HANDLE hInstance,\n" );
+	s = s + sprintf ( s, "  HANDLE hPrevInstance,\n" );
+	s = s + sprintf ( s, "  LPSTR lpszCmdParam,\n" );
+	s = s + sprintf ( s, "  int nCmdShow)\n" );
+	s = s + sprintf ( s, "{\n" );
+	s = s + sprintf ( s, "  InitializeTests();\n" );
+	s = s + sprintf ( s, "  RegisterTests();\n" );
+	s = s + sprintf ( s, "  SetupOnce();\n" );
+	s = s + sprintf ( s, "  PerformTests(ConsoleWrite, NULL);\n" );
+	s = s + sprintf ( s, "  _ExitProcess(0);\n" );
+	s = s + sprintf ( s, "  return 0;\n" );
+	s = s + sprintf ( s, "}\n" );
+	s = s + sprintf ( s, "\n" );
+
+	FileSupportCode::WriteIfChanged ( buf, GetStartupFilename ( module ) );
+
+	free ( buf );
+}