⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modulehandler.cpp

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright (C) 2005 Casper S. Hornstrup
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include "../../pch.h"
#include <assert.h>

#include "../../rbuild.h"
#include "mingw.h"
#include "modulehandler.h"

using std::string;
using std::vector;

#define CLEAN_FILE(f) clean_files.push_back ( f );

static string ros_temp = "$(TEMPORARY)";
MingwBackend*
MingwModuleHandler::backend = NULL;
FILE*
MingwModuleHandler::fMakefile = NULL;

string
PrefixFilename (
	const string& filename,
	const string& prefix )
{
	if ( !prefix.length() )
		return filename;
	string out;
	const char* pfilename = filename.c_str();
	const char* p1 = strrchr ( pfilename, '/' );
	const char* p2 = strrchr ( pfilename, '\\' );
	if ( p1 || p2 )
	{
		if ( p2 > p1 )
			p1 = p2;
		out += string(pfilename,p1-pfilename) + cSep;
		pfilename = p1 + 1;
	}
	out += prefix + pfilename;
	return out;
}

string
GetTargetMacro ( const Module& module, bool with_dollar )
{
	string s ( module.name );
	strupr ( &s[0] );
	s += "_TARGET";
	if ( with_dollar )
		return ssprintf ( "$(%s)", s.c_str() );
	return s;
}

MingwModuleHandler::MingwModuleHandler (
	const Module& module_ )

	: module(module_)
{
	use_pch = false;
}

MingwModuleHandler::~MingwModuleHandler()
{
}

/*static*/ void
MingwModuleHandler::SetBackend ( MingwBackend* backend_ )
{
	backend = backend_;
}

/*static*/ void
MingwModuleHandler::SetMakefile ( FILE* f )
{
	fMakefile = f;
}

void
MingwModuleHandler::EnablePreCompiledHeaderSupport ()
{
	use_pch = true;
}

/* static*/ string
MingwModuleHandler::RemoveVariables ( string path)
{
	size_t i = path.find ( '$' );
	if ( i != string::npos )
	{
		size_t j = path.find ( ')', i );
		if ( j != string::npos )
		{
			if ( j + 2 < path.length () && path[j + 1] == cSep )
				return path.substr ( j + 2);
			else
				return path.substr ( j + 1);
		}
	}
	return path;
}

/*static*/ string
MingwModuleHandler::PassThruCacheDirectory (
	const string &file,
	Directory* directoryTree )
{
	string directory ( GetDirectory ( RemoveVariables ( file ) ) );
	if ( directoryTree == NULL )
		return file;
	string generatedFilesDirectory = backend->AddDirectoryTarget ( directory,
	                                                               directoryTree );
	if ( directory.find ( generatedFilesDirectory ) != string::npos )
		/* This path already includes the generated files directory variable */
		return file;
	else
	{
		if ( file == "" )
			return generatedFilesDirectory;
		return generatedFilesDirectory + sSep + file;
	}
}

/*static*/ string
MingwModuleHandler::PassThruCacheDirectory (const FileLocation* fileLocation )
{
	return PassThruCacheDirectory ( fileLocation->filename,
	                                fileLocation->directory );
}

/*static*/ Directory*
MingwModuleHandler::GetTargetDirectoryTree (
	const Module& module )
{
	if ( module.type == StaticLibrary )
		return backend->intermediateDirectory;
	return backend->outputDirectory;
}

/*static*/ string
MingwModuleHandler::GetTargetFilename (
	const Module& module,
	string_list* pclean_files )
{
	string target = PassThruCacheDirectory (
		NormalizeFilename ( module.GetPath () ),
		GetTargetDirectoryTree ( module ) );
	if ( pclean_files )
	{
		string_list& clean_files = *pclean_files;
		CLEAN_FILE ( target );
	}
	return target;
}

/*static*/ string
MingwModuleHandler::GetImportLibraryFilename (
	const Module& module,
	string_list* pclean_files )
{
	string target = PassThruCacheDirectory (
		NormalizeFilename ( module.GetDependencyPath () ),
		backend->intermediateDirectory );
	if ( pclean_files )
	{
		string_list& clean_files = *pclean_files;
		CLEAN_FILE ( target );
	}
	return target;
}

