summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmCMakeLanguageCommand.cxx128
-rw-r--r--Tests/RunCMake/cmake_language/call_expand_command_name.cmake2
-rw-r--r--Tests/RunCMake/cmake_language/call_expanded_command.cmake2
-rw-r--r--Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_language/call_message.cmake2
-rw-r--r--Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_language/no_parameters-stderr.txt2
7 files changed, 71 insertions, 69 deletions
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index ae80066..b4454b1 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -29,6 +29,38 @@ std::array<cm::static_string_view, 12> InvalidCommands{
} // clang-format on
};
+bool cmCMakeLanguageCommandCALL(std::vector<cmListFileArgument> const& args,
+ std::string const& callCommand,
+ size_t startArg, cmExecutionStatus& status)
+{
+ // ensure specified command is valid
+ // start/end flow control commands are not allowed
+ auto cmd = cmSystemTools::LowerCase(callCommand);
+ if (std::find(InvalidCommands.cbegin(), InvalidCommands.cend(), cmd) !=
+ InvalidCommands.cend()) {
+ status.SetError(cmStrCat("invalid command specified: "_s, callCommand));
+ return false;
+ }
+
+ cmMakefile& makefile = status.GetMakefile();
+ cmListFileContext context = makefile.GetBacktrace().Top();
+
+ cmListFileFunction func;
+ func.Name = callCommand;
+ func.Line = context.Line;
+
+ // The rest of the arguments are passed to the function call above
+ for (size_t i = startArg; i < args.size(); ++i) {
+ cmListFileArgument lfarg;
+ lfarg.Delim = args[i].Delim;
+ lfarg.Line = context.Line;
+ lfarg.Value = args[i].Value;
+ func.Arguments.emplace_back(lfarg);
+ }
+
+ return makefile.ExecuteCommand(func, status);
+}
+
bool cmCMakeLanguageCommandEVAL(std::vector<cmListFileArgument> const& args,
cmExecutionStatus& status)
{
@@ -64,82 +96,52 @@ bool cmCMakeLanguageCommandEVAL(std::vector<cmListFileArgument> const& args,
bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
cmExecutionStatus& status)
{
- if (args.empty()) {
- status.SetError("called with incorrect number of arguments");
- return false;
- }
-
- cmMakefile& makefile = status.GetMakefile();
- cmListFileContext context = makefile.GetBacktrace().Top();
-
- bool result = false;
-
- std::vector<std::string> dispatchExpandedArgs;
- std::vector<cmListFileArgument> dispatchArgs;
- dispatchArgs.emplace_back(args[0]);
- makefile.ExpandArguments(dispatchArgs, dispatchExpandedArgs);
+ std::vector<std::string> expArgs;
+ size_t rawArg = 0;
+ size_t expArg = 0;
+
+ // Helper to consume and expand one raw argument at a time.
+ auto moreArgs = [&]() -> bool {
+ while (expArg >= expArgs.size()) {
+ if (rawArg >= args.size()) {
+ return false;
+ }
+ std::vector<cmListFileArgument> tmpArg;
+ tmpArg.emplace_back(args[rawArg++]);
+ status.GetMakefile().ExpandArguments(tmpArg, expArgs);
+ }
+ return true;
+ };
- if (dispatchExpandedArgs.empty()) {
+ if (!moreArgs()) {
status.SetError("called with incorrect number of arguments");
return false;
}
- if (dispatchExpandedArgs[0] == "CALL") {
- if ((args.size() == 1 && dispatchExpandedArgs.size() != 2) ||
- dispatchExpandedArgs.size() > 2) {
- status.SetError("called with incorrect number of arguments");
- return false;
- }
+ if (expArgs[expArg] == "CALL") {
+ ++expArg; // Consume "CALL".
- // First argument is the name of the function to call
- std::string callCommand;
- size_t startArg;
- if (dispatchExpandedArgs.size() == 1) {
- std::vector<std::string> functionExpandedArg;
- std::vector<cmListFileArgument> functionArg;
- functionArg.emplace_back(args[1]);
- makefile.ExpandArguments(functionArg, functionExpandedArg);
-
- if (functionExpandedArg.size() != 1) {
- status.SetError("called with incorrect number of arguments");
- return false;
- }
-
- callCommand = functionExpandedArg[0];
- startArg = 2;
- } else {
- callCommand = dispatchExpandedArgs[1];
- startArg = 1;
+ // CALL requires a command name.
+ if (!moreArgs()) {
+ status.SetError("CALL missing command name");
+ return false;
}
+ std::string const& callCommand = expArgs[expArg++];
- // ensure specified command is valid
- // start/end flow control commands are not allowed
- auto cmd = cmSystemTools::LowerCase(callCommand);
- if (std::find(InvalidCommands.cbegin(), InvalidCommands.cend(), cmd) !=
- InvalidCommands.cend()) {
- status.SetError(cmStrCat("invalid command specified: "_s, callCommand));
+ // CALL accepts no further expanded arguments.
+ if (expArg != expArgs.size()) {
+ status.SetError("CALL command's arguments must be literal");
return false;
}
- cmListFileFunction func;
- func.Name = callCommand;
- func.Line = context.Line;
-
- // The rest of the arguments are passed to the function call above
- for (size_t i = startArg; i < args.size(); ++i) {
- cmListFileArgument lfarg;
- lfarg.Delim = args[i].Delim;
- lfarg.Line = context.Line;
- lfarg.Value = args[i].Value;
- func.Arguments.emplace_back(lfarg);
- }
+ // Run the CALL.
+ return cmCMakeLanguageCommandCALL(args, callCommand, rawArg, status);
+ }
- result = makefile.ExecuteCommand(func, status);
- } else if (dispatchExpandedArgs[0] == "EVAL") {
+ if (expArgs[expArg] == "EVAL") {
return cmCMakeLanguageCommandEVAL(args, status);
- } else {
- status.SetError("called with unknown meta-operation");
}
- return result;
+ status.SetError("called with unknown meta-operation");
+ return false;
}
diff --git a/Tests/RunCMake/cmake_language/call_expand_command_name.cmake b/Tests/RunCMake/cmake_language/call_expand_command_name.cmake
index e03bb1f..f74d303 100644
--- a/Tests/RunCMake/cmake_language/call_expand_command_name.cmake
+++ b/Tests/RunCMake/cmake_language/call_expand_command_name.cmake
@@ -1,2 +1,2 @@
set (my_call "CALL")
-cmake_language (${my_call} message "OK!")
+cmake_language (${my_call} ${empty} message "OK!")
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command.cmake b/Tests/RunCMake/cmake_language/call_expanded_command.cmake
index e76e612..c52468d 100644
--- a/Tests/RunCMake/cmake_language/call_expanded_command.cmake
+++ b/Tests/RunCMake/cmake_language/call_expanded_command.cmake
@@ -3,4 +3,4 @@ function (itsok)
endfunction()
set (cmd CALL itsok)
-cmake_language (${cmd})
+cmake_language (${empty} ${cmd})
diff --git a/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt
index e87e9bc..82411d2 100644
--- a/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt
+++ b/Tests/RunCMake/cmake_language/call_expanded_command_and_arguments-stderr.txt
@@ -1,4 +1,4 @@
CMake Error at call_expanded_command_and_arguments.cmake:2 \(cmake_language\):
- cmake_language called with incorrect number of arguments
+ cmake_language CALL command's arguments must be literal
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_language/call_message.cmake b/Tests/RunCMake/cmake_language/call_message.cmake
index 31aefdf..3b98c80 100644
--- a/Tests/RunCMake/cmake_language/call_message.cmake
+++ b/Tests/RunCMake/cmake_language/call_message.cmake
@@ -1 +1 @@
-cmake_language(CALL message WORKS!)
+cmake_language(CALL ${empty} message WORKS!)
diff --git a/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt b/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt
index 9e2c08f..f6a0458 100644
--- a/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt
+++ b/Tests/RunCMake/cmake_language/call_no_parameters-stderr.txt
@@ -1,2 +1,2 @@
CMake Error at call_no_parameters.cmake:1 \(cmake_language\):
- cmake_language called with incorrect number of arguments
+ cmake_language CALL missing command name
diff --git a/Tests/RunCMake/cmake_language/no_parameters-stderr.txt b/Tests/RunCMake/cmake_language/no_parameters-stderr.txt
index 194bbe3..1862c77 100644
--- a/Tests/RunCMake/cmake_language/no_parameters-stderr.txt
+++ b/Tests/RunCMake/cmake_language/no_parameters-stderr.txt
@@ -1,2 +1,2 @@
CMake Error at no_parameters.cmake:1 \(cmake_language\):
- cmake_language called with incorrect number of arguments
+ cmake_language CALL missing command name