BUG: Fixed scanning to account for double-quote includes.

This commit is contained in:
Brad King 2005-03-03 15:22:18 -05:00
parent 5290b40c47
commit 2fe4e650bf
2 changed files with 53 additions and 20 deletions

View File

@ -37,7 +37,7 @@ cmDependsC::cmDependsC(const char* dir, const char* targetFile,
cmDepends(dir, targetFile), cmDepends(dir, targetFile),
m_SourceFile(sourceFile), m_SourceFile(sourceFile),
m_IncludePath(&includes), m_IncludePath(&includes),
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]"), m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
m_IncludeRegexScan(scanRegex), m_IncludeRegexScan(scanRegex),
m_IncludeRegexComplain(complainRegex) m_IncludeRegexComplain(complainRegex)
{ {
@ -65,7 +65,9 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
// Walk the dependency graph starting with the source file. // Walk the dependency graph starting with the source file.
bool first = true; bool first = true;
m_Unscanned.push(m_SourceFile); UnscannedEntry root;
root.FileName = m_SourceFile;
m_Unscanned.push(root);
m_Encountered.clear(); m_Encountered.clear();
m_Encountered.insert(m_SourceFile); m_Encountered.insert(m_SourceFile);
std::set<cmStdString> dependencies; std::set<cmStdString> dependencies;
@ -73,18 +75,26 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
while(!m_Unscanned.empty()) while(!m_Unscanned.empty())
{ {
// Get the next file to scan. // Get the next file to scan.
std::string fname = m_Unscanned.front(); UnscannedEntry current = m_Unscanned.front();
m_Unscanned.pop(); m_Unscanned.pop();
// If not a full path, find the file in the include path. // If not a full path, find the file in the include path.
std::string fullName; std::string fullName;
if(first || cmSystemTools::FileIsFullPath(fname.c_str())) if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
{ {
if(cmSystemTools::FileExists(fname.c_str())) if(cmSystemTools::FileExists(current.FileName.c_str()))
{ {
fullName = fname; fullName = current.FileName;
} }
} }
else if(!current.QuotedLocation.empty() &&
cmSystemTools::FileExists(current.QuotedLocation.c_str()))
{
// The include statement producing this entry was a double-quote
// include and the included file is present in the directory of
// the source containing the include statement.
fullName = current.QuotedLocation;
}
else else
{ {
for(std::vector<std::string>::const_iterator i = m_IncludePath->begin(); for(std::vector<std::string>::const_iterator i = m_IncludePath->begin();
@ -101,7 +111,7 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
{ {
temp += "/"; temp += "/";
} }
temp += fname; temp += current.FileName;
// Look for the file in this location. // Look for the file in this location.
if(cmSystemTools::FileExists(temp.c_str())) if(cmSystemTools::FileExists(temp.c_str()))
@ -114,9 +124,11 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
// Complain if the file cannot be found and matches the complain // Complain if the file cannot be found and matches the complain
// regex. // regex.
if(fullName.empty() && m_IncludeRegexComplain.find(fname.c_str())) if(fullName.empty() &&
m_IncludeRegexComplain.find(current.FileName.c_str()))
{ {
cmSystemTools::Error("Cannot find file \"", fname.c_str(), "\"."); cmSystemTools::Error("Cannot find file \"",
current.FileName.c_str(), "\".");
return false; return false;
} }
@ -134,8 +146,10 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
// Add this file as a dependency. // Add this file as a dependency.
dependencies.insert(fullName); dependencies.insert(fullName);
// Scan this file for new dependencies. // Scan this file for new dependencies. Pass the directory
this->Scan(fin); // containing the file to handle double-quote includes.
std::string dir = cmSystemTools::GetFilenamePath(fullName);
this->Scan(fin, dir.c_str());
} }
} }
@ -235,7 +249,7 @@ bool cmDependsC::CheckDependencies(std::istream& is)
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmDependsC::Scan(std::istream& is) void cmDependsC::Scan(std::istream& is, const char* directory)
{ {
// Read one line at a time. // Read one line at a time.
std::string line; std::string line;
@ -245,15 +259,29 @@ void cmDependsC::Scan(std::istream& is)
if(m_IncludeRegexLine.find(line.c_str())) if(m_IncludeRegexLine.find(line.c_str()))
{ {
// Get the file being included. // Get the file being included.
std::string includeFile = m_IncludeRegexLine.match(1); UnscannedEntry entry;
entry.FileName = m_IncludeRegexLine.match(1);
if(m_IncludeRegexLine.match(2) == "\"")
{
// This was a double-quoted include. We must check for the
// file in the directory containing the file we are scanning.
entry.QuotedLocation = directory;
entry.QuotedLocation += "/";
entry.QuotedLocation += entry.FileName;
}
// Queue the file if it has not yet been encountered and it // Queue the file if it has not yet been encountered and it
// matches the regular expression for recursive scanning. // matches the regular expression for recursive scanning. Note
if(m_Encountered.find(includeFile) == m_Encountered.end() && // that this check does not account for the possibility of two
m_IncludeRegexScan.find(includeFile.c_str())) // headers with the same name in different directories when one
// is included by double-quotes and the other by angle brackets.
// This kind of problem will be fixed when a more
// preprocessor-like implementation of this scanner is created.
if(m_Encountered.find(entry.FileName) == m_Encountered.end() &&
m_IncludeRegexScan.find(entry.FileName.c_str()))
{ {
m_Encountered.insert(includeFile); m_Encountered.insert(entry.FileName);
m_Unscanned.push(includeFile); m_Unscanned.push(entry);
} }
} }
} }

View File

@ -48,7 +48,7 @@ protected:
virtual bool CheckDependencies(std::istream& is); virtual bool CheckDependencies(std::istream& is);
// Method to scan a single file. // Method to scan a single file.
void Scan(std::istream& is); void Scan(std::istream& is, const char* directory);
// The source file from which to start scanning. // The source file from which to start scanning.
std::string m_SourceFile; std::string m_SourceFile;
@ -65,8 +65,13 @@ protected:
cmsys::RegularExpression m_IncludeRegexComplain; cmsys::RegularExpression m_IncludeRegexComplain;
// Data structures for dependency graph walk. // Data structures for dependency graph walk.
struct UnscannedEntry
{
cmStdString FileName;
cmStdString QuotedLocation;
};
std::set<cmStdString> m_Encountered; std::set<cmStdString> m_Encountered;
std::queue<cmStdString> m_Unscanned; std::queue<UnscannedEntry> m_Unscanned;
private: private:
cmDependsC(cmDependsC const&); // Purposely not implemented. cmDependsC(cmDependsC const&); // Purposely not implemented.