This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, master has been updated
via 18b0329a8165c92cf94b5b97c2425df090c877f0 (commit)
via 5228432b45b7ce740b93f2c80c8c7ce6987d4bf1 (commit)
via 8e746db6e11f9e017cd04552efaf40235d50363d (commit)
from 89ca5d7fdce7730f38a719683059bbe02e6fb19d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=18b0329a8165c92cf94b5b97c2425df090c877f0
commit 18b0329a8165c92cf94b5b97c2425df090c877f0
Merge: 89ca5d7 5228432
Author: Kyle Edwards <[email protected]>
AuthorDate: Fri Feb 8 17:14:36 2019 +0000
Commit: Kitware Robot <[email protected]>
CommitDate: Fri Feb 8 12:14:46 2019 -0500
Merge topic 'cmake_parse_arguments-keywords_missing_values'
5228432b45 cmake_parse_arguments: add KEYWORDS_MISSING_VALUES
8e746db6e1 cmake_parse_arguments: Factor out part of implementation for
re-use
Acked-by: Kitware Robot <[email protected]>
Merge-request: !2910
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5228432b45b7ce740b93f2c80c8c7ce6987d4bf1
commit 5228432b45b7ce740b93f2c80c8c7ce6987d4bf1
Author: Torsten Robitzki <[email protected]>
AuthorDate: Mon Feb 4 20:39:25 2019 +0100
Commit: Kyle Edwards <[email protected]>
CommitDate: Thu Feb 7 12:59:10 2019 -0500
cmake_parse_arguments: add KEYWORDS_MISSING_VALUES
Add KEYWORDS_MISSING_VALUES output variable to cmake_parse_arguments() to
allow to detect keywords that received no values.
Fixes: #18706
diff --git a/Help/command/cmake_parse_arguments.rst
b/Help/command/cmake_parse_arguments.rst
index c8327e2..196d90f 100644
--- a/Help/command/cmake_parse_arguments.rst
+++ b/Help/command/cmake_parse_arguments.rst
@@ -59,6 +59,11 @@ All remaining arguments are collected in a variable
where recognized. This can be checked afterwards to see
whether your macro was called with unrecognized parameters.
+``<one_value_keywords>`` and ``<multi_value_keywords>`` that where given no
+values at all are collected in a variable ``<prefix>_KEYWORDS_MISSING_VALUES``
+that will be undefined if all keywords received values. This can be checked
+to see if there where keywords without any values given.
+
As an example here a ``my_install()`` macro, which takes similar arguments
as the real :command:`install` command:
@@ -77,7 +82,7 @@ Assume ``my_install()`` has been called like this:
.. code-block:: cmake
- my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
+ my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub CONFIGURATIONS)
After the ``cmake_parse_arguments`` call the macro will have set or undefined
the following variables::
@@ -89,6 +94,8 @@ the following variables::
MY_INSTALL_TARGETS = "foo;bar"
MY_INSTALL_CONFIGURATIONS <UNDEFINED> # was not used
MY_INSTALL_UNPARSED_ARGUMENTS = "blub" # nothing expected after "OPTIONAL"
+ MY_INSTALL_KEYWORDS_MISSING_VALUES = "CONFIGURATIONS"
+ # No value for "CONFIGURATIONS" given
You can then continue and process these variables.
@@ -97,5 +104,6 @@ one_value_keyword another recognized keyword follows, this is
interpreted as the beginning of the new option. E.g.
``my_install(TARGETS foo DESTINATION OPTIONAL)`` would result in
``MY_INSTALL_DESTINATION`` set to ``"OPTIONAL"``, but as ``OPTIONAL``
-is a keyword itself ``MY_INSTALL_DESTINATION`` will be empty and
-``MY_INSTALL_OPTIONAL`` will therefore be set to ``TRUE``.
+is a keyword itself ``MY_INSTALL_DESTINATION`` will be empty (but added
+to ``MY_INSTALL_KEYWORDS_MISSING_VALUES``) and ``MY_INSTALL_OPTIONAL`` will
+therefore be set to ``TRUE``.
diff --git a/Help/release/dev/cmake_parse_arguments-keywords_missing_values.rst
b/Help/release/dev/cmake_parse_arguments-keywords_missing_values.rst
new file mode 100644
index 0000000..c7fe96b
--- /dev/null
+++ b/Help/release/dev/cmake_parse_arguments-keywords_missing_values.rst
@@ -0,0 +1,6 @@
+cmake_parse_arguments-keywords_missing_values
+---------------------------------------------
+
+* The :command:`cmake_parse_arguments` command gained an additional
+ ``<prefix>_KEYWORDS_MISSING_VALUES`` output variable to report
+ keyword arguments that were given by the caller with no values.
diff --git a/Source/cmParseArgumentsCommand.cxx
b/Source/cmParseArgumentsCommand.cxx
index cef0704..6231aab 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -14,7 +14,7 @@
class cmExecutionStatus;
-static std::string escape_arg(const std::string& arg)
+static std::string EscapeArg(const std::string& arg)
{
// replace ";" with "\;" so output argument lists will split correctly
std::string escapedArg;
@@ -28,7 +28,7 @@ static std::string escape_arg(const std::string& arg)
}
namespace {
-enum InsideValues
+enum insideValues
{
NONE,
SINGLE,
@@ -38,6 +38,22 @@ enum InsideValues
typedef std::map<std::string, bool> options_map;
typedef std::map<std::string, std::string> single_map;
typedef std::map<std::string, std::vector<std::string>> multi_map;
+typedef std::set<std::string> options_set;
+}
+
+// function to be called every time, a new key word was parsed or all
+// parameters where parsed.
+static void DetectKeywordsMissingValues(insideValues currentState,
+ const std::string& currentArgName,
+ int& argumentsFound,
+ options_set& keywordsMissingValues)
+{
+ if (currentState == SINGLE ||
+ (currentState == MULTI && argumentsFound == 0)) {
+ keywordsMissingValues.insert(currentArgName);
+ }
+
+ argumentsFound = 0;
}
static void PassParsedArguments(const std::string& prefix,
@@ -45,7 +61,8 @@ static void PassParsedArguments(const std::string& prefix,
const options_map& options,
const single_map& singleValArgs,
const multi_map& multiValArgs,
- const std::vector<std::string>& unparsed)
+ const std::vector<std::string>& unparsed,
+ const options_set& keywordsMissingValues)
{
for (auto const& iter : options) {
makefile.AddDefinition(prefix + iter.first,
@@ -75,6 +92,14 @@ static void PassParsedArguments(const std::string& prefix,
} else {
makefile.RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
}
+
+ if (!keywordsMissingValues.empty()) {
+ makefile.AddDefinition(
+ prefix + "KEYWORDS_MISSING_VALUES",
+ cmJoin(cmMakeRange(keywordsMissingValues), ";").c_str());
+ } else {
+ makefile.RemoveDefinition(prefix + "KEYWORDS_MISSING_VALUES");
+ }
}
bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
@@ -161,7 +186,7 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
multiValArgs[iter]; // default initialize
}
- InsideValues insideValues = NONE;
+ insideValues insideValues = NONE;
std::string currentArgName;
list.clear();
@@ -197,10 +222,15 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
}
}
+ options_set keywordsMissingValues;
+ int multiArgumentsFound = 0;
+
// iterate over the arguments list and fill in the values where applicable
for (std::string const& arg : list) {
const options_map::iterator optIter = options.find(arg);
if (optIter != options.end()) {
+ DetectKeywordsMissingValues(insideValues, currentArgName,
+ multiArgumentsFound, keywordsMissingValues);
insideValues = NONE;
optIter->second = true;
continue;
@@ -208,6 +238,8 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
const single_map::iterator singleIter = singleValArgs.find(arg);
if (singleIter != singleValArgs.end()) {
+ DetectKeywordsMissingValues(insideValues, currentArgName,
+ multiArgumentsFound, keywordsMissingValues);
insideValues = SINGLE;
currentArgName = arg;
continue;
@@ -215,6 +247,8 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
const multi_map::iterator multiIter = multiValArgs.find(arg);
if (multiIter != multiValArgs.end()) {
+ DetectKeywordsMissingValues(insideValues, currentArgName,
+ multiArgumentsFound, keywordsMissingValues);
insideValues = MULTI;
currentArgName = arg;
continue;
@@ -226,15 +260,18 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
insideValues = NONE;
break;
case MULTI:
+ ++multiArgumentsFound;
if (parseFromArgV) {
- multiValArgs[currentArgName].push_back(escape_arg(arg));
+ multiValArgs[currentArgName].push_back(EscapeArg(arg));
} else {
multiValArgs[currentArgName].push_back(arg);
}
break;
default:
+ multiArgumentsFound = 0;
+
if (parseFromArgV) {
- unparsed.push_back(escape_arg(arg));
+ unparsed.push_back(EscapeArg(arg));
} else {
unparsed.push_back(arg);
}
@@ -242,8 +279,11 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
}
}
+ DetectKeywordsMissingValues(insideValues, currentArgName,
+ multiArgumentsFound, keywordsMissingValues);
+
PassParsedArguments(prefix, *this->Makefile, options, singleValArgs,
- multiValArgs, unparsed);
+ multiValArgs, unparsed, keywordsMissingValues);
return true;
}
diff --git a/Tests/RunCMake/cmake_parse_arguments/KeyWordsMissingValues.cmake
b/Tests/RunCMake/cmake_parse_arguments/KeyWordsMissingValues.cmake
new file mode 100644
index 0000000..561f9c0
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/KeyWordsMissingValues.cmake
@@ -0,0 +1,133 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# No keywords that miss any values, _KEYWORDS_MISSING_VALUES should not be
defined
+cmake_parse_arguments(PREF "" "P1" "P2" P1 p1 P2 p2_a p2_b)
+
+TEST(PREF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+
+# Keyword should even be deleted from the actual scope
+set(PREF_KEYWORDS_MISSING_VALUES "What ever")
+cmake_parse_arguments(PREF "" "" "")
+
+TEST(PREF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+
+# Given missing keywords as only option
+cmake_parse_arguments(PREF "" "P1" "P2" P1)
+
+TEST(PREF_KEYWORDS_MISSING_VALUES "P1")
+TEST(PREF_P1 "UNDEFINED")
+TEST(PREF_UNPARSED_ARGUMENTS "UNDEFINED")
+
+# Mixed with unparsed arguments
+cmake_parse_arguments(UPREF "" "P1" "P2" A B P2 C P1)
+TEST(UPREF_KEYWORDS_MISSING_VALUES "P1")
+TEST(UPREF_UNPARSED_ARGUMENTS A B)
+
+# one_value_keyword followed by option
+cmake_parse_arguments(REF "OP" "P1" "" P1 OP)
+TEST(REF_KEYWORDS_MISSING_VALUES "P1")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_OP "TRUE")
+
+# Counter Test
+cmake_parse_arguments(REF "OP" "P1" "" P1 p1 OP)
+TEST(REF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+TEST(REF_P1 "p1")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_OP "TRUE")
+
+# one_value_keyword followed by a one_value_keyword
+cmake_parse_arguments(REF "" "P1;P2" "" P1 P2 p2)
+TEST(REF_KEYWORDS_MISSING_VALUES "P1")
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 "p2")
+
+# Counter Test
+cmake_parse_arguments(REF "" "P1;P2" "" P1 p1 P2 p2)
+TEST(REF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+TEST(REF_P1 "p1")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 "p2")
+
+# one_value_keyword followed by a multi_value_keywords
+cmake_parse_arguments(REF "" "P1" "P2" P1 P2 p1 p2)
+TEST(REF_KEYWORDS_MISSING_VALUES "P1")
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 p1 p2)
+
+# Counter Examples
+cmake_parse_arguments(REF "" "P1" "P2" P1 p1 P2 p1 p2)
+TEST(REF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+TEST(REF_P1 "p1")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 p1 p2)
+
+# multi_value_keywords as only option
+cmake_parse_arguments(REF "" "P1" "P2" P2)
+TEST(REF_KEYWORDS_MISSING_VALUES "P2")
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 "UNDEFINED")
+
+# multi_value_keywords followed by option
+cmake_parse_arguments(REF "O1" "" "P1" P1 O1)
+TEST(REF_KEYWORDS_MISSING_VALUES "P1")
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_O1 "TRUE")
+
+# counter test
+cmake_parse_arguments(REF "O1" "" "P1" P1 p1 p2 O1)
+TEST(REF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+TEST(REF_P1 "p1;p2")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_O1 "TRUE")
+
+# multi_value_keywords followed by one_value_keyword
+cmake_parse_arguments(REF "" "P1" "P2" P2 P1 p1)
+TEST(REF_KEYWORDS_MISSING_VALUES "P2")
+TEST(REF_P1 "p1")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 "UNDEFINED")
+
+# counter test
+cmake_parse_arguments(REF "" "P1" "P2" P2 p2 P1 p1)
+TEST(REF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+TEST(REF_P1 "p1")
+TEST(REF_UNPARSED_ARGUMENTS "UNDEFINED")
+TEST(REF_P2 "p2")
+
+# one_value_keyword as last argument
+cmake_parse_arguments(REF "" "P1" "P2" A P2 p2 P1)
+TEST(REF_KEYWORDS_MISSING_VALUES "P1")
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_UNPARSED_ARGUMENTS "A")
+TEST(REF_P2 "p2")
+
+# multi_value_keywords as last argument
+cmake_parse_arguments(REF "" "P1" "P2" P1 p1 P2)
+TEST(REF_KEYWORDS_MISSING_VALUES "P2")
+TEST(REF_P1 "p1")
+TEST(REF_P2 "UNDEFINED")
+
+# Multiple one_value_keyword and multi_value_keywords at different places
+cmake_parse_arguments(REF "O1;O2" "P1" "P2" P1 O1 P2 O2)
+TEST(REF_KEYWORDS_MISSING_VALUES P1 P2)
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_P2 "UNDEFINED")
+
+# Duplicated missing keywords
+cmake_parse_arguments(REF "O1;O2" "P1" "P2" P1 O1 P2 O2 P1 P2)
+TEST(REF_KEYWORDS_MISSING_VALUES P1 P2)
+TEST(REF_P1 "UNDEFINED")
+TEST(REF_P2 "UNDEFINED")
+
+# make sure keywords that are never used, don't get added to
KEYWORDS_MISSING_VALUES
+cmake_parse_arguments(REF "O1;O2" "P1" "P2")
+TEST(REF_KEYWORDS_MISSING_VALUES "UNDEFINED")
+TEST(REF_O1 FALSE)
+TEST(REF_O2 FALSE)
+TEST(REF_P1 UNDEFINED)
+TEST(REF_P2 UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
index 1e15b3b..505840d 100644
--- a/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
@@ -11,3 +11,4 @@ run_cmake(BadArgvN2)
run_cmake(BadArgvN3)
run_cmake(BadArgvN4)
run_cmake(CornerCasesArgvN)
+run_cmake(KeyWordsMissingValues)
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8e746db6e11f9e017cd04552efaf40235d50363d
commit 8e746db6e11f9e017cd04552efaf40235d50363d
Author: Torsten Robitzki <[email protected]>
AuthorDate: Mon Feb 4 20:29:41 2019 +0100
Commit: Brad King <[email protected]>
CommitDate: Wed Feb 6 14:46:52 2019 -0500
cmake_parse_arguments: Factor out part of implementation for re-use
diff --git a/Source/cmParseArgumentsCommand.cxx
b/Source/cmParseArgumentsCommand.cxx
index 796974c..cef0704 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -27,6 +27,56 @@ static std::string escape_arg(const std::string& arg)
return escapedArg;
}
+namespace {
+enum InsideValues
+{
+ NONE,
+ SINGLE,
+ MULTI
+};
+
+typedef std::map<std::string, bool> options_map;
+typedef std::map<std::string, std::string> single_map;
+typedef std::map<std::string, std::vector<std::string>> multi_map;
+}
+
+static void PassParsedArguments(const std::string& prefix,
+ cmMakefile& makefile,
+ const options_map& options,
+ const single_map& singleValArgs,
+ const multi_map& multiValArgs,
+ const std::vector<std::string>& unparsed)
+{
+ for (auto const& iter : options) {
+ makefile.AddDefinition(prefix + iter.first,
+ iter.second ? "TRUE" : "FALSE");
+ }
+
+ for (auto const& iter : singleValArgs) {
+ if (!iter.second.empty()) {
+ makefile.AddDefinition(prefix + iter.first, iter.second.c_str());
+ } else {
+ makefile.RemoveDefinition(prefix + iter.first);
+ }
+ }
+
+ for (auto const& iter : multiValArgs) {
+ if (!iter.second.empty()) {
+ makefile.AddDefinition(prefix + iter.first,
+ cmJoin(cmMakeRange(iter.second), ";").c_str());
+ } else {
+ makefile.RemoveDefinition(prefix + iter.first);
+ }
+ }
+
+ if (!unparsed.empty()) {
+ makefile.AddDefinition(prefix + "UNPARSED_ARGUMENTS",
+ cmJoin(cmMakeRange(unparsed), ";").c_str());
+ } else {
+ makefile.RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
+ }
+}
+
bool cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
{
@@ -67,9 +117,6 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
// define the result maps holding key/value pairs for
// options, single values and multi values
- typedef std::map<std::string, bool> options_map;
- typedef std::map<std::string, std::string> single_map;
- typedef std::map<std::string, std::vector<std::string>> multi_map;
options_map options;
single_map singleValArgs;
multi_map multiValArgs;
@@ -114,12 +161,7 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
multiValArgs[iter]; // default initialize
}
- enum insideValues
- {
- NONE,
- SINGLE,
- MULTI
- } insideValues = NONE;
+ InsideValues insideValues = NONE;
std::string currentArgName;
list.clear();
@@ -200,36 +242,8 @@ bool
cmParseArgumentsCommand::InitialPass(std::vector<std::string> const& args,
}
}
- // now iterate over the collected values and update their definition
- // within the current scope. undefine if necessary.
-
- for (auto const& iter : options) {
- this->Makefile->AddDefinition(prefix + iter.first,
- iter.second ? "TRUE" : "FALSE");
- }
- for (auto const& iter : singleValArgs) {
- if (!iter.second.empty()) {
- this->Makefile->AddDefinition(prefix + iter.first, iter.second.c_str());
- } else {
- this->Makefile->RemoveDefinition(prefix + iter.first);
- }
- }
-
- for (auto const& iter : multiValArgs) {
- if (!iter.second.empty()) {
- this->Makefile->AddDefinition(
- prefix + iter.first, cmJoin(cmMakeRange(iter.second), ";").c_str());
- } else {
- this->Makefile->RemoveDefinition(prefix + iter.first);
- }
- }
-
- if (!unparsed.empty()) {
- this->Makefile->AddDefinition(prefix + "UNPARSED_ARGUMENTS",
- cmJoin(cmMakeRange(unparsed), ";").c_str());
- } else {
- this->Makefile->RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
- }
+ PassParsedArguments(prefix, *this->Makefile, options, singleValArgs,
+ multiValArgs, unparsed);
return true;
}
-----------------------------------------------------------------------
Summary of changes:
Help/command/cmake_parse_arguments.rst | 14 ++-
...ake_parse_arguments-keywords_missing_values.rst | 6 +
Source/cmParseArgumentsCommand.cxx | 136 ++++++++++++++-------
.../KeyWordsMissingValues.cmake | 133 ++++++++++++++++++++
.../cmake_parse_arguments/RunCMakeTest.cmake | 1 +
5 files changed, 246 insertions(+), 44 deletions(-)
create mode 100644
Help/release/dev/cmake_parse_arguments-keywords_missing_values.rst
create mode 100644
Tests/RunCMake/cmake_parse_arguments/KeyWordsMissingValues.cmake
hooks/post-receive
--
CMake
_______________________________________________
Cmake-commits mailing list
[email protected]
https://cmake.org/mailman/listinfo/cmake-commits