summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-05-04 20:21:21 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2021-06-04 12:52:01 (GMT)
commit966f7250df01df7982aa6ff4117464d797b6bf10 (patch)
tree7d19419beeed67dddecb440caaed4032bfc30f7d /Source/cmSystemTools.cxx
parent2ef3ea394f424bf2397878b00725b93ebe04c589 (diff)
downloadCMake-966f7250df01df7982aa6ff4117464d797b6bf10.zip
CMake-966f7250df01df7982aa6ff4117464d797b6bf10.tar.gz
CMake-966f7250df01df7982aa6ff4117464d797b6bf10.tar.bz2
Refactor: Break up logic in cmSystemTools::ChangeRPath()
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx178
1 files changed, 108 insertions, 70 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 9b81bf2..b45228e 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -14,6 +14,7 @@
#include "cmSystemTools.h"
+#include <cm/optional>
#include <cmext/algorithm>
#include <cm3p/uv.h>
@@ -65,6 +66,7 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
+#include <functional>
#include <iostream>
#include <sstream>
#include <utility>
@@ -2524,6 +2526,7 @@ std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
#endif
#if defined(CMake_USE_ELF_PARSER)
+namespace {
struct cmSystemToolsRPathInfo
{
unsigned long Position;
@@ -2531,15 +2534,15 @@ struct cmSystemToolsRPathInfo
std::string Name;
std::string Value;
};
-#endif
+
+using EmptyCallback = std::function<bool(std::string*, const cmELF&)>;
+using AdjustCallback = std::function<bool(
+ cm::optional<std::string>&, const std::string&, const char*, std::string*)>;
// FIXME: Dispatch if multiple formats are supported.
-#if defined(CMake_USE_ELF_PARSER)
-bool cmSystemTools::ChangeRPath(std::string const& file,
- std::string const& oldRPath,
- std::string const& newRPath,
- bool removeEnvironmentRPath, std::string* emsg,
- bool* changed)
+bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
+ const AdjustCallback& adjustCallback, std::string* emsg,
+ bool* changed)
{
if (changed) {
*changed = false;
@@ -2566,17 +2569,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
++se_count;
}
if (se_count == 0) {
- if (newRPath.empty()) {
- // The new rpath is empty and there is no rpath anyway so it is
- // okay.
- return true;
- }
- if (emsg) {
- *emsg =
- cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ",
- elf.GetErrorMessage());
- }
- return false;
+ return emptyCallback(emsg, elf);
}
for (int i = 0; i < se_count; ++i) {
@@ -2586,68 +2579,38 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
continue;
}
- // Make sure the current rpath contains the old rpath.
- std::string::size_type pos =
- cmSystemToolsFindRPath(se[i]->Value, oldRPath);
- if (pos == std::string::npos) {
- // If it contains the new rpath instead then it is okay.
- if (cmSystemToolsFindRPath(se[i]->Value, newRPath) !=
- std::string::npos) {
- remove_rpath = false;
- continue;
- }
- if (emsg) {
- std::ostringstream e;
- /* clang-format off */
- e << "The current " << se_name[i] << " is:\n"
- << " " << se[i]->Value << "\n"
- << "which does not contain:\n"
- << " " << oldRPath << "\n"
- << "as was expected.";
- /* clang-format on */
- *emsg = e.str();
- }
- return false;
- }
-
// Store information about the entry in the file.
rp[rp_count].Position = se[i]->Position;
rp[rp_count].Size = se[i]->Size;
rp[rp_count].Name = se_name[i];
- std::string::size_type prefix_len = pos;
-
- // If oldRPath was at the end of the file's RPath, and newRPath is empty,
- // we should remove the unnecessary ':' at the end.
- if (newRPath.empty() && pos > 0 && se[i]->Value[pos - 1] == ':' &&
- pos + oldRPath.length() == se[i]->Value.length()) {
- prefix_len--;
- }
-
- // Construct the new value which preserves the part of the path
- // not being changed.
- if (!removeEnvironmentRPath) {
- rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
+ // Adjust the rpath.
+ cm::optional<std::string> outRPath;
+ if (!adjustCallback(outRPath, se[i]->Value, se_name[i], emsg)) {
+ return false;
}
- rp[rp_count].Value += newRPath;
- rp[rp_count].Value += se[i]->Value.substr(pos + oldRPath.length());
- if (!rp[rp_count].Value.empty()) {
- remove_rpath = false;
- }
+ if (outRPath) {
+ if (!outRPath->empty()) {
+ remove_rpath = false;
+ }
- // Make sure there is enough room to store the new rpath and at
- // least one null terminator.
- if (rp[rp_count].Size < rp[rp_count].Value.length() + 1) {
- if (emsg) {
- *emsg = cmStrCat("The replacement path is too long for the ",
- se_name[i], " entry.");
+ // Make sure there is enough room to store the new rpath and at
+ // least one null terminator.
+ if (rp[rp_count].Size < outRPath->length() + 1) {
+ if (emsg) {
+ *emsg = cmStrCat("The replacement path is too long for the ",
+ se_name[i], " entry.");
+ }
+ return false;
}
- return false;
- }
- // This entry is ready for update.
- ++rp_count;
+ // This entry is ready for update.
+ rp[rp_count].Value = std::move(*outRPath);
+ ++rp_count;
+ } else {
+ remove_rpath = false;
+ }
}
}
@@ -2706,6 +2669,81 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
}
return true;
}
+
+std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback(
+ const std::string& newRPath)
+{
+ return [newRPath](std::string* emsg, const cmELF& elf) -> bool {
+ if (newRPath.empty()) {
+ // The new rpath is empty and there is no rpath anyway so it is
+ // okay.
+ return true;
+ }
+ if (emsg) {
+ *emsg =
+ cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ",
+ elf.GetErrorMessage());
+ }
+ return false;
+ };
+};
+}
+
+bool cmSystemTools::ChangeRPath(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath, std::string* emsg,
+ bool* changed)
+{
+ auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath](
+ cm::optional<std::string>& outRPath,
+ const std::string& inRPath, const char* se_name,
+ std::string* emsg2) -> bool {
+ // Make sure the current rpath contains the old rpath.
+ std::string::size_type pos = cmSystemToolsFindRPath(inRPath, oldRPath);
+ if (pos == std::string::npos) {
+ // If it contains the new rpath instead then it is okay.
+ if (cmSystemToolsFindRPath(inRPath, newRPath) != std::string::npos) {
+ return true;
+ }
+ if (emsg2) {
+ std::ostringstream e;
+ /* clang-format off */
+ e << "The current " << se_name << " is:\n"
+ << " " << inRPath << "\n"
+ << "which does not contain:\n"
+ << " " << oldRPath << "\n"
+ << "as was expected.";
+ /* clang-format on */
+ *emsg2 = e.str();
+ }
+ return false;
+ }
+
+ std::string::size_type prefix_len = pos;
+
+ // If oldRPath was at the end of the file's RPath, and newRPath is empty,
+ // we should remove the unnecessary ':' at the end.
+ if (newRPath.empty() && pos > 0 && inRPath[pos - 1] == ':' &&
+ pos + oldRPath.length() == inRPath.length()) {
+ prefix_len--;
+ }
+
+ // Construct the new value which preserves the part of the path
+ // not being changed.
+ outRPath.emplace();
+ if (!removeEnvironmentRPath) {
+ *outRPath += inRPath.substr(0, prefix_len);
+ }
+ *outRPath += newRPath;
+ *outRPath += inRPath.substr(pos + oldRPath.length());
+
+ return true;
+ };
+
+ return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
+ changed);
+}
#elif defined(CMake_USE_XCOFF_PARSER)
bool cmSystemTools::ChangeRPath(std::string const& file,
std::string const& oldRPath,