mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-01 03:29:18 -05:00
Merge topic 'output-converter-simplify'
33f08eec18cmOutputConverter: Moved ContainedInDirectory to cmStateDirectory87e810f223cmOutputConverter: Moved ForceToRelativePath to cmSystem Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !2665
This commit is contained in:
@@ -697,9 +697,9 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile,
|
||||
std::string cmDependsFortran::MaybeConvertToRelativePath(
|
||||
std::string const& base, std::string const& path)
|
||||
{
|
||||
if (!cmOutputConverter::ContainedInDirectory(
|
||||
base, path, this->LocalGenerator->GetStateSnapshot().GetDirectory())) {
|
||||
if (!this->LocalGenerator->GetStateSnapshot().GetDirectory().ContainsBoth(
|
||||
base, path)) {
|
||||
return path;
|
||||
}
|
||||
return cmOutputConverter::ForceToRelativePath(base, path);
|
||||
return cmSystemTools::ForceToRelativePath(base, path);
|
||||
}
|
||||
|
||||
@@ -3563,7 +3563,7 @@ std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
|
||||
{
|
||||
// We force conversion because Xcode breakpoints do not work unless
|
||||
// they are in a file named relative to the source tree.
|
||||
return cmOutputConverter::ForceToRelativePath(
|
||||
return cmSystemTools::ForceToRelativePath(
|
||||
cmSystemTools::JoinPath(this->ProjectSourceDirectoryComponents), p);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "cmOutputConverter.h"
|
||||
#include "cmStateDirectory.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
|
||||
cmStateDirectory const& stateDir)
|
||||
@@ -46,9 +47,8 @@ std::string cmLinkLineComputer::ConvertToLinkReference(
|
||||
{
|
||||
std::string relLib = lib;
|
||||
|
||||
if (cmOutputConverter::ContainedInDirectory(
|
||||
this->StateDir.GetCurrentBinary(), lib, this->StateDir)) {
|
||||
relLib = cmOutputConverter::ForceToRelativePath(
|
||||
if (this->StateDir.ContainsBoth(this->StateDir.GetCurrentBinary(), lib)) {
|
||||
relLib = cmSystemTools::ForceToRelativePath(
|
||||
this->StateDir.GetCurrentBinary(), lib);
|
||||
}
|
||||
return relLib;
|
||||
|
||||
@@ -2093,9 +2093,8 @@ void cmLocalUnixMakefileGenerator3::CreateCDCommand(
|
||||
std::string cmLocalUnixMakefileGenerator3::MaybeConvertToRelativePath(
|
||||
std::string const& base, std::string const& path)
|
||||
{
|
||||
if (!cmOutputConverter::ContainedInDirectory(
|
||||
base, path, this->GetStateSnapshot().GetDirectory())) {
|
||||
if (!this->GetStateSnapshot().GetDirectory().ContainsBoth(base, path)) {
|
||||
return path;
|
||||
}
|
||||
return cmOutputConverter::ForceToRelativePath(base, path);
|
||||
return cmSystemTools::ForceToRelativePath(base, path);
|
||||
}
|
||||
|
||||
@@ -1308,11 +1308,10 @@ public:
|
||||
private:
|
||||
std::string MaybeConvertToRelativePath(std::string const& obj)
|
||||
{
|
||||
if (!cmOutputConverter::ContainedInDirectory(
|
||||
this->StateDir.GetCurrentBinary(), obj, this->StateDir)) {
|
||||
if (!this->StateDir.ContainsBoth(this->StateDir.GetCurrentBinary(), obj)) {
|
||||
return obj;
|
||||
}
|
||||
return cmOutputConverter::ForceToRelativePath(
|
||||
return cmSystemTools::ForceToRelativePath(
|
||||
this->StateDir.GetCurrentBinary(), obj);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmState.h"
|
||||
#include "cmStateDirectory.h"
|
||||
#include "cmSystemTools.h"
|
||||
@@ -73,119 +72,15 @@ std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool cmOutputConverterNotAbove(const char* a, const char* b)
|
||||
{
|
||||
return (cmSystemTools::ComparePath(a, b) ||
|
||||
cmSystemTools::IsSubDirectory(a, b));
|
||||
}
|
||||
|
||||
bool cmOutputConverter::ContainedInDirectory(std::string const& local_path,
|
||||
std::string const& remote_path,
|
||||
cmStateDirectory const& directory)
|
||||
{
|
||||
const std::string& relativePathTopBinary =
|
||||
directory.GetRelativePathTopBinary();
|
||||
const std::string& relativePathTopSource =
|
||||
directory.GetRelativePathTopSource();
|
||||
|
||||
const bool bothInBinary =
|
||||
cmOutputConverterNotAbove(local_path.c_str(),
|
||||
relativePathTopBinary.c_str()) &&
|
||||
cmOutputConverterNotAbove(remote_path.c_str(),
|
||||
relativePathTopBinary.c_str());
|
||||
|
||||
const bool bothInSource =
|
||||
cmOutputConverterNotAbove(local_path.c_str(),
|
||||
relativePathTopSource.c_str()) &&
|
||||
cmOutputConverterNotAbove(remote_path.c_str(),
|
||||
relativePathTopSource.c_str());
|
||||
|
||||
return bothInSource || bothInBinary;
|
||||
}
|
||||
|
||||
std::string cmOutputConverter::ConvertToRelativePath(
|
||||
std::string const& local_path, std::string const& remote_path) const
|
||||
{
|
||||
if (!ContainedInDirectory(local_path, remote_path,
|
||||
this->StateSnapshot.GetDirectory())) {
|
||||
if (!this->StateSnapshot.GetDirectory().ContainsBoth(local_path,
|
||||
remote_path)) {
|
||||
return remote_path;
|
||||
}
|
||||
|
||||
return cmOutputConverter::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;
|
||||
return cmSystemTools::ForceToRelativePath(local_path, remote_path);
|
||||
}
|
||||
|
||||
static bool cmOutputConverterIsShellOperator(const std::string& str)
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "cmStateSnapshot.h"
|
||||
|
||||
class cmState;
|
||||
class cmStateDirectory;
|
||||
|
||||
class cmOutputConverter
|
||||
{
|
||||
@@ -92,10 +91,6 @@ public:
|
||||
};
|
||||
static FortranFormat GetFortranFormat(const char* value);
|
||||
|
||||
static bool ContainedInDirectory(std::string const& local_path,
|
||||
std::string const& remote_path,
|
||||
cmStateDirectory const& directory);
|
||||
|
||||
/**
|
||||
* Convert the given remote path to a relative path with respect to
|
||||
* the given local path. Both paths must use forward slashes and not
|
||||
@@ -106,14 +101,6 @@ public:
|
||||
std::string ConvertToRelativePath(std::string const& local_path,
|
||||
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:
|
||||
cmState* GetState() const;
|
||||
|
||||
|
||||
@@ -138,6 +138,23 @@ void cmStateDirectory::SetRelativePathTopBinary(const char* dir)
|
||||
this->DirectoryState->RelativePathTopBinary = dir;
|
||||
}
|
||||
|
||||
bool cmStateDirectory::ContainsBoth(std::string const& local_path,
|
||||
std::string const& remote_path) const
|
||||
{
|
||||
auto PathEqOrSubDir = [](std::string const& a, std::string const& b) {
|
||||
return (cmSystemTools::ComparePath(a, b) ||
|
||||
cmSystemTools::IsSubDirectory(a, b));
|
||||
};
|
||||
|
||||
bool bothInBinary = PathEqOrSubDir(local_path, GetRelativePathTopBinary()) &&
|
||||
PathEqOrSubDir(remote_path, GetRelativePathTopBinary());
|
||||
|
||||
bool bothInSource = PathEqOrSubDir(local_path, GetRelativePathTopSource()) &&
|
||||
PathEqOrSubDir(remote_path, GetRelativePathTopSource());
|
||||
|
||||
return bothInBinary || bothInSource;
|
||||
}
|
||||
|
||||
cmStateDirectory::cmStateDirectory(
|
||||
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator iter,
|
||||
const cmStateSnapshot& snapshot)
|
||||
|
||||
@@ -32,6 +32,9 @@ public:
|
||||
void SetRelativePathTopSource(const char* dir);
|
||||
void SetRelativePathTopBinary(const char* dir);
|
||||
|
||||
bool ContainsBoth(std::string const& local_path,
|
||||
std::string const& remote_path) const;
|
||||
|
||||
cmStringRange GetIncludeDirectoriesEntries() const;
|
||||
cmBacktraceRange GetIncludeDirectoriesEntryBacktraces() const;
|
||||
void AppendIncludeDirectoriesEntry(std::string const& vec,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
@@ -1463,6 +1464,80 @@ std::string cmSystemTools::RelativePath(std::string const& local,
|
||||
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 const& file)
|
||||
{
|
||||
|
||||
@@ -375,6 +375,14 @@ public:
|
||||
static std::string RelativePath(std::string const& local,
|
||||
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
|
||||
* For example CollapseCombinedPath("a/b/c", "../../d") results in "a/d"
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user