summaryrefslogtreecommitdiffstats
path: root/Source/cmFindBase.cxx
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2022-06-11 14:25:45 (GMT)
committerBrad King <brad.king@kitware.com>2022-06-14 20:17:46 (GMT)
commitf3b5a7d6df02d5c714a848e9709c563b9555af71 (patch)
treebb0aeb6168fd43afaaaa64df4fb70f7d5233e8d9 /Source/cmFindBase.cxx
parentb78624fd29b91f748f3edcdaeea997a52691b647 (diff)
downloadCMake-f3b5a7d6df02d5c714a848e9709c563b9555af71.zip
CMake-f3b5a7d6df02d5c714a848e9709c563b9555af71.tar.gz
CMake-f3b5a7d6df02d5c714a848e9709c563b9555af71.tar.bz2
find_(program,library,file,path): add validation function
Fixes: #23603
Diffstat (limited to 'Source/cmFindBase.cxx')
-rw-r--r--Source/cmFindBase.cxx62
1 files changed, 60 insertions, 2 deletions
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 4dfbef9..91efc66 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -2,15 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindBase.h"
+#include <algorithm>
#include <cstddef>
#include <deque>
+#include <functional>
#include <map>
#include <utility>
#include <cm/optional>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmCMakePath.h"
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -24,8 +29,6 @@
#include "cmWindowsRegistry.h"
#include "cmake.h"
-class cmExecutionStatus;
-
cmFindBase::cmFindBase(std::string findCommandName, cmExecutionStatus& status)
: cmFindCommon(status)
, FindCommandName(std::move(findCommandName))
@@ -138,6 +141,31 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[j]));
return false;
}
+ } else if (args[j] == "VALIDATOR") {
+ if (++j == args.size()) {
+ this->SetError("missing required argument for \"VALIDATOR\"");
+ return false;
+ }
+ auto command = this->Makefile->GetState()->GetCommand(args[j]);
+ if (command == nullptr) {
+ this->SetError(cmStrCat(
+ "command specified for \"VALIDATOR\" is undefined: ", args[j], '.'));
+ return false;
+ }
+ // ensure a macro is not specified as validator
+ const auto& validatorName = args[j];
+ auto macros = cmExpandedList(this->Makefile->GetProperty("MACROS"));
+ if (std::find_if(macros.begin(), macros.end(),
+ [&validatorName](const std::string& item) {
+ return cmSystemTools::Strucmp(validatorName.c_str(),
+ item.c_str()) == 0;
+ }) != macros.end()) {
+ this->SetError(cmStrCat(
+ "command specified for \"VALIDATOR\" is not a function: ", args[j],
+ '.'));
+ return false;
+ }
+ this->ValidatorName = args[j];
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
} else {
@@ -188,6 +216,36 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
return true;
}
+bool cmFindBase::Validate(const std::string& path) const
+{
+ if (this->ValidatorName.empty()) {
+ return true;
+ }
+
+ // The validator command will be executed in an isolated scope.
+ cmMakefile::ScopePushPop varScope(this->Makefile);
+ cmMakefile::PolicyPushPop polScope(this->Makefile);
+ static_cast<void>(varScope);
+ static_cast<void>(polScope);
+
+ auto resultName =
+ cmStrCat("CMAKE_"_s, cmSystemTools::UpperCase(this->FindCommandName),
+ "_VALIDATOR_STATUS"_s);
+
+ this->Makefile->AddDefinitionBool(resultName, true);
+
+ cmListFileFunction validator(
+ this->ValidatorName, 0, 0,
+ { cmListFileArgument(resultName, cmListFileArgument::Unquoted, 0),
+ cmListFileArgument(path, cmListFileArgument::Quoted, 0) });
+ cmExecutionStatus status(*this->Makefile);
+
+ if (this->Makefile->ExecuteCommand(validator, status)) {
+ return this->Makefile->GetDefinition(resultName).IsOn();
+ }
+ return false;
+}
+
void cmFindBase::ExpandPaths()
{
if (!this->NoDefaultPath) {