summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-presets.7.rst16
-rw-r--r--Help/manual/presets/schema.json48
-rw-r--r--Source/cmCMakePresetsFile.cxx20
-rw-r--r--Source/cmCMakePresetsFileInternal.h10
-rw-r--r--Source/cmCMakePresetsFileReadJSON.cxx20
-rw-r--r--Tests/RunCMake/CMakePresets/Conditions.json.in57
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidRegex-result.txt1
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt2
-rw-r--r--Tests/RunCMake/CMakePresets/InvalidRegex.json.in15
-rw-r--r--Tests/RunCMake/CMakePresets/ListConditions-stdout.txt4
-rw-r--r--Tests/RunCMake/CMakePresets/RunCMakeTest.cmake1
11 files changed, 194 insertions, 0 deletions
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
index cc72603..8543be3 100644
--- a/Help/manual/cmake-presets.7.rst
+++ b/Help/manual/cmake-presets.7.rst
@@ -864,6 +864,22 @@ object, it has the following fields:
A required list of strings to search. This field supports macro
expansion, and uses short-circuit evaluation.
+ ``"matches"``
+
+ ``"notMatches"``
+
+ Indicates that the condition searches for a regular expression in a string.
+ The condition object will have the following additional fields:
+
+ ``string``
+
+ A required string to search. This field supports macro expansion.
+
+ ``regex``
+
+ A required regular expression to search for. This field supports macro
+ expansion.
+
``"anyOf"``
``"allOf"``
diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json
index c3c3ca1..9261519 100644
--- a/Help/manual/presets/schema.json
+++ b/Help/manual/presets/schema.json
@@ -1114,6 +1114,54 @@
"type": {
"type": "string",
"description": "A required string specifying the type of the condition.",
+ "const": "matches"
+ },
+ "string": {
+ "type": "string",
+ "description": "A required string to search. This field supports macro expansion."
+ },
+ "regex": {
+ "type": "string",
+ "description": "A required regular expression to search for. This field supports macro expansion."
+ }
+ },
+ "required": [
+ "type",
+ "string",
+ "regex"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "A required string specifying the type of the condition.",
+ "const": "notMatches"
+ },
+ "string": {
+ "type": "string",
+ "description": "A required string to search. This field supports macro expansion."
+ },
+ "regex": {
+ "type": "string",
+ "description": "A required regular expression to search for. This field supports macro expansion."
+ }
+ },
+ "required": [
+ "type",
+ "string",
+ "regex"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "description": "A required string specifying the type of the condition.",
"const": "anyOf"
},
"conditions": {
diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsFile.cxx
index fbe9fe5..d44dfb3 100644
--- a/Source/cmCMakePresetsFile.cxx
+++ b/Source/cmCMakePresetsFile.cxx
@@ -11,6 +11,8 @@
#include <cm/string_view>
+#include "cmsys/RegularExpression.hxx"
+
#include "cmCMakePresetsFileInternal.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -561,6 +563,24 @@ bool cmCMakePresetsFileInternal::InListCondition::Evaluate(
return true;
}
+bool cmCMakePresetsFileInternal::MatchesCondition::Evaluate(
+ const std::vector<MacroExpander>& expanders, int version,
+ cm::optional<bool>& out) const
+{
+ std::string str = this->String;
+ CHECK_EXPAND(out, str, expanders, version);
+ std::string regexStr = this->Regex;
+ CHECK_EXPAND(out, regexStr, expanders, version);
+
+ cmsys::RegularExpression regex;
+ if (!regex.compile(regexStr)) {
+ return false;
+ }
+
+ out = regex.find(str);
+ return true;
+}
+
bool cmCMakePresetsFileInternal::AnyAllOfCondition::Evaluate(
const std::vector<MacroExpander>& expanders, int version,
cm::optional<bool>& out) const
diff --git a/Source/cmCMakePresetsFileInternal.h b/Source/cmCMakePresetsFileInternal.h
index ffb6ce9..3269276 100644
--- a/Source/cmCMakePresetsFileInternal.h
+++ b/Source/cmCMakePresetsFileInternal.h
@@ -81,6 +81,16 @@ public:
std::vector<std::string> List;
};
+class MatchesCondition : public cmCMakePresetsFile::Condition
+{
+public:
+ bool Evaluate(const std::vector<MacroExpander>& expanders, int version,
+ cm::optional<bool>& out) const override;
+
+ std::string String;
+ std::string Regex;
+};
+
class AnyAllOfCondition : public cmCMakePresetsFile::Condition
{
public:
diff --git a/Source/cmCMakePresetsFileReadJSON.cxx b/Source/cmCMakePresetsFileReadJSON.cxx
index e26e7b4..403fac6 100644
--- a/Source/cmCMakePresetsFileReadJSON.cxx
+++ b/Source/cmCMakePresetsFileReadJSON.cxx
@@ -93,6 +93,16 @@ auto const InListConditionHelper =
.Bind("list"_s, &cmCMakePresetsFileInternal::InListCondition::List,
ConditionStringListHelper, true);
+auto const MatchesConditionHelper =
+ cmJSONObjectHelper<cmCMakePresetsFileInternal::MatchesCondition,
+ ReadFileResult>(ReadFileResult::READ_OK,
+ ReadFileResult::INVALID_CONDITION, false)
+ .Bind<std::string>("type"_s, nullptr, ConditionStringHelper, true)
+ .Bind("string"_s, &cmCMakePresetsFileInternal::MatchesCondition::String,
+ ConditionStringHelper, true)
+ .Bind("regex"_s, &cmCMakePresetsFileInternal::MatchesCondition::Regex,
+ ConditionStringHelper, true);
+
ReadFileResult SubConditionHelper(
std::unique_ptr<cmCMakePresetsFile::Condition>& out,
const Json::Value* value);
@@ -177,6 +187,16 @@ ReadFileResult ConditionHelper(
return ReadFileResult::READ_OK;
}
+ if (type == "matches" || type == "notMatches") {
+ auto c = cm::make_unique<cmCMakePresetsFileInternal::MatchesCondition>();
+ CHECK_OK(MatchesConditionHelper(*c, value));
+ out = std::move(c);
+ if (type == "notMatches") {
+ out = InvertCondition(std::move(out));
+ }
+ return ReadFileResult::READ_OK;
+ }
+
if (type == "anyOf" || type == "allOf") {
auto c =
cm::make_unique<cmCMakePresetsFileInternal::AnyAllOfCondition>();
diff --git a/Tests/RunCMake/CMakePresets/Conditions.json.in b/Tests/RunCMake/CMakePresets/Conditions.json.in
index 9a01e2f..9c0c6bd 100644
--- a/Tests/RunCMake/CMakePresets/Conditions.json.in
+++ b/Tests/RunCMake/CMakePresets/Conditions.json.in
@@ -181,6 +181,63 @@
}
},
{
+ "name": "MatchesTrue",
+ "inherits": "Base",
+ "condition": {
+ "type": "matches",
+ "string": "aaa",
+ "regex": "^a*$"
+ }
+ },
+ {
+ "name": "MatchesFalse",
+ "inherits": "Base",
+ "condition": {
+ "type": "matches",
+ "string": "aab",
+ "regex": "^a*$"
+ }
+ },
+ {
+ "name": "MatchesMacroString",
+ "inherits": "Base",
+ "condition": {
+ "type": "matches",
+ "string": "${presetName}",
+ "regex": "^Matches"
+ }
+ },
+ {
+ "name": "MatchesMacroRegex",
+ "inherits": "Base",
+ "condition": {
+ "type": "matches",
+ "string": "stuff",
+ "regex": "$env{CONDITION_REGEX}"
+ },
+ "environment": {
+ "CONDITION_REGEX": "^stuf*$"
+ }
+ },
+ {
+ "name": "NotMatchesTrue",
+ "inherits": "Base",
+ "condition": {
+ "type": "notMatches",
+ "string": "aab",
+ "regex": "^a*$"
+ }
+ },
+ {
+ "name": "NotMatchesFalse",
+ "inherits": "Base",
+ "condition": {
+ "type": "notMatches",
+ "string": "aaa",
+ "regex": "^a*$"
+ }
+ },
+ {
"name": "AnyOfTrue1",
"inherits": "Base",
"condition": {
diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex-result.txt b/Tests/RunCMake/CMakePresets/InvalidRegex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/InvalidRegex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt b/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt
new file mode 100644
index 0000000..5b500e4
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/InvalidRegex-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/InvalidRegex: Invalid macro expansion$
diff --git a/Tests/RunCMake/CMakePresets/InvalidRegex.json.in b/Tests/RunCMake/CMakePresets/InvalidRegex.json.in
new file mode 100644
index 0000000..69114d2
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/InvalidRegex.json.in
@@ -0,0 +1,15 @@
+{
+ "version": 3,
+ "configurePresets": [
+ {
+ "name": "InvalidRegex",
+ "binaryDir": "${sourceDir}/build",
+ "generator": "@RunCMake_GENERATOR@",
+ "condition": {
+ "type": "matches",
+ "string": "a",
+ "regex": "+"
+ }
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt b/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt
index 19f91d4..91e0017 100644
--- a/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt
+++ b/Tests/RunCMake/CMakePresets/ListConditions-stdout.txt
@@ -12,6 +12,10 @@ Available configure presets:
"InListMacroList"
"InListShortCircuit"
"NotInListTrue"
+ "MatchesTrue"
+ "MatchesMacroString"
+ "MatchesMacroRegex"
+ "NotMatchesTrue"
"AnyOfTrue1"
"AnyOfTrue2"
"AnyOfShortCircuit"
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
index 22425b2..9523430 100644
--- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -117,6 +117,7 @@ run_cmake_presets(NoSuchMacro)
run_cmake_presets(EnvCycle)
run_cmake_presets(EmptyEnv)
run_cmake_presets(EmptyPenv)
+run_cmake_presets(InvalidRegex)
set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
run_cmake_presets(ConditionFuture)
run_cmake_presets(SubConditionNull)