summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmDependsC.cxx18
-rw-r--r--Source/cmSystemTools.cxx34
-rw-r--r--Source/cmSystemTools.h6
3 files changed, 44 insertions, 14 deletions
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 43b7b8a..a252a1a 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -193,17 +193,8 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// Construct the name of the file as if it were in the current
// include directory. Avoid using a leading "./".
- tempPathStr = "";
- if((*i) == ".")
- {
- tempPathStr += current.FileName;
- }
- else
- {
- tempPathStr += *i;
- tempPathStr+="/";
- tempPathStr+=current.FileName;
- }
+ tempPathStr =
+ cmSystemTools::CollapseCombinedPath(*i, current.FileName);
// Look for the file in this location.
if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
@@ -458,9 +449,8 @@ void cmDependsC::Scan(std::istream& is, const char* directory,
// This was a double-quoted include with a relative path. We
// must check for the file in the directory containing the
// file we are scanning.
- entry.QuotedLocation = directory;
- entry.QuotedLocation += "/";
- entry.QuotedLocation += entry.FileName;
+ entry.QuotedLocation =
+ cmSystemTools::CollapseCombinedPath(directory, entry.FileName);
}
// Queue the file if it has not yet been encountered and it
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 21c361d..f32f2dc 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1594,6 +1594,40 @@ std::string cmSystemTools::RelativePath(const char* local, const char* remote)
return cmsys::SystemTools::RelativePath(local, remote);
}
+std::string cmSystemTools::CollapseCombinedPath(std::string const& dir,
+ std::string const& file)
+{
+ if(dir.empty() || dir == ".")
+ {
+ return file;
+ }
+
+ std::vector<std::string> dirComponents;
+ std::vector<std::string> fileComponents;
+ cmSystemTools::SplitPath(dir.c_str(), dirComponents);
+ cmSystemTools::SplitPath(file.c_str(), fileComponents);
+
+ if(fileComponents.empty())
+ {
+ return dir;
+ }
+ if(fileComponents[0] != "")
+ {
+ // File is not a relative path.
+ return file;
+ }
+
+ std::vector<std::string>::iterator i = fileComponents.begin()+1;
+ while(i != fileComponents.end() && *i == ".." && dirComponents.size() > 1)
+ {
+ ++i; // Remove ".." file component.
+ dirComponents.pop_back(); // Remove last dir component.
+ }
+
+ dirComponents.insert(dirComponents.end(), i, fileComponents.end());
+ return cmSystemTools::JoinPath(dirComponents);
+}
+
#ifdef CMAKE_BUILD_WITH_CMAKE
//----------------------------------------------------------------------
bool cmSystemTools::UnsetEnv(const char* value)
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index ec53929..9614449 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -365,6 +365,12 @@ public:
*/
static std::string RelativePath(const char* local, const char* remote);
+ /** Joins two paths while collapsing x/../ parts
+ * For example CollapseCombinedPath("a/b/c", "../../d") results in "a/d"
+ */
+ static std::string CollapseCombinedPath(std::string const& dir,
+ std::string const& file);
+
#ifdef CMAKE_BUILD_WITH_CMAKE
/** Remove an environment variable */
static bool UnsetEnv(const char* value);