diff --git a/Help/command/function.rst b/Help/command/function.rst index 069f9fa792..6722ca417b 100644 --- a/Help/command/function.rst +++ b/Help/command/function.rst @@ -59,20 +59,29 @@ Arguments When the function is invoked, the recorded ```` are first modified by replacing formal parameters (``${arg1}``, ...) with the -arguments passed, and then invoked as normal commands. +arguments passed, and then invoked as normal commands. The following +variables are set in the scope of the function: -In addition to referencing the formal parameters you can reference the -``ARGC`` variable which will be set to the number of arguments passed -into the function as well as ``ARGV0``, ``ARGV1``, ``ARGV2``, ... which -will have the actual values of the arguments passed in. This facilitates -creating functions with optional arguments. +``ARGC`` + The number of arguments passed into the function. -Furthermore, ``ARGV`` holds the list of all arguments given to the -function and ``ARGN`` holds the list of arguments past the last expected -argument. Referencing to ``ARGV#`` arguments beyond ``ARGC`` have -undefined behavior. Checking that ``ARGC`` is greater than ``#`` is -the only way to ensure that ``ARGV#`` was passed to the function as an -extra argument. +``ARGV`` + The list of all arguments given to the function. + +``ARGV#`` + The variables ``ARGV0``, ``ARGV1``, ``ARGV2``, ... which will have the + actual values of the arguments passed in. References to ``ARGV#`` + arguments beyond ``ARGC`` have undefined behavior. Checking that + ``ARGC`` is greater than ``#`` is the only way to ensure that ``ARGV#`` + was passed to the function as an extra argument. + +``ARGN`` + The list of arguments past the last expected argument. + +``ARGNC`` + .. versionadded:: 4.5 + + The number of arguments past the last expected argument. See Also ^^^^^^^^ diff --git a/Help/release/dev/function-argnc.rst b/Help/release/dev/function-argnc.rst new file mode 100644 index 0000000000..94210e0a88 --- /dev/null +++ b/Help/release/dev/function-argnc.rst @@ -0,0 +1,5 @@ +function-argnc +-------------- + +* The :command:`function` command now sets the ``ARGNC`` variable, which + holds the number of arguments past the last expected argument. diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 3e62649c89..0d029938fb 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -25,7 +25,7 @@ namespace { std::string const ARGC = "ARGC"; -std::string const kFUNCTION_ARGNC = "_FUNCTION_ARGNC"; +std::string const ARGNC = "ARGNC"; std::string const ARGN = "ARGN"; std::string const ARGV = "ARGV"; std::string const CMAKE_CURRENT_FUNCTION = "CMAKE_CURRENT_FUNCTION"; @@ -94,7 +94,7 @@ bool cmFunctionHelperCommand::operator()( makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]); } - // define ARGV, ARGN, and _FUNCTION_ARGNC + // define ARGV, ARGN, and ARGNC auto const argvDef = cmList::to_string(expandedArgs); auto const expIt = expandedArgs.begin() + (this->Args.size() - 1); auto const argnDef = @@ -105,8 +105,8 @@ bool cmFunctionHelperCommand::operator()( makefile.MarkVariableAsUsed(ARGV); makefile.AddDefinition(ARGN, argnDef); makefile.MarkVariableAsUsed(ARGN); - makefile.AddDefinition(kFUNCTION_ARGNC, functionArgncDef); - makefile.MarkVariableAsUsed(kFUNCTION_ARGNC); + makefile.AddDefinition(ARGNC, functionArgncDef); + makefile.MarkVariableAsUsed(ARGNC); makefile.AddDefinition(CMAKE_CURRENT_FUNCTION, this->Args.front()); makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION); diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx index 88b62952a8..19f23eed15 100644 --- a/Source/cmParseArgumentsCommand.cxx +++ b/Source/cmParseArgumentsCommand.cxx @@ -182,12 +182,11 @@ bool cmParseArgumentsCommand(std::vector const& args, } parseFromArg = true; argIter++; // move past PARSE_ARGN - std::string argncStr = - status.GetMakefile().GetSafeDefinition("_FUNCTION_ARGNC"); + std::string argncStr = status.GetMakefile().GetSafeDefinition("ARGNC"); if (!cmStrToULong(argncStr, &argnc)) { status.GetMakefile().IssueMessage( MessageType::FATAL_ERROR, - cmStrCat("PARSE_ARGN called with _FUNCTION_ARGNC='", argncStr, + cmStrCat("PARSE_ARGN called with ARGNC='", argncStr, "' that is not an unsigned integer")); cmSystemTools::SetFatalErrorOccurred(); return true; diff --git a/Tests/RunCMake/cmake_parse_arguments/BadArgN2-stderr.txt b/Tests/RunCMake/cmake_parse_arguments/BadArgN2-stderr.txt index 806756a379..dcb6341ab4 100644 --- a/Tests/RunCMake/cmake_parse_arguments/BadArgN2-stderr.txt +++ b/Tests/RunCMake/cmake_parse_arguments/BadArgN2-stderr.txt @@ -1,5 +1,5 @@ ^CMake Error at BadArgN2\.cmake:[0-9]+ \(cmake_parse_arguments\): - PARSE_ARGN called with _FUNCTION_ARGNC='' that is not an unsigned integer + PARSE_ARGN called with ARGNC='' that is not an unsigned integer Call Stack \(most recent call first\): BadArgN2\.cmake:[0-9]+ \(test2\) CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/cmake_parse_arguments/BadArgN2.cmake b/Tests/RunCMake/cmake_parse_arguments/BadArgN2.cmake index 0e916791c4..476d0bca22 100644 --- a/Tests/RunCMake/cmake_parse_arguments/BadArgN2.cmake +++ b/Tests/RunCMake/cmake_parse_arguments/BadArgN2.cmake @@ -1,5 +1,5 @@ function(test2) - unset(_FUNCTION_ARGNC) + unset(ARGNC) cmake_parse_arguments(PARSE_ARGN pref "" "" "") endfunction() test2()