[Cmake-commits] CMake branch, next, updated. v3.4.1-1763-gf07caa4
Brad King
brad.king at kitware.com
Thu Dec 17 10:45:30 EST 2015
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, next has been updated
via f07caa4874144ecb7701df41bb1c2e7ef754f16d (commit)
via ab8a280857da5cf8545bd2a6f69b7378f53449a5 (commit)
via e8b148318f1fab26b2289cadc2d0c5e12201169d (commit)
via cbbdfc2b6120e192b4248ce89af93cf34ea8a254 (commit)
from deef02dd4b919d85f636eecd8dca09500ee322c4 (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=f07caa4874144ecb7701df41bb1c2e7ef754f16d
commit f07caa4874144ecb7701df41bb1c2e7ef754f16d
Merge: deef02d ab8a280
Author: Brad King <brad.king at kitware.com>
AuthorDate: Thu Dec 17 10:45:28 2015 -0500
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Dec 17 10:45:28 2015 -0500
Merge topic 'CMakeParseArguments-native-impl' into next
ab8a2808 cmake_parse_arguments: consider duplicate keyword as warning
e8b14831 CMakeParseArguments: replace by native cmake_parse_arguments command
cbbdfc2b CMakeParseArguments: add a RunCMake test suite
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ab8a280857da5cf8545bd2a6f69b7378f53449a5
commit ab8a280857da5cf8545bd2a6f69b7378f53449a5
Author: Matthias Maennich <matthias at maennich.net>
AuthorDate: Sat Dec 5 19:02:19 2015 +0100
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Dec 17 10:45:19 2015 -0500
cmake_parse_arguments: consider duplicate keyword as warning
The behaviour of double specified keywords is rather undefined or at
least not clearly documented. This change introduces a strict check and
emits a warning in case a keyword has been specified more than once.
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
index 7638b61..6206611 100644
--- a/Help/command/cmake_parse_arguments.rst
+++ b/Help/command/cmake_parse_arguments.rst
@@ -25,6 +25,13 @@ The ``<multi_value_keywords>`` argument contains all keywords for this
macro which can be followed by more than one value, like e.g. the
``TARGETS`` or ``FILES`` keywords of the :command:`install` command.
+.. note::
+
+ All keywords shall be unique. I.e. every keyword shall only be specified
+ once in either ``<options>``, ``<one_value_keywords>`` or
+ ``<multi_value_keywords>``. A warning will be emitted if uniqueness is
+ violated.
+
When done, ``cmake_parse_arguments`` will have defined for each of the
keywords listed in ``<options>``, ``<one_value_keywords>`` and
``<multi_value_keywords>`` a variable composed of the given ``<prefix>``
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index ce7a7b3..a861965 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -43,6 +43,10 @@ bool cmParseArgumentsCommand
// anything else is put into a vector of unparsed strings
std::vector<std::string> unparsed;
+ // remember already defined keywords
+ std::set<std::string> used_keywords;
+ const std::string dup_warning = "keyword defined more than once: ";
+
// the second argument is a (cmake) list of options without argument
std::vector<std::string> list;
cmSystemTools::ExpandListArgument(*argIter++, list);
@@ -50,6 +54,10 @@ bool cmParseArgumentsCommand
end = list.end();
iter != end; ++iter)
{
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
options[*iter]; // default initialize
}
@@ -60,6 +68,10 @@ bool cmParseArgumentsCommand
end = list.end();
iter != end; ++iter)
{
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
single[*iter]; // default initialize
}
@@ -70,6 +82,10 @@ bool cmParseArgumentsCommand
end = list.end();
iter != end; ++iter)
{
+ if (!used_keywords.insert(*iter).second)
+ {
+ this->GetMakefile()->IssueMessage(cmake::WARNING, dup_warning + *iter);
+ }
multi[*iter]; // default initialize
}
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
index 5394eaf..f2ba9b8 100644
--- a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
@@ -1,14 +1,44 @@
-CMake Error at Errors\.cmake:1 \(cmake_parse_arguments\):
+CMake Error at Errors\.cmake:2 \(cmake_parse_arguments\):
cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
-CMake Error at Errors\.cmake:2 \(cmake_parse_arguments\):
+CMake Error at Errors\.cmake:3 \(cmake_parse_arguments\):
cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
+
-CMake Error at Errors\.cmake:3 \(cmake_parse_arguments\):
+CMake Error at Errors\.cmake:4 \(cmake_parse_arguments\):
cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:8 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:9 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:10 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:12 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:13 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
++
+CMake Warning at Errors\.cmake:14 \(cmake_parse_arguments\):
+ keyword defined more than once: OPT
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
index 98e22e9..6a38081 100644
--- a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
@@ -1,4 +1,14 @@
+# wrong argument count
cmake_parse_arguments()
cmake_parse_arguments(prefix OPT)
cmake_parse_arguments(prefix OPT SINGLE)
cmake_parse_arguments(prefix OPT SINGLE MULTI) # not an error
+
+# duplicate keywords
+cmake_parse_arguments(prefix "OPT;OPT" "" "")
+cmake_parse_arguments(prefix "" "OPT;OPT" "")
+cmake_parse_arguments(prefix "" "" "OPT;OPT")
+
+cmake_parse_arguments(prefix "OPT" "OPT" "")
+cmake_parse_arguments(prefix "" "OPT" "OPT")
+cmake_parse_arguments(prefix "OPT" "" "OPT")
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e8b148318f1fab26b2289cadc2d0c5e12201169d
commit e8b148318f1fab26b2289cadc2d0c5e12201169d
Author: Matthias Maennich <matthias at maennich.net>
AuthorDate: Sat Dec 5 19:01:12 2015 +0100
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Dec 17 10:44:28 2015 -0500
CMakeParseArguments: replace by native cmake_parse_arguments command
Implement a native `cmake_parse_arguments` command that is fully
compatible with the documented behaviour of the previous implementation.
Leave the CMakeParseArguments module empty but existing for
compatibility.
diff --git a/Help/command/cmake_parse_arguments.rst b/Help/command/cmake_parse_arguments.rst
new file mode 100644
index 0000000..7638b61
--- /dev/null
+++ b/Help/command/cmake_parse_arguments.rst
@@ -0,0 +1,78 @@
+cmake_parse_arguments
+---------------------
+
+``cmake_parse_arguments`` is intended to be used in macros or functions for
+parsing the arguments given to that macro or function. It processes the
+arguments and defines a set of variables which hold the values of the
+respective options.
+
+::
+
+ cmake_parse_arguments(<prefix> <options> <one_value_keywords>
+ <multi_value_keywords> args...)
+
+
+The ``<options>`` argument contains all options for the respective macro,
+i.e. keywords which can be used when calling the macro without any value
+following, like e.g. the ``OPTIONAL`` keyword of the :command:`install`
+command.
+
+The ``<one_value_keywords>`` argument contains all keywords for this macro
+which are followed by one value, like e.g. ``DESTINATION`` keyword of the
+:command:`install` command.
+
+The ``<multi_value_keywords>`` argument contains all keywords for this
+macro which can be followed by more than one value, like e.g. the
+``TARGETS`` or ``FILES`` keywords of the :command:`install` command.
+
+When done, ``cmake_parse_arguments`` will have defined for each of the
+keywords listed in ``<options>``, ``<one_value_keywords>`` and
+``<multi_value_keywords>`` a variable composed of the given ``<prefix>``
+followed by ``"_"`` and the name of the respective keyword. These
+variables will then hold the respective value from the argument list.
+For the ``<options>`` keywords this will be ``TRUE`` or ``FALSE``.
+
+All remaining arguments are collected in a variable
+``<prefix>_UNPARSED_ARGUMENTS``, this can be checked afterwards to see
+whether your macro was called with unrecognized parameters.
+
+As an example here a ``my_install()`` macro, which takes similar arguments
+as the real :command:`install` command:
+
+.. code-block:: cmake
+
+ function(MY_INSTALL)
+ set(options OPTIONAL FAST)
+ set(oneValueArgs DESTINATION RENAME)
+ set(multiValueArgs TARGETS CONFIGURATIONS)
+ cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
+ "${multiValueArgs}" ${ARGN} )
+
+ # ...
+
+Assume ``my_install()`` has been called like this:
+
+.. code-block:: cmake
+
+ my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
+
+After the ``cmake_parse_arguments`` call the macro will have set the
+following variables::
+
+ MY_INSTALL_OPTIONAL = TRUE
+ MY_INSTALL_FAST = FALSE (was not used in call to my_install)
+ MY_INSTALL_DESTINATION = "bin"
+ MY_INSTALL_RENAME = "" (was not used)
+ MY_INSTALL_TARGETS = "foo;bar"
+ MY_INSTALL_CONFIGURATIONS = "" (was not used)
+ MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (nothing expected after "OPTIONAL")
+
+You can then continue and process these variables.
+
+Keywords terminate lists of values, e.g. if directly after a
+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``.
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 5b92b51..d0c2986 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -29,6 +29,7 @@ These commands may be used freely in CMake projects.
/command/build_command
/command/cmake_host_system_information
/command/cmake_minimum_required
+ /command/cmake_parse_arguments
/command/cmake_policy
/command/configure_file
/command/continue
diff --git a/Help/release/dev/CMakeParseArguments-native-impl.rst b/Help/release/dev/CMakeParseArguments-native-impl.rst
new file mode 100644
index 0000000..114a099
--- /dev/null
+++ b/Help/release/dev/CMakeParseArguments-native-impl.rst
@@ -0,0 +1,6 @@
+CMakeParseArguments-native-impl
+-------------------------------
+
+* The :command:`cmake_parse_arguments` command is now implemented natively.
+ The :module:`CMakeParseArguments` module remains as an empty placeholder
+ for compatibility.
diff --git a/Modules/CMakeParseArguments.cmake b/Modules/CMakeParseArguments.cmake
index 8553f38..fc64ab9 100644
--- a/Modules/CMakeParseArguments.cmake
+++ b/Modules/CMakeParseArguments.cmake
@@ -2,86 +2,10 @@
# CMakeParseArguments
# -------------------
#
-#
-#
-# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords>
-# <multi_value_keywords> args...)
-#
-# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions
-# for parsing the arguments given to that macro or function. It
-# processes the arguments and defines a set of variables which hold the
-# values of the respective options.
-#
-# The <options> argument contains all options for the respective macro,
-# i.e. keywords which can be used when calling the macro without any
-# value following, like e.g. the OPTIONAL keyword of the install()
-# command.
-#
-# The <one_value_keywords> argument contains all keywords for this macro
-# which are followed by one value, like e.g. DESTINATION keyword of the
-# install() command.
-#
-# The <multi_value_keywords> argument contains all keywords for this
-# macro which can be followed by more than one value, like e.g. the
-# TARGETS or FILES keywords of the install() command.
-#
-# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
-# keywords listed in <options>, <one_value_keywords> and
-# <multi_value_keywords> a variable composed of the given <prefix>
-# followed by "_" and the name of the respective keyword. These
-# variables will then hold the respective value from the argument list.
-# For the <options> keywords this will be TRUE or FALSE.
-#
-# All remaining arguments are collected in a variable
-# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see
-# whether your macro was called with unrecognized parameters.
-#
-# As an example here a my_install() macro, which takes similar arguments
-# as the real install() command:
-#
-# ::
-#
-# function(MY_INSTALL)
-# set(options OPTIONAL FAST)
-# set(oneValueArgs DESTINATION RENAME)
-# set(multiValueArgs TARGETS CONFIGURATIONS)
-# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
-# "${multiValueArgs}" ${ARGN} )
-# ...
-#
-#
-#
-# Assume my_install() has been called like this:
-#
-# ::
-#
-# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
-#
-#
-#
-# After the cmake_parse_arguments() call the macro will have set the
-# following variables:
-#
-# ::
-#
-# MY_INSTALL_OPTIONAL = TRUE
-# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
-# MY_INSTALL_DESTINATION = "bin"
-# MY_INSTALL_RENAME = "" (was not used)
-# MY_INSTALL_TARGETS = "foo;bar"
-# MY_INSTALL_CONFIGURATIONS = "" (was not used)
-# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
-#
-#
-#
-# You can then continue and process these variables.
-#
-# Keywords terminate lists of values, e.g. if directly after a
-# 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 MY_INSTALL_DESTINATION
-# would be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
+# This module once implemented the :command:`cmake_parse_arguments` command
+# that is now implemented natively by CMake. It is now an empty placeholder
+# for compatibility with projects that include it to get the command from
+# CMake 3.4 and lower.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf at kde.org>
@@ -95,67 +19,3 @@
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
-
-
-if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
- return()
-endif()
-set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
-
-
-function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
- # first set all result variables to empty/FALSE
- foreach(arg_name ${_singleArgNames} ${_multiArgNames})
- set(${prefix}_${arg_name})
- endforeach()
-
- foreach(option ${_optionNames})
- set(${prefix}_${option} FALSE)
- endforeach()
-
- set(${prefix}_UNPARSED_ARGUMENTS)
-
- set(insideValues FALSE)
- set(currentArgName)
-
- # now iterate over all arguments and fill the result variables
- foreach(currentArg ${ARGN})
- list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
- list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
- list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
-
- if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
- if(insideValues)
- if("${insideValues}" STREQUAL "SINGLE")
- set(${prefix}_${currentArgName} ${currentArg})
- set(insideValues FALSE)
- elseif("${insideValues}" STREQUAL "MULTI")
- list(APPEND ${prefix}_${currentArgName} ${currentArg})
- endif()
- else()
- list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
- endif()
- else()
- if(NOT ${optionIndex} EQUAL -1)
- set(${prefix}_${currentArg} TRUE)
- set(insideValues FALSE)
- elseif(NOT ${singleArgIndex} EQUAL -1)
- set(currentArgName ${currentArg})
- set(${prefix}_${currentArgName})
- set(insideValues "SINGLE")
- elseif(NOT ${multiArgIndex} EQUAL -1)
- set(currentArgName ${currentArg})
- set(${prefix}_${currentArgName})
- set(insideValues "MULTI")
- endif()
- endif()
-
- endforeach()
-
- # propagate the result variables to the caller:
- foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
- set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
- endforeach()
- set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
-
-endfunction()
diff --git a/Source/cmBootstrapCommands1.cxx b/Source/cmBootstrapCommands1.cxx
index 1184514..0782b3b 100644
--- a/Source/cmBootstrapCommands1.cxx
+++ b/Source/cmBootstrapCommands1.cxx
@@ -54,6 +54,7 @@
#include "cmFunctionCommand.cxx"
#include "cmPathLabel.cxx"
#include "cmSearchPath.cxx"
+#include "cmParseArgumentsCommand.cxx"
void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
{
@@ -91,4 +92,5 @@ void GetBootstrapCommands1(std::vector<cmCommand*>& commands)
commands.push_back(new cmFindProgramCommand);
commands.push_back(new cmForEachCommand);
commands.push_back(new cmFunctionCommand);
+ commands.push_back(new cmParseArgumentsCommand);
}
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
new file mode 100644
index 0000000..ce7a7b3
--- /dev/null
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -0,0 +1,176 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Matthias Maennich <matthias at maennich.net>
+ Copyright 2010 Alexander Neundorf <neundorf at kde.org>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "cmParseArgumentsCommand.h"
+#include "cmAlgorithms.h"
+
+//----------------------------------------------------------------------------
+bool cmParseArgumentsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // cmake_parse_arguments(prefix options single multi <ARGN>)
+ // 1 2 3 4
+ if (args.size() < 4)
+ {
+ this->SetError("must be called with at least 4 arguments.");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator argIter = args.begin(),
+ argEnd = args.end();
+ // the first argument is the prefix
+ const std::string prefix = (*argIter++) + "_";
+
+ // 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 single;
+ multi_map multi;
+
+ // anything else is put into a vector of unparsed strings
+ std::vector<std::string> unparsed;
+
+ // the second argument is a (cmake) list of options without argument
+ std::vector<std::string> list;
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ options[*iter]; // default initialize
+ }
+
+ // the third argument is a (cmake) list of single argument options
+ list.clear();
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ single[*iter]; // default initialize
+ }
+
+ // the fourth argument is a (cmake) list of multi argument options
+ list.clear();
+ cmSystemTools::ExpandListArgument(*argIter++, list);
+ for (std::vector<std::string>::const_iterator iter = list.begin(),
+ end = list.end();
+ iter != end; ++iter)
+ {
+ multi[*iter]; // default initialize
+ }
+
+ enum insideValues
+ {
+ NONE,
+ SINGLE,
+ MULTI
+ } insideValues = NONE;
+ std::string currentArgName;
+
+ // now iterate over the remaining arguments
+ // and fill in the values where applicable
+ for(; argIter != argEnd; ++argIter)
+ {
+ const options_map::iterator optIter = options.find(*argIter);
+ if (optIter != options.end())
+ {
+ insideValues = NONE;
+ optIter->second = true;
+ continue;
+ }
+
+ const single_map::iterator singleIter = single.find(*argIter);
+ if (singleIter != single.end())
+ {
+ insideValues = SINGLE;
+ currentArgName = *argIter;
+ continue;
+ }
+
+ const multi_map::iterator multiIter = multi.find(*argIter);
+ if (multiIter != multi.end())
+ {
+ insideValues = MULTI;
+ currentArgName = *argIter;
+ continue;
+ }
+
+ switch(insideValues)
+ {
+ case SINGLE:
+ single[currentArgName] = *argIter;
+ insideValues = NONE;
+ break;
+ case MULTI:
+ multi[currentArgName].push_back(*argIter);
+ break;
+ default:
+ unparsed.push_back(*argIter);
+ break;
+ }
+ }
+
+ // now iterate over the collected values and update their definition
+ // within the current scope. undefine if necessary.
+
+ for (options_map::const_iterator iter = options.begin(), end = options.end();
+ iter != end; ++iter)
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ iter->second? "TRUE": "FALSE");
+ }
+ for (single_map::const_iterator iter = single.begin(), end = single.end();
+ iter != end; ++iter)
+ {
+ if (!iter->second.empty())
+ {
+ this->Makefile->AddDefinition(prefix + iter->first,
+ iter->second.c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(prefix + iter->first);
+ }
+ }
+
+ for (multi_map::const_iterator iter = multi.begin(), end = multi.end();
+ iter != end; ++iter)
+ {
+ 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");
+ }
+
+ return true;
+}
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
new file mode 100644
index 0000000..7fbf642
--- /dev/null
+++ b/Source/cmParseArgumentsCommand.h
@@ -0,0 +1,54 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2015 Matthias Maennich <matthias at maennich.net>
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmParseArgumentsCommand_h
+#define cmParseArgumentsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmParseArgumentsCommand
+ *
+ */
+class cmParseArgumentsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmParseArgumentsCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status);
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual std::string GetName() const { return "cmake_parse_arguments";}
+
+ cmTypeMacro(cmParseArgumentsCommand, cmCommand);
+
+};
+
+
+#endif
diff --git a/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
index 7337b71..9a727dd 100644
--- a/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
+++ b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
@@ -1,5 +1,4 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
-include(CMakeParseArguments)
# example from the documentation
# OPTIONAL is a keyword and therefore terminates the definition of
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
index 5976fdc..5394eaf 100644
--- a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
@@ -1,17 +1,14 @@
-CMake Error at Errors.cmake:3 \(cmake_parse_arguments\):
- CMAKE_PARSE_ARGUMENTS Function invoked with incorrect arguments for
- function named: CMAKE_PARSE_ARGUMENTS
+CMake Error at Errors\.cmake:1 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists\.txt:3 \(include\)
+
-CMake Error at Errors.cmake:4 \(cmake_parse_arguments\):
- CMAKE_PARSE_ARGUMENTS Function invoked with incorrect arguments for
- function named: CMAKE_PARSE_ARGUMENTS
+CMake Error at Errors\.cmake:2 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists\.txt:3 \(include\)
+
-CMake Error at Errors.cmake:5 \(cmake_parse_arguments\):
- CMAKE_PARSE_ARGUMENTS Function invoked with incorrect arguments for
- function named: CMAKE_PARSE_ARGUMENTS
+CMake Error at Errors\.cmake:3 \(cmake_parse_arguments\):
+ cmake_parse_arguments must be called with at least 4 arguments\.
Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
+ CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
index 2db3bb1..98e22e9 100644
--- a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
@@ -1,5 +1,3 @@
-include(CMakeParseArguments)
-
cmake_parse_arguments()
cmake_parse_arguments(prefix OPT)
cmake_parse_arguments(prefix OPT SINGLE)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
index 8729bc6..462f923 100644
--- a/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
+++ b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
@@ -1,5 +1,4 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
-include(CMakeParseArguments)
# unparsed arguments
cmake_parse_arguments(pref "" "" "")
diff --git a/Tests/RunCMake/cmake_parse_arguments/Mix.cmake b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
index c14fdfd..b3eff39 100644
--- a/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
+++ b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
@@ -1,5 +1,4 @@
include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
-include(CMakeParseArguments)
# specify two keywords for each category and set the first keyword of each
# within ARGN
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cbbdfc2b6120e192b4248ce89af93cf34ea8a254
commit cbbdfc2b6120e192b4248ce89af93cf34ea8a254
Author: Matthias Maennich <matthias at maennich.net>
AuthorDate: Sat Dec 5 18:57:41 2015 +0100
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Dec 17 10:31:04 2015 -0500
CMakeParseArguments: add a RunCMake test suite
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index a6cbf86..0a388c5 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -177,6 +177,7 @@ add_RunCMake_test(build_command)
add_RunCMake_test(execute_process)
add_RunCMake_test(export)
add_RunCMake_test(cmake_minimum_required)
+add_RunCMake_test(cmake_parse_arguments)
add_RunCMake_test(continue)
add_RunCMake_test(ctest_build)
add_RunCMake_test(ctest_configure)
diff --git a/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt b/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt
new file mode 100644
index 0000000..6dd8cdf
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
new file mode 100644
index 0000000..7337b71
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
@@ -0,0 +1,16 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+include(CMakeParseArguments)
+
+# example from the documentation
+# OPTIONAL is a keyword and therefore terminates the definition of
+# the multi-value DEFINITION before even a single value has been added
+
+set(options OPTIONAL FAST)
+set(oneValueArgs DESTINATION RENAME)
+set(multiValueArgs TARGETS CONFIGURATIONS)
+cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
+ "${multiValueArgs}"
+ TARGETS foo DESTINATION OPTIONAL)
+
+TEST(MY_INSTALL_DESTINATION UNDEFINED)
+TEST(MY_INSTALL_OPTIONAL TRUE)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
new file mode 100644
index 0000000..5976fdc
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at Errors.cmake:3 \(cmake_parse_arguments\):
+ CMAKE_PARSE_ARGUMENTS Function invoked with incorrect arguments for
+ function named: CMAKE_PARSE_ARGUMENTS
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at Errors.cmake:4 \(cmake_parse_arguments\):
+ CMAKE_PARSE_ARGUMENTS Function invoked with incorrect arguments for
+ function named: CMAKE_PARSE_ARGUMENTS
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at Errors.cmake:5 \(cmake_parse_arguments\):
+ CMAKE_PARSE_ARGUMENTS Function invoked with incorrect arguments for
+ function named: CMAKE_PARSE_ARGUMENTS
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Errors.cmake b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
new file mode 100644
index 0000000..2db3bb1
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Errors.cmake
@@ -0,0 +1,6 @@
+include(CMakeParseArguments)
+
+cmake_parse_arguments()
+cmake_parse_arguments(prefix OPT)
+cmake_parse_arguments(prefix OPT SINGLE)
+cmake_parse_arguments(prefix OPT SINGLE MULTI) # not an error
diff --git a/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
new file mode 100644
index 0000000..8729bc6
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
@@ -0,0 +1,69 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+include(CMakeParseArguments)
+
+# unparsed arguments
+cmake_parse_arguments(pref "" "" "")
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "" FOO)
+TEST(pref_UNPARSED_ARGUMENTS "FOO")
+cmake_parse_arguments(pref "" "" "" FOO BAR)
+TEST(pref_UNPARSED_ARGUMENTS "FOO;BAR")
+cmake_parse_arguments(pref "" "" "")
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+
+# options
+cmake_parse_arguments(pref "OPT1" "" "")
+TEST(pref_OPT1 FALSE)
+
+cmake_parse_arguments(pref "OPT1;OPT2" "" "")
+TEST(pref_OPT1 FALSE)
+TEST(pref_OPT2 FALSE)
+
+cmake_parse_arguments(pref "OPT1" "" "" OPT1)
+TEST(pref_OPT1 TRUE)
+cmake_parse_arguments(pref "OPT1;OPT2" "" "" OPT1 OPT2)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 TRUE)
+cmake_parse_arguments(pref "OPT1;OPT2" "" "")
+TEST(pref_OPT1 FALSE)
+TEST(pref_OPT2 FALSE)
+
+
+# single arguments
+cmake_parse_arguments(pref "" "SINGLE1" "")
+TEST(pref_SINGLE1 UNDEFINED)
+
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
+TEST(pref_SINGLE1 UNDEFINED)
+TEST(pref_SINGLE2 UNDEFINED)
+
+
+cmake_parse_arguments(pref "" "SINGLE1" "" SINGLE1 foo)
+TEST(pref_SINGLE1 foo)
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "" SINGLE1 foo SINGLE2 bar)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 bar)
+cmake_parse_arguments(pref "" "SINGLE1;SINGLE2" "")
+TEST(pref_SINGLE1 UNDEFINED)
+TEST(pref_SINGLE2 UNDEFINED)
+
+
+# multi arguments
+
+cmake_parse_arguments(pref "" "" "MULTI1")
+TEST(pref_MULTI1 UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
+TEST(pref_MULTI1 UNDEFINED)
+TEST(pref_MULTI2 UNDEFINED)
+
+cmake_parse_arguments(pref "" "" "MULTI1" MULTI1 foo)
+TEST(pref_MULTI1 foo)
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2" MULTI1 foo bar MULTI2 bar foo)
+TEST(pref_MULTI1 foo bar)
+TEST(pref_MULTI2 bar foo)
+cmake_parse_arguments(pref "" "" "MULTI1;MULTI2")
+TEST(pref_MULTI1 UNDEFINED)
+TEST(pref_MULTI2 UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Mix.cmake b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
new file mode 100644
index 0000000..c14fdfd
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Mix.cmake
@@ -0,0 +1,25 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+include(CMakeParseArguments)
+
+# specify two keywords for each category and set the first keyword of each
+# within ARGN
+cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
+ OPT1 SINGLE1 foo MULTI1 bar foo bar)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 FALSE)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 UNDEFINED)
+TEST(pref_MULTI1 bar foo bar)
+TEST(pref_MULTI2 UNDEFINED)
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
+
+# same as above but reversed ARGN
+cmake_parse_arguments(pref "OPT1;OPT2" "SINGLE1;SINGLE2" "MULTI1;MULTI2"
+ MULTI1 bar foo bar SINGLE1 foo OPT1)
+TEST(pref_OPT1 TRUE)
+TEST(pref_OPT2 FALSE)
+TEST(pref_SINGLE1 foo)
+TEST(pref_SINGLE2 UNDEFINED)
+TEST(pref_MULTI1 bar foo bar)
+TEST(pref_MULTI2 UNDEFINED)
+TEST(pref_UNPARSED_ARGUMENTS UNDEFINED)
diff --git a/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
new file mode 100644
index 0000000..b89f1a5
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(Utils)
+run_cmake(Initialization)
+run_cmake(Mix)
+run_cmake(CornerCases)
+run_cmake(Errors)
diff --git a/Tests/RunCMake/cmake_parse_arguments/Utils.cmake b/Tests/RunCMake/cmake_parse_arguments/Utils.cmake
new file mode 100644
index 0000000..3bbf115
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/Utils.cmake
@@ -0,0 +1,20 @@
+include(${CMAKE_CURRENT_LIST_DIR}/test_utils.cmake)
+
+# test the TEST macro itself
+
+TEST(asdf UNDEFINED)
+
+SET (asdf FALSE)
+TEST(asdf FALSE)
+
+SET (asdf TRUE)
+TEST(asdf TRUE)
+
+SET (asdf TRUE)
+TEST(asdf TRUE)
+
+SET (asdf "some value")
+TEST(asdf "some value")
+
+SET (asdf some list)
+TEST(asdf "some;list")
diff --git a/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake b/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
new file mode 100644
index 0000000..f5425c2
--- /dev/null
+++ b/Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
@@ -0,0 +1,20 @@
+macro(TEST variable)
+ SET(expected "${ARGN}")
+ if ( "${expected}" STREQUAL "UNDEFINED" )
+ if (DEFINED ${variable})
+ message(FATAL_ERROR "'${variable}' shall be undefined but has value '${${variable}}'")
+ endif()
+ elseif( "${expected}" STREQUAL "FALSE" )
+ if (NOT ${variable} STREQUAL "FALSE")
+ message(FATAL_ERROR "'${variable}' shall be FALSE")
+ endif()
+ elseif( "${expected}" STREQUAL "TRUE" )
+ if (NOT ${variable} STREQUAL "TRUE")
+ message(FATAL_ERROR "'${variable}' shall be TRUE")
+ endif()
+ else()
+ if (NOT ${variable} STREQUAL "${expected}")
+ message(FATAL_ERROR "'${variable}' shall be '${expected}'")
+ endif()
+ endif()
+endmacro()
-----------------------------------------------------------------------
Summary of changes:
Help/command/cmake_parse_arguments.rst | 85 +++++++++
Help/manual/cmake-commands.7.rst | 1 +
.../dev/CMakeParseArguments-native-impl.rst | 6 +
Modules/CMakeParseArguments.cmake | 148 +--------------
Source/cmBootstrapCommands1.cxx | 2 +
Source/cmParseArgumentsCommand.cxx | 192 ++++++++++++++++++++
...riteFileCommand.h => cmParseArgumentsCommand.h} | 19 +-
Tests/RunCMake/CMakeLists.txt | 1 +
.../CMakeLists.txt | 0
.../cmake_parse_arguments/CornerCases.cmake | 15 ++
.../Errors-result.txt} | 0
.../cmake_parse_arguments/Errors-stderr.txt | 44 +++++
Tests/RunCMake/cmake_parse_arguments/Errors.cmake | 14 ++
.../cmake_parse_arguments/Initialization.cmake | 68 +++++++
Tests/RunCMake/cmake_parse_arguments/Mix.cmake | 24 +++
.../cmake_parse_arguments/RunCMakeTest.cmake | 7 +
Tests/RunCMake/cmake_parse_arguments/Utils.cmake | 20 ++
.../cmake_parse_arguments/test_utils.cmake | 20 ++
18 files changed, 513 insertions(+), 153 deletions(-)
create mode 100644 Help/command/cmake_parse_arguments.rst
create mode 100644 Help/release/dev/CMakeParseArguments-native-impl.rst
create mode 100644 Source/cmParseArgumentsCommand.cxx
copy Source/{cmWriteFileCommand.h => cmParseArgumentsCommand.h} (74%)
copy Tests/RunCMake/{Framework => cmake_parse_arguments}/CMakeLists.txt (100%)
create mode 100644 Tests/RunCMake/cmake_parse_arguments/CornerCases.cmake
copy Tests/RunCMake/{CMP0004/CMP0004-NEW-result.txt => cmake_parse_arguments/Errors-result.txt} (100%)
create mode 100644 Tests/RunCMake/cmake_parse_arguments/Errors-stderr.txt
create mode 100644 Tests/RunCMake/cmake_parse_arguments/Errors.cmake
create mode 100644 Tests/RunCMake/cmake_parse_arguments/Initialization.cmake
create mode 100644 Tests/RunCMake/cmake_parse_arguments/Mix.cmake
create mode 100644 Tests/RunCMake/cmake_parse_arguments/RunCMakeTest.cmake
create mode 100644 Tests/RunCMake/cmake_parse_arguments/Utils.cmake
create mode 100644 Tests/RunCMake/cmake_parse_arguments/test_utils.cmake
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list