summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-08-05 13:27:01 -0400
committerBrad King <brad.king@kitware.com>2008-08-05 13:27:01 -0400
commitd800910efd5c59e25ba0026a14642e0b99b237f6 (patch)
tree90fa7fb7b426d30dbec364eb6a3dfa408c1588a1
parentd35b5a2fb1159dbdfea46961df522ccf21e3e373 (diff)
downloadcmake-d800910efd5c59e25ba0026a14642e0b99b237f6.tar.gz
BUG: Fix matching of ambiguous sf extensions.
A name with an ambiguous extension may only match an unambiguous name that is extended by one of the fixed set of extensions tried when finding the source file on disk. This rule makes matching of source files with ambiguous extensions much less aggressive but still sufficient.
-rw-r--r--Source/cmSourceFileLocation.cxx74
-rw-r--r--Source/cmSourceFileLocation.h2
2 files changed, 58 insertions, 18 deletions
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index d7b2aa6baf..9b2affaeec 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -152,37 +152,75 @@ void cmSourceFileLocation::UpdateDirectory(const char* name)
}
//----------------------------------------------------------------------------
+bool
+cmSourceFileLocation
+::MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const
+{
+ // This location's extension is not ambiguous but loc's extension
+ // is. See if the names match as-is.
+ if(this->Name == loc.Name)
+ {
+ return true;
+ }
+
+ // Check if loc's name could possibly be extended to our name by
+ // adding an extension.
+ if(!(this->Name.size() > loc.Name.size() &&
+ this->Name.substr(0, loc.Name.size()) == loc.Name &&
+ this->Name[loc.Name.size()] == '.'))
+ {
+ return false;
+ }
+
+ // Only a fixed set of extensions will be tried to match a file on
+ // disk. One of these must match if loc refers to this source file.
+ std::string ext = this->Name.substr(loc.Name.size()+1);
+ cmMakefile* mf = this->Makefile;
+ const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
+ if(std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end())
+ {
+ return true;
+ }
+ const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
+ if(std::find(hdrExts.begin(), hdrExts.end(), ext) != hdrExts.end())
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
{
- if(this->AmbiguousExtension || loc.AmbiguousExtension)
+ if(this->AmbiguousExtension && loc.AmbiguousExtension)
{
- // Need to compare without the file extension.
- std::string thisName;
- if(this->AmbiguousExtension)
- {
- thisName = this->Name;
- }
- else
- {
- thisName = cmSystemTools::GetFilenameWithoutLastExtension(this->Name);
- }
- std::string locName;
- if(loc.AmbiguousExtension)
+ // Both extensions are ambiguous. Since only the old fixed set of
+ // extensions will be tried, the names must match at this point to
+ // be the same file.
+ if(this->Name != loc.Name)
{
- locName = loc.Name;
+ return false;
}
- else
+ }
+ else if(this->AmbiguousExtension)
+ {
+ // Only "this" extension is ambiguous.
+ if(!loc.MatchesAmbiguousExtension(*this))
{
- locName = cmSystemTools::GetFilenameWithoutLastExtension(loc.Name);
+ return false;
}
- if(thisName != locName)
+ }
+ else if(loc.AmbiguousExtension)
+ {
+ // Only "loc" extension is ambiguous.
+ if(!this->MatchesAmbiguousExtension(loc))
{
return false;
}
}
else
{
- // Compare with extension.
+ // Neither extension is ambiguous.
if(this->Name != loc.Name)
{
return false;
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
index c14b2fa84b..3ee528aa81 100644
--- a/Source/cmSourceFileLocation.h
+++ b/Source/cmSourceFileLocation.h
@@ -94,6 +94,8 @@ private:
std::string Directory;
std::string Name;
+ bool MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const;
+
// Update the location with additional knowledge.
void Update(cmSourceFileLocation const& loc);
void Update(const char* name);