/*static*/ MingwModuleHandler*
MingwModuleHandler::InstanciateHandler (
	const Module& module,
	MingwBackend* backend )
{
	MingwModuleHandler* handler;
	switch ( module.type )
	{
		case BuildTool:
			handler = new MingwBuildToolModuleHandler ( module );
			break;
		case StaticLibrary:
			handler = new MingwStaticLibraryModuleHandler ( module );
			break;
		case ObjectLibrary:
			handler = new MingwObjectLibraryModuleHandler ( module );
			break;
		case Kernel:
			handler = new MingwKernelModuleHandler ( module );
			break;
		case NativeCUI:
			handler = new MingwNativeCUIModuleHandler ( module );
			break;
		case Win32CUI:
			handler = new MingwWin32CUIModuleHandler ( module );
			break;
		case Win32SCR:
		case Win32GUI:
			handler = new MingwWin32GUIModuleHandler ( module );
			break;
		case KernelModeDLL:
			handler = new MingwKernelModeDLLModuleHandler ( module );
			break;
		case NativeDLL:
			handler = new MingwNativeDLLModuleHandler ( module );
			break;
		case Win32DLL:
			handler = new MingwWin32DLLModuleHandler ( module );
			break;
		case Win32OCX: 
			handler = new MingwWin32OCXModuleHandler ( module );
			break;
		case KernelModeDriver:
			handler = new MingwKernelModeDriverModuleHandler ( module );
			break;
		case BootLoader:
			handler = new MingwBootLoaderModuleHandler ( module );
			break;
		case BootSector:
			handler = new MingwBootSectorModuleHandler ( module );
			break;
		case BootProgram:
			handler = new MingwBootProgramModuleHandler ( module );
			break;
		case Iso:
			handler = new MingwIsoModuleHandler ( module );
			break;
		case LiveIso:
			handler = new MingwLiveIsoModuleHandler ( module );
			break;
		case IsoRegTest:
			handler = new MingwIsoModuleHandler ( module );
			break;
		case LiveIsoRegTest:
			handler = new MingwLiveIsoModuleHandler ( module );
			break;
		case Test:
			handler = new MingwTestModuleHandler ( module );
			break;
		case RpcServer:
			handler = new MingwRpcServerModuleHandler ( module );
			break;
		case RpcClient:
			handler = new MingwRpcClientModuleHandler ( module );
			break;
		case Alias:
			handler = new MingwAliasModuleHandler ( module );
			break;
		case IdlHeader:
			handler = new MingwIdlHeaderModuleHandler ( module );
			break;
		case EmbeddedTypeLib:
			handler = new MingwEmbeddedTypeLibModuleHandler ( module );
			break;
		default:
			throw UnknownModuleTypeException (
				module.node.location,
				module.type );
			break;
	}
	return handler;
}

string
MingwModuleHandler::GetWorkingDirectory () const
{
	return ".";
}

string
MingwModuleHandler::GetBasename ( const string& filename ) const
{
	size_t index = filename.find_last_of ( '.' );
	if ( index != string::npos )
		return filename.substr ( 0, index );
	return "";
}

