BUG: Fixed scanning to account for double-quote includes.
This commit is contained in:
parent
5290b40c47
commit
2fe4e650bf
|
@ -37,7 +37,7 @@ cmDependsC::cmDependsC(const char* dir, const char* targetFile,
|
|||
cmDepends(dir, targetFile),
|
||||
m_SourceFile(sourceFile),
|
||||
m_IncludePath(&includes),
|
||||
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]"),
|
||||
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
|
||||
m_IncludeRegexScan(scanRegex),
|
||||
m_IncludeRegexComplain(complainRegex)
|
||||
{
|
||||
|
@ -65,7 +65,9 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
|
||||
// Walk the dependency graph starting with the source file.
|
||||
bool first = true;
|
||||
m_Unscanned.push(m_SourceFile);
|
||||
UnscannedEntry root;
|
||||
root.FileName = m_SourceFile;
|
||||
m_Unscanned.push(root);
|
||||
m_Encountered.clear();
|
||||
m_Encountered.insert(m_SourceFile);
|
||||
std::set<cmStdString> dependencies;
|
||||
|
@ -73,18 +75,26 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
while(!m_Unscanned.empty())
|
||||
{
|
||||
// Get the next file to scan.
|
||||
std::string fname = m_Unscanned.front();
|
||||
UnscannedEntry current = m_Unscanned.front();
|
||||
m_Unscanned.pop();
|
||||
|
||||
// If not a full path, find the file in the include path.
|
||||
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
|
||||
{
|
||||
for(std::vector<std::string>::const_iterator i = m_IncludePath->begin();
|
||||
|
@ -101,7 +111,7 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
{
|
||||
temp += "/";
|
||||
}
|
||||
temp += fname;
|
||||
temp += current.FileName;
|
||||
|
||||
// Look for the file in this location.
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -134,8 +146,10 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
// Add this file as a dependency.
|
||||
dependencies.insert(fullName);
|
||||
|
||||
// Scan this file for new dependencies.
|
||||
this->Scan(fin);
|
||||
// Scan this file for new dependencies. Pass the directory
|
||||
// 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.
|
||||
std::string line;
|
||||
|
@ -245,15 +259,29 @@ void cmDependsC::Scan(std::istream& is)
|
|||
if(m_IncludeRegexLine.find(line.c_str()))
|
||||
{
|
||||
// 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
|
||||
// matches the regular expression for recursive scanning.
|
||||
if(m_Encountered.find(includeFile) == m_Encountered.end() &&
|
||||
m_IncludeRegexScan.find(includeFile.c_str()))
|
||||
// matches the regular expression for recursive scanning. Note
|
||||
// that this check does not account for the possibility of two
|
||||
// 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_Unscanned.push(includeFile);
|
||||
m_Encountered.insert(entry.FileName);
|
||||
m_Unscanned.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
|||
virtual bool CheckDependencies(std::istream& is);
|
||||
|
||||
// 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.
|
||||
std::string m_SourceFile;
|
||||
|
@ -65,8 +65,13 @@ protected:
|
|||
cmsys::RegularExpression m_IncludeRegexComplain;
|
||||
|
||||
// Data structures for dependency graph walk.
|
||||
struct UnscannedEntry
|
||||
{
|
||||
cmStdString FileName;
|
||||
cmStdString QuotedLocation;
|
||||
};
|
||||
std::set<cmStdString> m_Encountered;
|
||||
std::queue<cmStdString> m_Unscanned;
|
||||
std::queue<UnscannedEntry> m_Unscanned;
|
||||
|
||||
private:
|
||||
cmDependsC(cmDependsC const&); // Purposely not implemented.
|
||||
|
|
Loading…
Reference in New Issue