Commit 87e810f2 authored by bmanga's avatar bmanga

cmOutputConverter: Moved ForceToRelativePath to cmSystem

parent 99a224e3
...@@ -701,5 +701,5 @@ std::string cmDependsFortran::MaybeConvertToRelativePath( ...@@ -701,5 +701,5 @@ std::string cmDependsFortran::MaybeConvertToRelativePath(
base, path, this->LocalGenerator->GetStateSnapshot().GetDirectory())) { base, path, this->LocalGenerator->GetStateSnapshot().GetDirectory())) {
return path; return path;
} }
return cmOutputConverter::ForceToRelativePath(base, path); return cmSystemTools::ForceToRelativePath(base, path);
} }
...@@ -3563,7 +3563,7 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p) ...@@ -3563,7 +3563,7 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
{ {
// We force conversion because Xcode breakpoints do not work unless // We force conversion because Xcode breakpoints do not work unless
// they are in a file named relative to the source tree. // they are in a file named relative to the source tree.
return cmOutputConverter::ForceToRelativePath( return cmSystemTools::ForceToRelativePath(
cmSystemTools::JoinPath(this->ProjectSourceDirectoryComponents), p); cmSystemTools::JoinPath(this->ProjectSourceDirectoryComponents), p);
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "cmOutputConverter.h" #include "cmOutputConverter.h"
#include "cmStateDirectory.h" #include "cmStateDirectory.h"
#include "cmStateTypes.h" #include "cmStateTypes.h"
#include "cmSystemTools.h"
cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter, cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) cmStateDirectory const& stateDir)
...@@ -48,7 +49,7 @@ std::string cmLinkLineComputer::ConvertToLinkReference( ...@@ -48,7 +49,7 @@ std::string cmLinkLineComputer::ConvertToLinkReference(
if (cmOutputConverter::ContainedInDirectory( if (cmOutputConverter::ContainedInDirectory(
this->StateDir.GetCurrentBinary(), lib, this->StateDir)) { this->StateDir.GetCurrentBinary(), lib, this->StateDir)) {
relLib = cmOutputConverter::ForceToRelativePath( relLib = cmSystemTools::ForceToRelativePath(
this->StateDir.GetCurrentBinary(), lib); this->StateDir.GetCurrentBinary(), lib);
} }
return relLib; return relLib;
......
...@@ -2097,5 +2097,5 @@ std::string cmLocalUnixMakefileGenerator3::MaybeConvertToRelativePath( ...@@ -2097,5 +2097,5 @@ std::string cmLocalUnixMakefileGenerator3::MaybeConvertToRelativePath(
base, path, this->GetStateSnapshot().GetDirectory())) { base, path, this->GetStateSnapshot().GetDirectory())) {
return path; return path;
} }
return cmOutputConverter::ForceToRelativePath(base, path); return cmSystemTools::ForceToRelativePath(base, path);
} }
...@@ -1312,7 +1312,7 @@ private: ...@@ -1312,7 +1312,7 @@ private:
this->StateDir.GetCurrentBinary(), obj, this->StateDir)) { this->StateDir.GetCurrentBinary(), obj, this->StateDir)) {
return obj; return obj;
} }
return cmOutputConverter::ForceToRelativePath( return cmSystemTools::ForceToRelativePath(
this->StateDir.GetCurrentBinary(), obj); this->StateDir.GetCurrentBinary(), obj);
} }
......
...@@ -111,81 +111,7 @@ std::string cmOutputConverter::ConvertToRelativePath( ...@@ -111,81 +111,7 @@ std::string cmOutputConverter::ConvertToRelativePath(
return remote_path; return remote_path;
} }
return cmOutputConverter::ForceToRelativePath(local_path, remote_path); return cmSystemTools::ForceToRelativePath(local_path, remote_path);
}
std::string cmOutputConverter::ForceToRelativePath(
std::string const& local_path, std::string const& remote_path)
{
// The paths should never be quoted.
assert(local_path.front() != '\"');
assert(remote_path.front() != '\"');
// The local path should never have a trailing slash.
assert(local_path.empty() || local_path.back() != '/');
// If the path is already relative then just return the path.
if (!cmSystemTools::FileIsFullPath(remote_path)) {
return remote_path;
}
// Identify the longest shared path component between the remote
// path and the local path.
std::vector<std::string> local;
cmSystemTools::SplitPath(local_path, local);
std::vector<std::string> remote;
cmSystemTools::SplitPath(remote_path, remote);
unsigned int common = 0;
while (common < remote.size() && common < local.size() &&
cmSystemTools::ComparePath(remote[common], local[common])) {
++common;
}
// If no part of the path is in common then return the full path.
if (common == 0) {
return remote_path;
}
// If the entire path is in common then just return a ".".
if (common == remote.size() && common == local.size()) {
return ".";
}
// If the entire path is in common except for a trailing slash then
// just return a "./".
if (common + 1 == remote.size() && remote[common].empty() &&
common == local.size()) {
return "./";
}
// Construct the relative path.
std::string relative;
// First add enough ../ to get up to the level of the shared portion
// of the path. Leave off the trailing slash. Note that the last
// component of local will never be empty because local should never
// have a trailing slash.
for (unsigned int i = common; i < local.size(); ++i) {
relative += "..";
if (i < local.size() - 1) {
relative += "/";
}
}
// Now add the portion of the destination path that is not included
// in the shared portion of the path. Add a slash the first time
// only if there was already something in the path. If there was a
// trailing slash in the input then the last iteration of the loop
// will add a slash followed by an empty string which will preserve
// the trailing slash in the output.
if (!relative.empty() && !remote.empty()) {
relative += "/";
}
relative += cmJoin(cmMakeRange(remote).advance(common), "/");
// Finally return the path.
return relative;
} }
static bool cmOutputConverterIsShellOperator(const std::string& str) static bool cmOutputConverterIsShellOperator(const std::string& str)
......
...@@ -106,14 +106,6 @@ public: ...@@ -106,14 +106,6 @@ public:
std::string ConvertToRelativePath(std::string const& local_path, std::string ConvertToRelativePath(std::string const& local_path,
std::string const& remote_path) const; std::string const& remote_path) const;
/**
* Convert the given remote path to a relative path with respect to
* the given local path. Both paths must use forward slashes and not
* already be escaped or quoted.
*/
static std::string ForceToRelativePath(std::string const& local_path,
std::string const& remote_path);
private: private:
cmState* GetState() const; cmState* GetState() const;
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <utility> #include <utility>
#include <vector>
#if defined(_WIN32) #if defined(_WIN32)
# include <windows.h> # include <windows.h>
...@@ -1463,6 +1464,80 @@ std::string cmSystemTools::RelativePath(std::string const& local, ...@@ -1463,6 +1464,80 @@ std::string cmSystemTools::RelativePath(std::string const& local,
return cmsys::SystemTools::RelativePath(local, remote); return cmsys::SystemTools::RelativePath(local, remote);
} }
std::string cmSystemTools::ForceToRelativePath(std::string const& local_path,
std::string const& remote_path)
{
// The paths should never be quoted.
assert(local_path.front() != '\"');
assert(remote_path.front() != '\"');
// The local path should never have a trailing slash.
assert(local_path.empty() || local_path.back() != '/');
// If the path is already relative then just return the path.
if (!cmSystemTools::FileIsFullPath(remote_path)) {
return remote_path;
}
// Identify the longest shared path component between the remote
// path and the local path.
std::vector<std::string> local;
cmSystemTools::SplitPath(local_path, local);
std::vector<std::string> remote;
cmSystemTools::SplitPath(remote_path, remote);
unsigned int common = 0;
while (common < remote.size() && common < local.size() &&
cmSystemTools::ComparePath(remote[common], local[common])) {
++common;
}
// If no part of the path is in common then return the full path.
if (common == 0) {
return remote_path;
}
// If the entire path is in common then just return a ".".
if (common == remote.size() && common == local.size()) {
return ".";
}
// If the entire path is in common except for a trailing slash then
// just return a "./".
if (common + 1 == remote.size() && remote[common].empty() &&
common == local.size()) {
return "./";
}
// Construct the relative path.
std::string relative;
// First add enough ../ to get up to the level of the shared portion
// of the path. Leave off the trailing slash. Note that the last
// component of local will never be empty because local should never
// have a trailing slash.
for (unsigned int i = common; i < local.size(); ++i) {
relative += "..";
if (i < local.size() - 1) {
relative += "/";
}
}
// Now add the portion of the destination path that is not included
// in the shared portion of the path. Add a slash the first time
// only if there was already something in the path. If there was a
// trailing slash in the input then the last iteration of the loop
// will add a slash followed by an empty string which will preserve
// the trailing slash in the output.
if (!relative.empty() && !remote.empty()) {
relative += "/";
}
relative += cmJoin(cmMakeRange(remote).advance(common), "/");
// Finally return the path.
return relative;
}
std::string cmSystemTools::CollapseCombinedPath(std::string const& dir, std::string cmSystemTools::CollapseCombinedPath(std::string const& dir,
std::string const& file) std::string const& file)
{ {
......
...@@ -375,6 +375,14 @@ public: ...@@ -375,6 +375,14 @@ public:
static std::string RelativePath(std::string const& local, static std::string RelativePath(std::string const& local,
std::string const& remote); std::string const& remote);
/**
* Convert the given remote path to a relative path with respect to
* the given local path. Both paths must use forward slashes and not
* already be escaped or quoted.
*/
static std::string ForceToRelativePath(std::string const& local_path,
std::string const& remote_path);
/** Joins two paths while collapsing x/../ parts /** Joins two paths while collapsing x/../ parts
* For example CollapseCombinedPath("a/b/c", "../../d") results in "a/d" * For example CollapseCombinedPath("a/b/c", "../../d") results in "a/d"
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment