diff options
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 |