Continue rbuild cleanup (AutomaticDependency and SourceFile classes)

svn path=/trunk/; revision=29150
This commit is contained in:
Hervé Poussineau 2007-09-23 08:04:24 +00:00
parent c0c201c35d
commit 8ad6033250
2 changed files with 121 additions and 180 deletions

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2005 Casper S. Hornstrup * Copyright (C) 2005 Casper S. Hornstrup
* Copyright (C) 2007 Hervé Poussineau
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -27,48 +28,17 @@ using std::string;
using std::vector; using std::vector;
using std::map; using std::map;
static std::string
GetExtension ( const std::string& filename )
{
size_t index = filename.find_last_of ( '/' );
if (index == string::npos) index = 0;
string tmp = filename.substr( index, filename.size() - index );
size_t ext_index = tmp.find_last_of( '.' );
if (ext_index != string::npos)
return filename.substr ( index + ext_index, filename.size() );
return "";
}
SourceFile::SourceFile ( AutomaticDependency* automaticDependency, SourceFile::SourceFile ( AutomaticDependency* automaticDependency,
const Module& module, const Module& module,
const string& filename, const File& file,
SourceFile* parent, SourceFile* parent )
bool isNonAutomaticDependency ) : file ( file ),
: automaticDependency ( automaticDependency ), automaticDependency ( automaticDependency),
module ( module ), module ( module ),
filename ( filename ),
isNonAutomaticDependency ( isNonAutomaticDependency ),
youngestLastWriteTime ( 0 ) youngestLastWriteTime ( 0 )
{ {
if ( parent != NULL ) if (parent != NULL )
parents.push_back ( parent ); parents.push_back ( parent );
GetDirectoryAndFilenameParts ();
}
void
SourceFile::GetDirectoryAndFilenameParts ()
{
size_t index = filename.find_last_of ( cSep );
if ( index != string::npos )
{
directoryPart = filename.substr ( 0, index );
filenamePart = filename.substr ( index + 1, filename.length () - index );
}
else
{
directoryPart = "";
filenamePart = filename;
}
} }
void void
@ -82,6 +52,7 @@ void
SourceFile::Open () SourceFile::Open ()
{ {
struct stat statbuf; struct stat statbuf;
string filename = file.GetFullPath ();
Close (); Close ();
FILE* f = fopen ( filename.c_str (), "rb" ); FILE* f = fopen ( filename.c_str (), "rb" );
@ -119,7 +90,14 @@ SourceFile::ReadInclude ( string& filename,
{ {
while ( p < end ) while ( p < end )
{ {
if ( ( *p == '#') && ( end - p > 13 ) ) if ( p != buf.c_str () )
{
/* Go to end of line */
while ( *p != '\n' && p < end )
p++;
SkipWhitespace ();
}
if ( ( end - p > 13 ) && ( *p == '#') )
{ {
bool include = false; bool include = false;
p++; p++;
@ -132,14 +110,14 @@ SourceFile::ReadInclude ( string& filename,
includeNext = false; includeNext = false;
include = true; include = true;
} }
if ( strncmp ( p, "include_next ", 13 ) == 0 ) if ( strncmp ( p, "include_next ", 13 ) == 0 )
{ {
p += 13; p += 13;
includeNext = true; includeNext = true;
include = true; include = true;
} }
if ( include ) if ( include )
{ {
SkipWhitespace (); SkipWhitespace ();
if ( p < end ) if ( p < end )
@ -200,58 +178,56 @@ SourceFile::IsParentOf ( const SourceFile* parent,
} }
bool bool
SourceFile::IsIncludedFrom ( const string& normalizedFilename ) SourceFile::IsIncludedFrom ( const File& file )
{ {
if ( normalizedFilename == filename ) SourceFile* sourceFile = automaticDependency->RetrieveFromCache ( file );
return true;
SourceFile* sourceFile = automaticDependency->RetrieveFromCache ( normalizedFilename );
if ( sourceFile == NULL ) if ( sourceFile == NULL )
return false; return false;
if ( sourceFile == this )
return true;
return IsParentOf ( sourceFile, return IsParentOf ( sourceFile,
this ); this );
} }
SourceFile*
SourceFile::GetParentSourceFile ()
{
if ( isNonAutomaticDependency )
return NULL;
return this;
}
bool bool
SourceFile::CanProcessFile ( const string& extension ) SourceFile::CanProcessFile ( const File& file )
{ {
if ( extension == ".h" || extension == ".H" ) string extension = GetExtension ( file.file );
std::transform ( extension.begin (), extension.end (), extension.begin (), tolower );
if ( extension == ".h" )
return true; return true;
if ( extension == ".c" || extension == ".C" ) if ( extension == ".c" )
return true; return true;
if ( extension == ".cpp" || extension == ".CPP" ) if ( extension == ".cpp" )
return true; return true;
if ( extension == ".rc" || extension == ".RC" ) if ( extension == ".rc" )
return true; return true;
if ( extension == ".s" || extension == ".S" ) if ( extension == ".s" )
return true; return true;
if ( extension == ".nls" )
return true;
if ( extension == ".idl" )
return true;
if ( automaticDependency->project.configuration.Verbose )
printf ( "Skipping file %s, as its extension is not recognized\n", file.file.name.c_str () );
return false; return false;
} }
SourceFile* SourceFile*
SourceFile::ParseFile ( const string& normalizedFilename ) SourceFile::ParseFile ( const File& file )
{ {
string extension = GetExtension ( normalizedFilename ); if ( !CanProcessFile ( file ) )
if ( CanProcessFile ( extension ) ) return NULL;
{
if ( IsIncludedFrom ( normalizedFilename ) )
return NULL;
SourceFile* sourceFile = automaticDependency->RetrieveFromCacheOrParse ( module, if ( IsIncludedFrom ( file ) )
normalizedFilename, return NULL;
GetParentSourceFile () );
return sourceFile; SourceFile* sourceFile = automaticDependency->RetrieveFromCacheOrParse ( module,
} file,
return NULL; this );
return sourceFile;
} }
void void
@ -260,7 +236,7 @@ SourceFile::Parse ()
Open (); Open ();
while ( p < end ) while ( p < end )
{ {
string includedFilename ( "" ); string includedFilename;
bool searchCurrentDirectory; bool searchCurrentDirectory;
bool includeNext; bool includeNext;
@ -268,41 +244,32 @@ SourceFile::Parse ()
searchCurrentDirectory, searchCurrentDirectory,
includeNext ) ) includeNext ) )
{ {
string resolvedFilename ( "" ); File resolvedFile ( SourceDirectory, "", "", false, "", false ) ;
bool locatedFile = automaticDependency->LocateIncludedFile ( this, bool locatedFile = automaticDependency->LocateIncludedFile ( this,
module, module,
includedFilename, includedFilename,
searchCurrentDirectory, searchCurrentDirectory,
includeNext, includeNext,
resolvedFilename ); resolvedFile );
if ( locatedFile ) if ( locatedFile )
{ {
SourceFile* sourceFile = ParseFile ( resolvedFilename ); SourceFile* sourceFile = ParseFile ( *new File ( resolvedFile ) );
if ( sourceFile != NULL ) if ( sourceFile != NULL )
files.push_back ( sourceFile ); files.push_back ( sourceFile );
} } else if ( automaticDependency->project.configuration.Verbose )
printf ( "Unable to find %c%s%c, included in %s%c%s\n",
searchCurrentDirectory ? '\"' : '<',
includedFilename.c_str (),
searchCurrentDirectory ? '\"' : '>',
this->file.file.relative_path.c_str (),
cSep,
this->file.file.name.c_str () );
} }
p++; p++;
} }
Close (); Close ();
} }
string
SourceFile::Location () const
{
int line = 1;
const char* end_of_line = strchr ( buf.c_str (), '\n' );
while ( end_of_line && end_of_line < p )
{
++line;
end_of_line = strchr ( end_of_line + 1, '\n' );
}
return ssprintf ( "%s(%i)",
filename.c_str (),
line );
}
AutomaticDependency::AutomaticDependency ( const Project& project ) AutomaticDependency::AutomaticDependency ( const Project& project )
: project ( project ) : project ( project )
{ {
@ -352,37 +319,14 @@ void
AutomaticDependency::ParseFile ( const Module& module, AutomaticDependency::ParseFile ( const Module& module,
const File& file ) const File& file )
{ {
string normalizedFilename = NormalizeFilename ( file.GetFullPath () );
RetrieveFromCacheOrParse ( module, RetrieveFromCacheOrParse ( module,
normalizedFilename, file,
NULL ); NULL );
} }
string
AutomaticDependency::ReplaceVariable ( const string& name,
const string& value,
string path )
{
size_t i = path.find ( name );
if ( i != string::npos )
return path.replace ( i, name.length (), value );
else
return path;
}
string
AutomaticDependency::ResolveVariablesInPath ( const string& path )
{
string s = ReplaceVariable ( "$(INTERMEDIATE)", Environment::GetIntermediatePath (), path );
s = ReplaceVariable ( "$(OUTPUT)", Environment::GetOutputPath (), s );
s = ReplaceVariable ( "$(INSTALL)", Environment::GetInstallPath (), s );
return s;
}
bool bool
AutomaticDependency::LocateIncludedFile ( const FileLocation& directory, AutomaticDependency::LocateIncludedFile ( const FileLocation& directory,
const string& includedFilename, const string& includedFilename )
string& resolvedFilename )
{ {
string path; string path;
switch ( directory.directory ) switch ( directory.directory )
@ -414,22 +358,16 @@ AutomaticDependency::LocateIncludedFile ( const FileLocation& directory,
if ( f != NULL ) if ( f != NULL )
{ {
fclose ( f ); fclose ( f );
resolvedFilename = normalizedFilename;
return true; return true;
} }
resolvedFilename = "";
return false; return false;
} }
void void
AutomaticDependency::GetIncludeDirectories ( vector<Include*>& includes, AutomaticDependency::GetIncludeDirectories ( vector<Include*>& includes,
const Module& module, const Module& module )
Include& currentDirectory,
bool searchCurrentDirectory )
{ {
size_t i; size_t i;
if ( searchCurrentDirectory )
includes.push_back( &currentDirectory );
for ( i = 0; i < module.non_if_data.includes.size (); i++ ) for ( i = 0; i < module.non_if_data.includes.size (); i++ )
includes.push_back( module.non_if_data.includes[i] ); includes.push_back( module.non_if_data.includes[i] );
for ( i = 0; i < module.project.non_if_data.includes.size (); i++ ) for ( i = 0; i < module.project.non_if_data.includes.size (); i++ )
@ -442,44 +380,61 @@ AutomaticDependency::LocateIncludedFile ( SourceFile* sourceFile,
const string& includedFilename, const string& includedFilename,
bool searchCurrentDirectory, bool searchCurrentDirectory,
bool includeNext, bool includeNext,
string& resolvedFilename ) File& resolvedFile )
{ {
vector<Include*> includes; vector<Include*> includes;
Include currentDirectory ( module.project, SourceDirectory, sourceFile->directoryPart ); string includedFileDir;
GetIncludeDirectories ( includes, module, currentDirectory, searchCurrentDirectory ); Include currentDirectory ( module.project, SourceDirectory, sourceFile->file.file.relative_path );
if ( searchCurrentDirectory )
includes.push_back ( &currentDirectory );
GetIncludeDirectories ( includes, module );
for ( size_t j = 0; j < includes.size (); j++ ) for ( size_t j = 0; j < includes.size (); j++ )
{ {
Include& include = *includes[j]; Include& include = *includes[j];
if ( LocateIncludedFile ( *include.directory, if ( LocateIncludedFile ( *include.directory,
includedFilename, includedFilename ) )
resolvedFilename ) )
{ {
if ( includeNext && stricmp ( resolvedFilename.c_str (), if ( includeNext &&
sourceFile->filename.c_str () ) == 0 ) include.directory->directory == sourceFile->file.file.directory &&
include.directory->relative_path == sourceFile->file.file.relative_path )
{
includeNext = false;
continue; continue;
}
resolvedFile.file.directory = include.directory->directory;
size_t index = includedFilename.find_last_of ( "/\\" );
if ( index == string::npos )
{
resolvedFile.file.name = includedFilename;
resolvedFile.file.relative_path = include.directory->relative_path;
}
else
{
resolvedFile.file.relative_path = NormalizeFilename (
include.directory->relative_path + sSep +
includedFilename.substr ( 0, index ) );
resolvedFile.file.name = includedFilename.substr ( index + 1 );
}
return true; return true;
} }
} }
/*printf ( "Unable to find %s, included in %s.\n",
includedFilename.c_str (),
sourceFile->filename.c_str () );*/
resolvedFilename = "";
return false; return false;
} }
SourceFile* SourceFile*
AutomaticDependency::RetrieveFromCacheOrParse ( const Module& module, AutomaticDependency::RetrieveFromCacheOrParse ( const Module& module,
const string& filename, const File& file,
SourceFile* parentSourceFile ) SourceFile* parentSourceFile )
{ {
string filename = file.GetFullPath();
SourceFile* sourceFile = sourcefile_map[filename]; SourceFile* sourceFile = sourcefile_map[filename];
if ( sourceFile == NULL ) if ( sourceFile == NULL )
{ {
sourceFile = new SourceFile ( this, sourceFile = new SourceFile ( this,
module, module,
ResolveVariablesInPath ( filename ), file,
parentSourceFile, parentSourceFile );
false );
sourcefile_map[filename] = sourceFile; sourcefile_map[filename] = sourceFile;
sourceFile->Parse (); sourceFile->Parse ();
} }
@ -489,8 +444,9 @@ AutomaticDependency::RetrieveFromCacheOrParse ( const Module& module,
} }
SourceFile* SourceFile*
AutomaticDependency::RetrieveFromCache ( const string& filename ) AutomaticDependency::RetrieveFromCache ( const File& file )
{ {
string filename = file.GetFullPath();
return sourcefile_map[filename]; return sourcefile_map[filename];
} }
@ -543,9 +499,7 @@ AutomaticDependency::CheckAutomaticDependencies ( const Module& module,
for ( size_t fi = 0; fi < files.size (); fi++ ) for ( size_t fi = 0; fi < files.size (); fi++ )
{ {
File& file = *files[fi]; File& file = *files[fi];
string normalizedFilename = NormalizeFilename ( file.GetFullPath () ); SourceFile* sourceFile = RetrieveFromCache ( file );
SourceFile* sourceFile = RetrieveFromCache ( normalizedFilename );
if ( sourceFile != NULL ) if ( sourceFile != NULL )
{ {
CheckAutomaticDependenciesForFile ( sourceFile ); CheckAutomaticDependenciesForFile ( sourceFile );
@ -554,13 +508,15 @@ AutomaticDependency::CheckAutomaticDependencies ( const Module& module,
{ {
if ( verbose ) if ( verbose )
{ {
printf ( "Marking %s for rebuild due to younger file %s\n", printf ( "Marking %s%c%s for rebuild due to younger file %s%c%s\n",
sourceFile->filename.c_str (), sourceFile->file.file.relative_path.c_str (),
sourceFile->youngestFile->filename.c_str () ); cSep, sourceFile->file.file.name.c_str (),
sourceFile->youngestFile->file.file.relative_path.c_str (),
cSep, sourceFile->youngestFile->file.file.name.c_str () );
} }
timebuf.actime = sourceFile->youngestLastWriteTime; timebuf.actime = sourceFile->youngestLastWriteTime;
timebuf.modtime = sourceFile->youngestLastWriteTime; timebuf.modtime = sourceFile->youngestLastWriteTime;
utime ( sourceFile->filename.c_str (), utime ( sourceFile->file.GetFullPath ().c_str (),
&timebuf ); &timebuf );
} }
} }

View file

@ -725,35 +725,27 @@ class SourceFile
public: public:
SourceFile ( AutomaticDependency* automaticDependency, SourceFile ( AutomaticDependency* automaticDependency,
const Module& module, const Module& module,
const std::string& filename, const File& file,
SourceFile* parent, SourceFile* parent );
bool isNonAutomaticDependency );
SourceFile* ParseFile ( const std::string& normalizedFilename );
void Parse (); void Parse ();
std::string Location () const; std::vector<SourceFile*> files; /* List of files included in this file */
std::vector<SourceFile*> files; const File& file;
AutomaticDependency* automaticDependency; AutomaticDependency* automaticDependency;
const Module& module; const Module& module;
std::string filename;
std::string filenamePart;
std::string directoryPart;
std::vector<SourceFile*> parents; /* List of files, this file is included from */ std::vector<SourceFile*> parents; /* List of files, this file is included from */
bool isNonAutomaticDependency;
std::string cachedDependencies;
time_t lastWriteTime; time_t lastWriteTime;
time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */ time_t youngestLastWriteTime; /* Youngest last write time of this file and all children */
SourceFile* youngestFile; SourceFile* youngestFile;
private: private:
void GetDirectoryAndFilenameParts ();
void Close (); void Close ();
void Open (); void Open ();
void SkipWhitespace (); void SkipWhitespace ();
bool ReadInclude ( std::string& filename, bool ReadInclude ( std::string& filename,
bool& searchCurrentDirectory, bool& searchCurrentDirectory,
bool& includeNext ); bool& includeNext );
bool IsIncludedFrom ( const std::string& normalizedFilename ); bool IsIncludedFrom ( const File& file );
SourceFile* GetParentSourceFile (); SourceFile* ParseFile(const File& file);
bool CanProcessFile ( const std::string& extension ); bool CanProcessFile ( const File& file );
bool IsParentOf ( const SourceFile* parent, bool IsParentOf ( const SourceFile* parent,
const SourceFile* child ); const SourceFile* child );
std::string buf; std::string buf;
@ -771,18 +763,17 @@ public:
AutomaticDependency ( const Project& project ); AutomaticDependency ( const Project& project );
~AutomaticDependency (); ~AutomaticDependency ();
bool LocateIncludedFile ( const FileLocation& directory, bool LocateIncludedFile ( const FileLocation& directory,
const std::string& includedFilename, const std::string& includedFilename );
std::string& resolvedFilename );
bool LocateIncludedFile ( SourceFile* sourceFile, bool LocateIncludedFile ( SourceFile* sourceFile,
const Module& module, const Module& module,
const std::string& includedFilename, const std::string& includedFilename,
bool searchCurrentDirectory, bool searchCurrentDirectory,
bool includeNext, bool includeNext,
std::string& resolvedFilename ); File& resolvedFile );
SourceFile* RetrieveFromCacheOrParse ( const Module& module, SourceFile* RetrieveFromCacheOrParse ( const Module& module,
const std::string& filename, const File& file,
SourceFile* parentSourceFile ); SourceFile* parentSourceFile );
SourceFile* RetrieveFromCache ( const std::string& filename ); SourceFile* RetrieveFromCache ( const File& file );
void CheckAutomaticDependencies ( bool verbose ); void CheckAutomaticDependencies ( bool verbose );
void CheckAutomaticDependenciesForModule ( Module& module, void CheckAutomaticDependenciesForModule ( Module& module,
bool verbose ); bool verbose );
@ -792,19 +783,13 @@ private:
bool verbose ); bool verbose );
void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile ); void CheckAutomaticDependenciesForFile ( SourceFile* sourceFile );
void GetIncludeDirectories ( std::vector<Include*>& includes, void GetIncludeDirectories ( std::vector<Include*>& includes,
const Module& module, const Module& module );
Include& currentDirectory,
bool searchCurrentDirectory );
void GetModuleFiles ( const Module& module, void GetModuleFiles ( const Module& module,
std::vector<File*>& files ) const; std::vector<File*>& files ) const;
void ParseFiles (); void ParseFiles ();
void ParseFiles ( const Module& module ); void ParseFiles ( const Module& module );
void ParseFile ( const Module& module, void ParseFile ( const Module& module,
const File& file ); const File& file );
std::string ReplaceVariable ( const std::string& name,
const std::string& value,
std::string path );
std::string ResolveVariablesInPath ( const std::string& path );
std::map<std::string, SourceFile*> sourcefile_map; std::map<std::string, SourceFile*> sourcefile_map;
}; };