summaryrefslogtreecommitdiffstats
path: root/Source/cmState.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmState.cxx')
-rw-r--r--Source/cmState.cxx150
1 files changed, 150 insertions, 0 deletions
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 82a2939..4965ae3 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -197,6 +197,10 @@ void cmState::Initialize()
this->Locations.clear();
this->OutputLocations.clear();
this->ParentPositions.clear();
+ this->CurrentSourceDirectoryComponents.clear();
+ this->CurrentBinaryDirectoryComponents.clear();
+ this->RelativePathTopSource.clear();
+ this->RelativePathTopBinary.clear();
this->CreateSnapshot(Snapshot());
this->DefineProperty
@@ -458,6 +462,10 @@ void cmState::SetSourceDirectory(std::string const& sourceDirectory)
{
this->SourceDirectory = sourceDirectory;
cmSystemTools::ConvertToUnixSlashes(this->SourceDirectory);
+
+ cmSystemTools::SplitPath(
+ cmSystemTools::CollapseFullPath(this->SourceDirectory),
+ this->SourceDirectoryComponents);
}
const char* cmState::GetSourceDirectory() const
@@ -465,10 +473,19 @@ const char* cmState::GetSourceDirectory() const
return this->SourceDirectory.c_str();
}
+std::vector<std::string> const& cmState::GetSourceDirectoryComponents() const
+{
+ return this->SourceDirectoryComponents;
+}
+
void cmState::SetBinaryDirectory(std::string const& binaryDirectory)
{
this->BinaryDirectory = binaryDirectory;
cmSystemTools::ConvertToUnixSlashes(this->BinaryDirectory);
+
+ cmSystemTools::SplitPath(
+ cmSystemTools::CollapseFullPath(this->BinaryDirectory),
+ this->BinaryDirectoryComponents);
}
const char* cmState::GetBinaryDirectory() const
@@ -476,12 +493,103 @@ const char* cmState::GetBinaryDirectory() const
return this->BinaryDirectory.c_str();
}
+std::vector<std::string> const& cmState::GetBinaryDirectoryComponents() const
+{
+ return this->BinaryDirectoryComponents;
+}
+
+void cmState::Snapshot::ComputeRelativePathTopSource()
+{
+ // Relative path conversion inside the source tree is not used to
+ // construct relative paths passed to build tools so it is safe to use
+ // even when the source is a network path.
+
+ cmState::Snapshot snapshot = *this;
+ std::vector<cmState::Snapshot> snapshots;
+ snapshots.push_back(snapshot);
+ while (true)
+ {
+ snapshot = snapshot.GetParent();
+ if (snapshot.IsValid())
+ {
+ snapshots.push_back(snapshot);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ std::string result = snapshots.front().GetCurrentSourceDirectory();
+
+ for (std::vector<cmState::Snapshot>::const_iterator it =
+ snapshots.begin() + 1; it != snapshots.end(); ++it)
+ {
+ std::string currentSource = it->GetCurrentSourceDirectory();
+ if(cmSystemTools::IsSubDirectory(result, currentSource))
+ {
+ result = currentSource;
+ }
+ }
+ this->State->RelativePathTopSource[this->Position] = result;
+}
+
+void cmState::Snapshot::ComputeRelativePathTopBinary()
+{
+ cmState::Snapshot snapshot = *this;
+ std::vector<cmState::Snapshot> snapshots;
+ snapshots.push_back(snapshot);
+ while (true)
+ {
+ snapshot = snapshot.GetParent();
+ if (snapshot.IsValid())
+ {
+ snapshots.push_back(snapshot);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ std::string result =
+ snapshots.front().GetCurrentBinaryDirectory();
+
+ for (std::vector<cmState::Snapshot>::const_iterator it =
+ snapshots.begin() + 1; it != snapshots.end(); ++it)
+ {
+ std::string currentBinary = it->GetCurrentBinaryDirectory();
+ if(cmSystemTools::IsSubDirectory(result, currentBinary))
+ {
+ result = currentBinary;
+ }
+ }
+
+ // The current working directory on Windows cannot be a network
+ // path. Therefore relative paths cannot work when the binary tree
+ // is a network path.
+ if(result.size() < 2 || result.substr(0, 2) != "//")
+ {
+ this->State->RelativePathTopBinary[this->Position] = result;
+ }
+ else
+ {
+ this->State->RelativePathTopBinary[this->Position] = "";
+ }
+}
+
cmState::Snapshot cmState::CreateSnapshot(Snapshot originSnapshot)
{
PositionType pos = this->ParentPositions.size();
this->ParentPositions.push_back(originSnapshot.Position);
this->Locations.resize(this->Locations.size() + 1);
this->OutputLocations.resize(this->OutputLocations.size() + 1);
+ this->CurrentSourceDirectoryComponents.resize(
+ this->CurrentSourceDirectoryComponents.size() + 1);
+ this->CurrentBinaryDirectoryComponents.resize(
+ this->CurrentBinaryDirectoryComponents.size() + 1);
+ this->RelativePathTopSource.resize(this->RelativePathTopSource.size() + 1);
+ this->RelativePathTopBinary.resize(this->RelativePathTopBinary.size() + 1);
return cmState::Snapshot(this, pos);
}
@@ -505,6 +613,11 @@ void cmState::Snapshot::SetCurrentSourceDirectory(std::string const& dir)
this->State->Locations[this->Position]);
this->State->Locations[this->Position] =
cmSystemTools::CollapseFullPath(this->State->Locations[this->Position]);
+
+ cmSystemTools::SplitPath(
+ this->State->Locations[this->Position],
+ this->State->CurrentSourceDirectoryComponents[this->Position]);
+ this->ComputeRelativePathTopSource();
}
const char* cmState::Snapshot::GetCurrentBinaryDirectory() const
@@ -521,6 +634,43 @@ void cmState::Snapshot::SetCurrentBinaryDirectory(std::string const& dir)
this->State->OutputLocations[this->Position] =
cmSystemTools::CollapseFullPath(
this->State->OutputLocations[this->Position]);
+
+ cmSystemTools::SplitPath(
+ this->State->OutputLocations[this->Position],
+ this->State->CurrentBinaryDirectoryComponents[this->Position]);
+ this->ComputeRelativePathTopBinary();
+}
+
+std::vector<std::string> const&
+cmState::Snapshot::GetCurrentSourceDirectoryComponents()
+{
+ return this->State->CurrentSourceDirectoryComponents[this->Position];
+}
+
+std::vector<std::string> const&
+cmState::Snapshot::GetCurrentBinaryDirectoryComponents()
+{
+ return this->State->CurrentBinaryDirectoryComponents[this->Position];
+}
+
+const char* cmState::Snapshot::GetRelativePathTopSource() const
+{
+ return this->State->RelativePathTopSource[this->Position].c_str();
+}
+
+const char* cmState::Snapshot::GetRelativePathTopBinary() const
+{
+ return this->State->RelativePathTopBinary[this->Position].c_str();
+}
+
+void cmState::Snapshot::SetRelativePathTopSource(const char* dir)
+{
+ this->State->RelativePathTopSource[this->Position] = dir;
+}
+
+void cmState::Snapshot::SetRelativePathTopBinary(const char* dir)
+{
+ this->State->RelativePathTopBinary[this->Position] = dir;
}
bool cmState::Snapshot::IsValid() const