FileLocation*
MingwModuleHandler::GetActualSourceFilename (
	const FileLocation* fileLocation ) const
{
	string filename = fileLocation->filename;
	string extension = GetExtension ( filename );
	if ( extension == ".spec" || extension == ".SPEC" )
	{
		string basename = GetBasename ( filename );
		PassThruCacheDirectory ( NormalizeFilename ( basename + ".stubs.c" ),
		                         backend->intermediateDirectory );
		return new FileLocation ( backend->intermediateDirectory, NormalizeFilename ( basename + ".stubs.c" ) );
	}
	else if ( extension == ".idl" || extension == ".IDL" )
	{
		string basename = GetBasename ( filename );
		string newname;
		if ( module.type == RpcServer )
		{
			newname = basename + "_s.c";
			PassThruCacheDirectory ( NormalizeFilename ( newname ),
				                     backend->intermediateDirectory );
			return new FileLocation ( backend->intermediateDirectory, NormalizeFilename ( newname ) );
		}
		else if ( module.type == RpcClient )
		{
			newname = basename + "_c.c";
			PassThruCacheDirectory ( NormalizeFilename ( newname ),
				                     backend->intermediateDirectory );
			return new FileLocation ( backend->intermediateDirectory, NormalizeFilename ( newname ) );
		}
		else if ( module.type == IdlHeader )
		{
			newname = basename + ".h";
			PassThruCacheDirectory ( NormalizeFilename ( newname ),
				                     backend->intermediateDirectory );
			return new FileLocation ( fileLocation->directory, filename );
		}
		else
		{
			return new FileLocation ( fileLocation->directory, filename );
		}
	}
	else
		return new FileLocation ( fileLocation->directory, filename );
}

string
MingwModuleHandler::GetExtraDependencies (
	const string& filename ) const
{
	string extension = GetExtension ( filename );
	if ( extension == ".idl" || extension == ".IDL" )
	{
		string basename = GetBasename ( filename );
		if ( (module.type == RpcServer) || (module.type == RpcClient) )
			return GetRpcServerHeaderFilename ( basename ) + " " + GetRpcClientHeaderFilename ( basename );
		else if ( module.type == IdlHeader )
			return GetIdlHeaderFilename ( basename );
		else
			return "";
	}
	else
		return "";
}

string
MingwModuleHandler::GetCompilationUnitDependencies (
	const CompilationUnit& compilationUnit ) const
{
	if ( compilationUnit.files.size () <= 1 )
		return "";
	vector<string> sourceFiles;
	for ( size_t i = 0; i < compilationUnit.files.size (); i++ )
	{
		File& file = *compilationUnit.files[i];
		sourceFiles.push_back ( NormalizeFilename ( file.name ) );
	}
	return v2s ( sourceFiles, 10 );
}

string
MingwModuleHandler::GetModuleArchiveFilename () const
{
	if ( module.type == StaticLibrary )
		return GetTargetFilename ( module, NULL );
	return PassThruCacheDirectory ( ReplaceExtension (
		NormalizeFilename ( module.GetPath () ),
		".temp.a" ),
		backend->intermediateDirectory );
}

bool
MingwModuleHandler::IsGeneratedFile ( const File& file ) const
{
	string extension = GetExtension ( file.name );
	return ( extension == ".spec" || extension == ".SPEC" );
}

/*static*/ bool
MingwModuleHandler::ReferenceObjects (
	const Module& module )
{
	if ( module.type == ObjectLibrary )
		return true;
	if ( module.type == RpcServer )
		return true;
	if ( module.type == RpcClient )
		return true;
	if ( module.type == IdlHeader )
		return true;
	return false;
}

string
MingwModuleHandler::GetImportLibraryDependency (
	const Module& importedModule )
{
	string dep;
	if ( ReferenceObjects ( importedModule ) )
		dep = GetTargetMacro ( importedModule );
	else
		dep = GetImportLibraryFilename ( importedModule, NULL );
	return dep;
}

void
MingwModuleHandler::GetTargets ( const Module& dependencyModule,
	                             string_list& targets )
{
	if ( dependencyModule.invocations.size () > 0 )
	{
		for ( size_t i = 0; i < dependencyModule.invocations.size (); i++ )
		{
			Invoke& invoke = *dependencyModule.invocations[i];
			invoke.GetTargets ( targets );
		}
	}
	else
		targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
}

void
MingwModuleHandler::GetModuleDependencies (
	string_list& dependencies )
{
	size_t iend = module.dependencies.size ();

	if ( iend == 0 )
		return;

	for ( size_t i = 0; i < iend; i++ )
	{
		const Dependency& dependency = *module.dependencies[i];
		const Module& dependencyModule = *dependency.dependencyModule;
		GetTargets ( dependencyModule,
		             dependencies );
	}
	GetDefinitionDependencies ( dependencies );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -