mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 20:43:18 +00:00
Generate hooks and stubs for tests
svn path=/branches/xmlbuildsystem/; revision=15304
This commit is contained in:
parent
c141408f1d
commit
9017f3f4f6
11 changed files with 426 additions and 150 deletions
|
@ -1,3 +1,19 @@
|
||||||
|
<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">
|
<module name="kernel32_base" type="objectlibrary">
|
||||||
<include base="kernel32_base">.</include>
|
<include base="kernel32_base">.</include>
|
||||||
<include base="kernel32_base">include</include>
|
<include base="kernel32_base">include</include>
|
||||||
|
@ -104,22 +120,6 @@
|
||||||
<file>tls.c</file>
|
<file>tls.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
</module>
|
</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">
|
<directory name="tests">
|
||||||
<xi:include href="tests/kernel32.xml" />
|
<xi:include href="tests/kernel32.xml" />
|
||||||
|
|
|
@ -93,7 +93,7 @@ MockNtCreateFile(PHANDLE FileHandle,
|
||||||
static HOOK NtCreateFileHooks[] =
|
static HOOK NtCreateFileHooks[] =
|
||||||
{
|
{
|
||||||
{"NtCreateFile", MockNtCreateFile},
|
{"NtCreateFile", MockNtCreateFile},
|
||||||
NULL, NULL
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void TestFile()
|
static void TestFile()
|
||||||
|
|
|
@ -41,18 +41,6 @@ v2s ( const string_list& v, int wrap_at )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static */ string
|
|
||||||
Environment::GetVariable ( const string& name )
|
|
||||||
{
|
|
||||||
char* value = getenv ( name.c_str () );
|
|
||||||
if ( value != NULL && strlen ( value ) > 0 )
|
|
||||||
return ssprintf ( "%s",
|
|
||||||
value );
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Directory::Directory ( const string& name_ )
|
Directory::Directory ( const string& name_ )
|
||||||
: name(name_)
|
: name(name_)
|
||||||
{
|
{
|
||||||
|
@ -131,45 +119,13 @@ Directory::ReplaceVariable ( string name,
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ string
|
|
||||||
Directory::GetEnvironmentVariablePathOrDefault ( const string& name,
|
|
||||||
const string& defaultValue )
|
|
||||||
{
|
|
||||||
const string& environmentVariableValue = Environment::GetVariable ( name );
|
|
||||||
if ( environmentVariableValue.length () > 0 )
|
|
||||||
return NormalizeFilename ( environmentVariableValue );
|
|
||||||
else
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ string
|
|
||||||
Directory::GetIntermediatePath ()
|
|
||||||
{
|
|
||||||
return GetEnvironmentVariablePathOrDefault ( "ROS_INTERMEDIATE",
|
|
||||||
"obj-i386" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ string
|
|
||||||
Directory::GetOutputPath ()
|
|
||||||
{
|
|
||||||
return GetEnvironmentVariablePathOrDefault ( "ROS_OUTPUT",
|
|
||||||
"output-i386" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ string
|
|
||||||
Directory::GetInstallPath ()
|
|
||||||
{
|
|
||||||
return GetEnvironmentVariablePathOrDefault ( "ROS_INSTALL",
|
|
||||||
"reactos" );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Directory::ResolveVariablesInPath ( char* buf,
|
Directory::ResolveVariablesInPath ( char* buf,
|
||||||
string path )
|
string path )
|
||||||
{
|
{
|
||||||
string s = ReplaceVariable ( "$(INTERMEDIATE)", GetIntermediatePath (), path );
|
string s = ReplaceVariable ( "$(INTERMEDIATE)", Environment::GetIntermediatePath (), path );
|
||||||
s = ReplaceVariable ( "$(OUTPUT)", GetOutputPath (), s );
|
s = ReplaceVariable ( "$(OUTPUT)", Environment::GetOutputPath (), s );
|
||||||
s = ReplaceVariable ( "$(INSTALL)", GetInstallPath (), s );
|
s = ReplaceVariable ( "$(INSTALL)", Environment::GetInstallPath (), s );
|
||||||
strcpy ( buf, s.c_str () );
|
strcpy ( buf, s.c_str () );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +312,7 @@ MingwBackend::Process ()
|
||||||
GenerateDirectoryTargets ();
|
GenerateDirectoryTargets ();
|
||||||
GenerateDirectories ();
|
GenerateDirectories ();
|
||||||
UnpackWineResources ();
|
UnpackWineResources ();
|
||||||
|
GenerateTestSupportCode ();
|
||||||
CheckAutomaticDependencies ();
|
CheckAutomaticDependencies ();
|
||||||
CloseMakefile ();
|
CloseMakefile ();
|
||||||
}
|
}
|
||||||
|
@ -641,7 +598,7 @@ MingwBackend::GenerateXmlBuildFilesMacro() const
|
||||||
string
|
string
|
||||||
MingwBackend::GetBin2ResExecutable ()
|
MingwBackend::GetBin2ResExecutable ()
|
||||||
{
|
{
|
||||||
return NormalizeFilename ( Directory::GetOutputPath () + SSEP + "tools/bin2res/bin2res" + EXEPOSTFIX );
|
return NormalizeFilename ( Environment::GetOutputPath () + SSEP + "tools/bin2res/bin2res" + EXEPOSTFIX );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -654,6 +611,15 @@ MingwBackend::UnpackWineResources ()
|
||||||
printf ( "done\n" );
|
printf ( "done\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MingwBackend::GenerateTestSupportCode ()
|
||||||
|
{
|
||||||
|
printf ( "Generating test support code..." );
|
||||||
|
TestSupportCode testSupportCode ( ProjectNode );
|
||||||
|
testSupportCode.GenerateTestSupportCode ( verbose );
|
||||||
|
printf ( "done\n" );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MingwBackend::CheckAutomaticDependencies ()
|
MingwBackend::CheckAutomaticDependencies ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,13 +18,6 @@ v2s ( const string_list& v, int wrap_at );
|
||||||
typedef std::map<std::string,Directory*> directory_map;
|
typedef std::map<std::string,Directory*> directory_map;
|
||||||
|
|
||||||
|
|
||||||
class Environment
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static std::string GetVariable ( const std::string& name );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Directory
|
class Directory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,17 +30,12 @@ public:
|
||||||
std::string EscapeSpaces ( std::string path );
|
std::string EscapeSpaces ( std::string path );
|
||||||
void CreateRule ( FILE* f,
|
void CreateRule ( FILE* f,
|
||||||
const std::string& parent );
|
const std::string& parent );
|
||||||
static std::string GetIntermediatePath ();
|
|
||||||
static std::string GetOutputPath ();
|
|
||||||
static std::string GetInstallPath ();
|
|
||||||
private:
|
private:
|
||||||
bool mkdir_p ( const char* path );
|
bool mkdir_p ( const char* path );
|
||||||
std::string ReplaceVariable ( std::string name,
|
std::string ReplaceVariable ( std::string name,
|
||||||
std::string value,
|
std::string value,
|
||||||
std::string path );
|
std::string path );
|
||||||
std::string GetEnvironmentVariable ( const std::string& name );
|
std::string GetEnvironmentVariable ( const std::string& name );
|
||||||
static std::string GetEnvironmentVariablePathOrDefault ( const std::string& name,
|
|
||||||
const std::string& defaultValue );
|
|
||||||
void ResolveVariablesInPath ( char* buf,
|
void ResolveVariablesInPath ( char* buf,
|
||||||
std::string path );
|
std::string path );
|
||||||
bool CreateDirectory ( std::string path );
|
bool CreateDirectory ( std::string path );
|
||||||
|
@ -92,6 +80,7 @@ private:
|
||||||
void GenerateXmlBuildFilesMacro() const;
|
void GenerateXmlBuildFilesMacro() const;
|
||||||
std::string GetBin2ResExecutable ();
|
std::string GetBin2ResExecutable ();
|
||||||
void UnpackWineResources ();
|
void UnpackWineResources ();
|
||||||
|
void GenerateTestSupportCode ();
|
||||||
void CheckAutomaticDependencies ();
|
void CheckAutomaticDependencies ();
|
||||||
bool IncludeDirectoryTarget ( const std::string& directory ) const;
|
bool IncludeDirectoryTarget ( const std::string& directory ) const;
|
||||||
bool TryToDetectThisCompiler ( const std::string& compiler );
|
bool TryToDetectThisCompiler ( const std::string& compiler );
|
||||||
|
|
68
reactos/tools/rbuild/filesupportcode.cpp
Normal file
68
reactos/tools/rbuild/filesupportcode.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include "pch.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "rbuild.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
FileSupportCode::WriteIfChanged ( char* outbuf,
|
||||||
|
string filename )
|
||||||
|
{
|
||||||
|
FILE* out;
|
||||||
|
unsigned int end;
|
||||||
|
char* cmpbuf;
|
||||||
|
unsigned int stat;
|
||||||
|
|
||||||
|
out = fopen ( filename.c_str (), "rb" );
|
||||||
|
if ( out == NULL )
|
||||||
|
{
|
||||||
|
out = fopen ( filename.c_str (), "wb" );
|
||||||
|
if ( out == NULL )
|
||||||
|
throw AccessDeniedException ( filename );
|
||||||
|
fputs ( outbuf, out );
|
||||||
|
fclose ( out );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek ( out, 0, SEEK_END );
|
||||||
|
end = ftell ( out );
|
||||||
|
cmpbuf = (char*) malloc ( end );
|
||||||
|
if ( cmpbuf == NULL )
|
||||||
|
{
|
||||||
|
fclose ( out );
|
||||||
|
throw OutOfMemoryException ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek ( out, 0, SEEK_SET );
|
||||||
|
stat = fread ( cmpbuf, 1, end, out );
|
||||||
|
if ( stat != end )
|
||||||
|
{
|
||||||
|
free ( cmpbuf );
|
||||||
|
fclose ( out );
|
||||||
|
throw AccessDeniedException ( filename );
|
||||||
|
}
|
||||||
|
if ( end == strlen ( outbuf ) && memcmp ( cmpbuf, outbuf, end ) == 0 )
|
||||||
|
{
|
||||||
|
free ( cmpbuf );
|
||||||
|
fclose ( out );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free ( cmpbuf );
|
||||||
|
fclose ( out );
|
||||||
|
out = fopen ( filename.c_str (), "wb" );
|
||||||
|
if ( out == NULL )
|
||||||
|
{
|
||||||
|
throw AccessDeniedException ( filename );
|
||||||
|
}
|
||||||
|
|
||||||
|
stat = fwrite ( outbuf, 1, strlen ( outbuf ), out);
|
||||||
|
if ( strlen ( outbuf ) != stat )
|
||||||
|
{
|
||||||
|
fclose ( out );
|
||||||
|
throw AccessDeniedException ( filename );
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose ( out );
|
||||||
|
}
|
|
@ -7,6 +7,50 @@
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
|
/* static */ string
|
||||||
|
Environment::GetVariable ( const string& name )
|
||||||
|
{
|
||||||
|
char* value = getenv ( name.c_str () );
|
||||||
|
if ( value != NULL && strlen ( value ) > 0 )
|
||||||
|
return ssprintf ( "%s",
|
||||||
|
value );
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ string
|
||||||
|
Environment::GetEnvironmentVariablePathOrDefault ( const string& name,
|
||||||
|
const string& defaultValue )
|
||||||
|
{
|
||||||
|
const string& environmentVariableValue = Environment::GetVariable ( name );
|
||||||
|
if ( environmentVariableValue.length () > 0 )
|
||||||
|
return NormalizeFilename ( environmentVariableValue );
|
||||||
|
else
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ string
|
||||||
|
Environment::GetIntermediatePath ()
|
||||||
|
{
|
||||||
|
return GetEnvironmentVariablePathOrDefault ( "ROS_INTERMEDIATE",
|
||||||
|
"obj-i386" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ string
|
||||||
|
Environment::GetOutputPath ()
|
||||||
|
{
|
||||||
|
return GetEnvironmentVariablePathOrDefault ( "ROS_OUTPUT",
|
||||||
|
"output-i386" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ string
|
||||||
|
Environment::GetInstallPath ()
|
||||||
|
{
|
||||||
|
return GetEnvironmentVariablePathOrDefault ( "ROS_INSTALL",
|
||||||
|
"reactos" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Project::Project ( const string& filename )
|
Project::Project ( const string& filename )
|
||||||
: xmlfile (filename),
|
: xmlfile (filename),
|
||||||
node (NULL),
|
node (NULL),
|
||||||
|
@ -41,68 +85,6 @@ Project::LookupProperty ( const string& name ) const
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Project::WriteIfChanged ( char* outbuf,
|
|
||||||
string filename )
|
|
||||||
{
|
|
||||||
FILE* out;
|
|
||||||
unsigned int end;
|
|
||||||
char* cmpbuf;
|
|
||||||
unsigned int stat;
|
|
||||||
|
|
||||||
out = fopen ( filename.c_str (), "rb" );
|
|
||||||
if ( out == NULL )
|
|
||||||
{
|
|
||||||
out = fopen ( filename.c_str (), "wb" );
|
|
||||||
if ( out == NULL )
|
|
||||||
throw AccessDeniedException ( filename );
|
|
||||||
fputs ( outbuf, out );
|
|
||||||
fclose ( out );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek ( out, 0, SEEK_END );
|
|
||||||
end = ftell ( out );
|
|
||||||
cmpbuf = (char*) malloc ( end );
|
|
||||||
if ( cmpbuf == NULL )
|
|
||||||
{
|
|
||||||
fclose ( out );
|
|
||||||
throw OutOfMemoryException ();
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek ( out, 0, SEEK_SET );
|
|
||||||
stat = fread ( cmpbuf, 1, end, out );
|
|
||||||
if ( stat != end )
|
|
||||||
{
|
|
||||||
free ( cmpbuf );
|
|
||||||
fclose ( out );
|
|
||||||
throw AccessDeniedException ( filename );
|
|
||||||
}
|
|
||||||
if ( end == strlen ( outbuf ) && memcmp ( cmpbuf, outbuf, end ) == 0 )
|
|
||||||
{
|
|
||||||
free ( cmpbuf );
|
|
||||||
fclose ( out );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
free ( cmpbuf );
|
|
||||||
fclose ( out );
|
|
||||||
out = fopen ( filename.c_str (), "wb" );
|
|
||||||
if ( out == NULL )
|
|
||||||
{
|
|
||||||
throw AccessDeniedException ( filename );
|
|
||||||
}
|
|
||||||
|
|
||||||
stat = fwrite ( outbuf, 1, strlen ( outbuf ), out);
|
|
||||||
if ( strlen ( outbuf ) != stat )
|
|
||||||
{
|
|
||||||
fclose ( out );
|
|
||||||
throw AccessDeniedException ( filename );
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose ( out );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Project::SetConfigurationOption ( char* s,
|
Project::SetConfigurationOption ( char* s,
|
||||||
string name,
|
string name,
|
||||||
|
@ -161,7 +143,7 @@ Project::WriteConfigurationFile ()
|
||||||
|
|
||||||
s = s + sprintf ( s, "#endif /* __INCLUDE_CONFIG_H */\n" );
|
s = s + sprintf ( s, "#endif /* __INCLUDE_CONFIG_H */\n" );
|
||||||
|
|
||||||
WriteIfChanged ( buf, "include" SSEP "roscfg.h" );
|
FileSupportCode::WriteIfChanged ( buf, "include" SSEP "roscfg.h" );
|
||||||
|
|
||||||
free ( buf );
|
free ( buf );
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ class If;
|
||||||
class CompilerFlag;
|
class CompilerFlag;
|
||||||
class LinkerFlag;
|
class LinkerFlag;
|
||||||
class Property;
|
class Property;
|
||||||
|
class TestSupportCode;
|
||||||
class WineResource;
|
class WineResource;
|
||||||
class AutomaticDependency;
|
class AutomaticDependency;
|
||||||
class Bootstrap;
|
class Bootstrap;
|
||||||
|
@ -66,6 +67,25 @@ class StubbedSymbol;
|
||||||
|
|
||||||
class SourceFileTest;
|
class SourceFileTest;
|
||||||
|
|
||||||
|
|
||||||
|
class Environment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::string GetVariable ( const std::string& name );
|
||||||
|
static std::string GetIntermediatePath ();
|
||||||
|
static std::string GetOutputPath ();
|
||||||
|
static std::string GetInstallPath ();
|
||||||
|
static std::string GetEnvironmentVariablePathOrDefault ( const std::string& name,
|
||||||
|
const std::string& defaultValue );
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileSupportCode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void WriteIfChanged ( char* outbuf,
|
||||||
|
std::string filename );
|
||||||
|
};
|
||||||
|
|
||||||
class IfableData
|
class IfableData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -110,8 +130,6 @@ private:
|
||||||
std::string* alternativeName );
|
std::string* alternativeName );
|
||||||
void SetConfigurationOption ( char* s,
|
void SetConfigurationOption ( char* s,
|
||||||
std::string name );
|
std::string name );
|
||||||
void WriteIfChanged ( char* outbuf,
|
|
||||||
std::string filename );
|
|
||||||
void ReadXml ();
|
void ReadXml ();
|
||||||
void ProcessXMLSubElement ( const XMLElement& e,
|
void ProcessXMLSubElement ( const XMLElement& e,
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
|
@ -422,6 +440,37 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TestSupportCode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const Project& project;
|
||||||
|
|
||||||
|
TestSupportCode ( const Project& project );
|
||||||
|
~TestSupportCode ();
|
||||||
|
void GenerateTestSupportCode ( bool verbose );
|
||||||
|
private:
|
||||||
|
bool IsTestModule ( const Module& module );
|
||||||
|
void GenerateTestSupportCodeForModule ( Module& module,
|
||||||
|
bool verbose );
|
||||||
|
std::string GetHooksFilename ( Module& module );
|
||||||
|
char* WriteStubbedSymbolToHooksFile ( char* buffer,
|
||||||
|
const StubbedComponent& component,
|
||||||
|
const StubbedSymbol& symbol );
|
||||||
|
char* WriteStubbedComponentToHooksFile ( char* buffer,
|
||||||
|
const StubbedComponent& component );
|
||||||
|
void WriteHooksFile ( Module& module );
|
||||||
|
std::string GetStubsFilename ( Module& module );
|
||||||
|
char* WriteStubbedSymbolToStubsFile ( char* buffer,
|
||||||
|
const StubbedComponent& component,
|
||||||
|
const StubbedSymbol& symbol,
|
||||||
|
int stubIndex );
|
||||||
|
char* WriteStubbedComponentToStubsFile ( char* buffer,
|
||||||
|
const StubbedComponent& component,
|
||||||
|
int* stubIndex );
|
||||||
|
void WriteStubsFile ( Module& module );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class WineResource
|
class WineResource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -610,10 +659,13 @@ public:
|
||||||
const XMLElement& node;
|
const XMLElement& node;
|
||||||
std::string symbol;
|
std::string symbol;
|
||||||
std::string newname;
|
std::string newname;
|
||||||
|
std::string strippedName;
|
||||||
|
|
||||||
StubbedSymbol ( const XMLElement& stubbedSymbolNode );
|
StubbedSymbol ( const XMLElement& stubbedSymbolNode );
|
||||||
~StubbedSymbol ();
|
~StubbedSymbol ();
|
||||||
void ProcessXML();
|
void ProcessXML();
|
||||||
|
private:
|
||||||
|
std::string StripSymbol ( std::string symbol );
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::string
|
extern std::string
|
||||||
|
|
|
@ -116,6 +116,7 @@ RBUILD_COMMON_SOURCES = \
|
||||||
compilerflag.cpp \
|
compilerflag.cpp \
|
||||||
define.cpp \
|
define.cpp \
|
||||||
exception.cpp \
|
exception.cpp \
|
||||||
|
filesupportcode.cpp \
|
||||||
include.cpp \
|
include.cpp \
|
||||||
installfile.cpp \
|
installfile.cpp \
|
||||||
linkerflag.cpp \
|
linkerflag.cpp \
|
||||||
|
@ -123,6 +124,7 @@ RBUILD_COMMON_SOURCES = \
|
||||||
project.cpp \
|
project.cpp \
|
||||||
ssprintf.cpp \
|
ssprintf.cpp \
|
||||||
stubbedcomponent.cpp \
|
stubbedcomponent.cpp \
|
||||||
|
testsupportcode.cpp \
|
||||||
wineresource.cpp \
|
wineresource.cpp \
|
||||||
XML.cpp \
|
XML.cpp \
|
||||||
)
|
)
|
||||||
|
@ -230,6 +232,10 @@ $(RBUILD_INT_)exception.o: $(RBUILD_BASE_)exception.cpp $(RBUILD_HEADERS) | $(RB
|
||||||
$(ECHO_CC)
|
$(ECHO_CC)
|
||||||
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(RBUILD_INT_)filesupportcode.o: $(RBUILD_BASE_)filesupportcode.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
|
||||||
|
$(ECHO_CC)
|
||||||
|
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(RBUILD_INT_)include.o: $(RBUILD_BASE_)include.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
|
$(RBUILD_INT_)include.o: $(RBUILD_BASE_)include.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
|
||||||
$(ECHO_CC)
|
$(ECHO_CC)
|
||||||
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
||||||
|
@ -266,6 +272,10 @@ $(RBUILD_INT_)wineresource.o: $(RBUILD_BASE_)wineresource.cpp $(RBUILD_HEADERS)
|
||||||
$(ECHO_CC)
|
$(ECHO_CC)
|
||||||
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(RBUILD_INT_)testsupportcode.o: $(RBUILD_BASE_)testsupportcode.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
|
||||||
|
$(ECHO_CC)
|
||||||
|
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(RBUILD_INT_)XML.o: $(RBUILD_BASE_)XML.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
|
$(RBUILD_INT_)XML.o: $(RBUILD_BASE_)XML.cpp $(RBUILD_HEADERS) | $(RBUILD_INT)
|
||||||
$(ECHO_CC)
|
$(ECHO_CC)
|
||||||
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@
|
||||||
|
|
|
@ -77,4 +77,23 @@ StubbedSymbol::ProcessXML ()
|
||||||
newname = att->value;
|
newname = att->value;
|
||||||
else
|
else
|
||||||
newname = symbol;
|
newname = symbol;
|
||||||
|
|
||||||
|
strippedName = StripSymbol ( symbol );
|
||||||
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
StubbedSymbol::StripSymbol ( string symbol )
|
||||||
|
{
|
||||||
|
size_t start = 0;
|
||||||
|
while ( start < symbol.length () && symbol[start] == '@')
|
||||||
|
start++;
|
||||||
|
size_t end = symbol.length () - 1;
|
||||||
|
while ( end > 0 && isdigit ( symbol[end] ) )
|
||||||
|
end--;
|
||||||
|
if ( end > 0 and symbol[end] == '@' )
|
||||||
|
end--;
|
||||||
|
if ( end > 0 )
|
||||||
|
return symbol.substr ( start, end - start + 1 );
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
190
reactos/tools/rbuild/testsupportcode.cpp
Normal file
190
reactos/tools/rbuild/testsupportcode.cpp
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
#include "pch.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "rbuild.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
TestSupportCode::TestSupportCode ( const Project& project )
|
||||||
|
: project ( project )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TestSupportCode::~TestSupportCode ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TestSupportCode::IsTestModule ( const Module& module )
|
||||||
|
{
|
||||||
|
return module.type == Test;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TestSupportCode::GenerateTestSupportCode ( bool verbose )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < project.modules.size (); i++ )
|
||||||
|
{
|
||||||
|
if ( IsTestModule ( *project.modules[i] ) )
|
||||||
|
{
|
||||||
|
GenerateTestSupportCodeForModule ( *project.modules[i],
|
||||||
|
verbose );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TestSupportCode::GenerateTestSupportCodeForModule ( Module& module,
|
||||||
|
bool verbose )
|
||||||
|
{
|
||||||
|
if ( verbose )
|
||||||
|
{
|
||||||
|
printf ( "\nGenerating test support code for %s",
|
||||||
|
module.name.c_str () );
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteHooksFile ( module );
|
||||||
|
WriteStubsFile ( module );
|
||||||
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
TestSupportCode::GetHooksFilename ( Module& module )
|
||||||
|
{
|
||||||
|
return NormalizeFilename ( Environment::GetIntermediatePath () + SSEP + module.GetBasePath () + SSEP + "_hooks.c" );
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
TestSupportCode::WriteStubbedSymbolToHooksFile ( char* buffer,
|
||||||
|
const StubbedComponent& component,
|
||||||
|
const StubbedSymbol& symbol )
|
||||||
|
{
|
||||||
|
buffer = buffer + sprintf ( buffer,
|
||||||
|
" {\"%s\", \"%s\", NULL, NULL, NULL},\n",
|
||||||
|
component.name.c_str (),
|
||||||
|
symbol.strippedName.c_str () );
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
TestSupportCode::WriteStubbedComponentToHooksFile ( char* buffer,
|
||||||
|
const StubbedComponent& component )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < component.symbols.size () ; i++ )
|
||||||
|
buffer = WriteStubbedSymbolToHooksFile ( buffer,
|
||||||
|
component,
|
||||||
|
*component.symbols[i] );
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TestSupportCode::WriteHooksFile ( 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, "#include <windows.h>\n" );
|
||||||
|
s = s + sprintf ( s, "#include \"regtests.h\"\n" );
|
||||||
|
s = s + sprintf ( s, "\n" );
|
||||||
|
s = s + sprintf ( s, "API_DESCRIPTION ExternalDependencies[] =\n" );
|
||||||
|
s = s + sprintf ( s, "{\n" );
|
||||||
|
|
||||||
|
int symbolCount = 0;
|
||||||
|
for ( size_t i = 0; i < module.stubbedComponents.size () ; i++ )
|
||||||
|
{
|
||||||
|
s = WriteStubbedComponentToHooksFile ( s,
|
||||||
|
*module.stubbedComponents[i] );
|
||||||
|
symbolCount += module.stubbedComponents[i]->symbols.size ();
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s + sprintf ( s, "};\n" );
|
||||||
|
s = s + sprintf ( s, "\n" );
|
||||||
|
s = s + sprintf ( s, "#define ExternalDependencyCount %d\n", symbolCount );
|
||||||
|
s = s + sprintf ( s, "ULONG MaxExternalDependency = ExternalDependencyCount - 1;\n" );
|
||||||
|
s = s + sprintf ( s, "\n" );
|
||||||
|
|
||||||
|
FileSupportCode::WriteIfChanged ( buf, GetHooksFilename ( module ) );
|
||||||
|
|
||||||
|
free ( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
TestSupportCode::GetStubsFilename ( Module& module )
|
||||||
|
{
|
||||||
|
return NormalizeFilename ( Environment::GetIntermediatePath () + SSEP + module.GetBasePath () + SSEP + "_stubs.S" );
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
TestSupportCode::WriteStubbedSymbolToStubsFile ( char* buffer,
|
||||||
|
const StubbedComponent& component,
|
||||||
|
const StubbedSymbol& symbol,
|
||||||
|
int stubIndex )
|
||||||
|
{
|
||||||
|
buffer = buffer + sprintf ( buffer,
|
||||||
|
".globl _%s\n",
|
||||||
|
symbol.symbol.c_str () );
|
||||||
|
buffer = buffer + sprintf ( buffer,
|
||||||
|
"_%s:\n",
|
||||||
|
symbol.symbol.c_str () );
|
||||||
|
buffer = buffer + sprintf ( buffer,
|
||||||
|
" pushl $%d\n",
|
||||||
|
stubIndex );
|
||||||
|
buffer = buffer + sprintf ( buffer,
|
||||||
|
" jmp passthrough\n" );
|
||||||
|
buffer = buffer + sprintf ( buffer, "\n" );
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
TestSupportCode::WriteStubbedComponentToStubsFile ( char* buffer,
|
||||||
|
const StubbedComponent& component,
|
||||||
|
int* stubIndex )
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < component.symbols.size () ; i++ )
|
||||||
|
buffer = WriteStubbedSymbolToStubsFile ( buffer,
|
||||||
|
component,
|
||||||
|
*component.symbols[i],
|
||||||
|
(*stubIndex)++ );
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TestSupportCode::WriteStubsFile ( 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, "passthrough:\n" );
|
||||||
|
s = s + sprintf ( s, " call _FrameworkGetHook@4\n" );
|
||||||
|
s = s + sprintf ( s, " test %%eax, %%eax\n" );
|
||||||
|
s = s + sprintf ( s, " je .return\n" );
|
||||||
|
s = s + sprintf ( s, " jmp *%%eax\n" );
|
||||||
|
s = s + sprintf ( s, ".return:\n" );
|
||||||
|
s = s + sprintf ( s, " /* This will most likely corrupt the stack */\n" );
|
||||||
|
s = s + sprintf ( s, " ret\n" );
|
||||||
|
s = s + sprintf ( s, "\n" );
|
||||||
|
|
||||||
|
int stubIndex = 0;
|
||||||
|
for ( size_t i = 0; i < module.stubbedComponents.size () ; i++ )
|
||||||
|
{
|
||||||
|
s = WriteStubbedComponentToStubsFile ( s,
|
||||||
|
*module.stubbedComponents[i],
|
||||||
|
&stubIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSupportCode::WriteIfChanged ( buf, GetStubsFilename ( module ) );
|
||||||
|
|
||||||
|
free ( buf );
|
||||||
|
}
|
|
@ -82,7 +82,7 @@ WineResource::UnpackResourcesInModule ( Module& module,
|
||||||
|
|
||||||
if ( verbose )
|
if ( verbose )
|
||||||
{
|
{
|
||||||
printf ( "Unpacking resources for %s",
|
printf ( "\nUnpacking resources for %s",
|
||||||
module.name.c_str () );
|
module.name.c_str () );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue