diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-05-04 20:21:21 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-06-04 12:52:01 (GMT) |
commit | 966f7250df01df7982aa6ff4117464d797b6bf10 (patch) | |
tree | 7d19419beeed67dddecb440caaed4032bfc30f7d /Source/cmSystemTools.cxx | |
parent | 2ef3ea394f424bf2397878b00725b93ebe04c589 (diff) | |
download | CMake-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.cxx | 178 |
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, |