From aa55587094f833db511a8c6e2ba63748af7d1719 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Fri, 15 May 2020 13:25:38 +0200 Subject: cmake_command: Expand INVOKE function name argument Fixes: #20707 --- Source/cmCMakeCommand.cxx | 72 +++++++++++++++------- Tests/RunCMake/cmake_command/RunCMakeTest.cmake | 9 +++ ...ake_command_eval_expand_command_name-stderr.txt | 1 + .../cmake_command_eval_expand_command_name.cmake | 2 + ..._eval_expanded_command_and_arguments-stderr.txt | 1 + ...mmand_eval_expanded_command_and_arguments.cmake | 2 + ...tra_parameters_between_eval_and_code-result.txt | 1 + ...tra_parameters_between_eval_and_code-stderr.txt | 5 ++ ...al_extra_parameters_between_eval_and_code.cmake | 1 + ...ake_command_invoke_double_evaluation-stderr.txt | 1 + .../cmake_command_invoke_double_evaluation.cmake | 2 + ...e_command_invoke_expand_command_name-stderr.txt | 1 + .../cmake_command_invoke_expand_command_name.cmake | 2 + ..._command_invoke_expand_function_name-stderr.txt | 1 + ...cmake_command_invoke_expand_function_name.cmake | 11 ++++ ...make_command_invoke_expanded_command-stderr.txt | 1 + .../cmake_command_invoke_expanded_command.cmake | 6 ++ ...nvoke_expanded_command_and_arguments-result.txt | 1 + ...nvoke_expanded_command_and_arguments-stderr.txt | 4 ++ ...and_invoke_expanded_command_and_arguments.cmake | 2 + ...anded_command_with_explicit_argument-stderr.txt | 1 + ...e_expanded_command_with_explicit_argument.cmake | 2 + 22 files changed, 108 insertions(+), 21 deletions(-) create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-result.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-result.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments.cmake create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument-stderr.txt create mode 100644 Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument.cmake diff --git a/Source/cmCMakeCommand.cxx b/Source/cmCMakeCommand.cxx index da15b1a..23bc0ea 100644 --- a/Source/cmCMakeCommand.cxx +++ b/Source/cmCMakeCommand.cxx @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -14,13 +13,6 @@ #include "cmRange.h" #include "cmStringAlgorithms.h" -inline std::ostream& operator<<(std::ostream& os, - cmListFileArgument const& arg) -{ - os << arg.Value; - return os; -} - bool cmCMakeCommand(std::vector const& args, cmExecutionStatus& status) { @@ -34,20 +26,50 @@ bool cmCMakeCommand(std::vector const& args, bool result = false; - if (args[0].Value == "INVOKE") { - if (args.size() == 1) { + std::vector dispatchExpandedArgs; + std::vector dispatchArgs; + dispatchArgs.emplace_back(args[0]); + makefile.ExpandArguments(dispatchArgs, dispatchExpandedArgs); + + if (dispatchExpandedArgs.empty()) { + status.SetError("called with incorrect number of arguments"); + return false; + } + + if (dispatchExpandedArgs[0] == "INVOKE") { + if ((args.size() == 1 && dispatchExpandedArgs.size() != 2) || + dispatchExpandedArgs.size() > 2) { status.SetError("called with incorrect number of arguments"); return false; } // First argument is the name of the function to call + std::string invokeCommand; + size_t startArg; + if (dispatchExpandedArgs.size() == 1) { + std::vector functionExpandedArg; + std::vector functionArg; + functionArg.emplace_back(args[1]); + makefile.ExpandArguments(functionArg, functionExpandedArg); + + if (functionExpandedArg.size() != 1) { + status.SetError("called with incorrect number of arguments"); + return false; + } + + invokeCommand = functionExpandedArg[0]; + startArg = 2; + } else { + invokeCommand = dispatchExpandedArgs[1]; + startArg = 1; + } + cmListFileFunction func; - func.Name = args[1].Value; + func.Name = invokeCommand; func.Line = context.Line; // The rest of the arguments are passed to the function call above - func.Arguments.resize(args.size() - 1); - for (size_t i = 2; i < args.size(); ++i) { + for (size_t i = startArg; i < args.size(); ++i) { cmListFileArgument lfarg; lfarg.Delim = args[i].Delim; lfarg.Line = context.Line; @@ -56,21 +78,29 @@ bool cmCMakeCommand(std::vector const& args, } result = makefile.ExecuteCommand(func, status); - } else if (args[0].Value == "EVAL") { - if (args.size() < 2) { + } else if (dispatchExpandedArgs[0] == "EVAL") { + std::vector expandedArgs; + makefile.ExpandArguments(args, expandedArgs); + + if (expandedArgs.size() < 2) { status.SetError("called with incorrect number of arguments"); return false; } - auto code_iter = std::find_if( - args.begin(), args.end(), - [](cmListFileArgument const& arg) { return arg.Value == "CODE"; }); - if (code_iter == args.end()) { - status.SetError("called without CODE argument"); + if (expandedArgs[1] != "CODE") { + auto code_iter = + std::find(expandedArgs.begin() + 2, expandedArgs.end(), "CODE"); + if (code_iter == expandedArgs.end()) { + status.SetError("called without CODE argument"); + } else { + status.SetError( + "called with unsupported arguments between EVAL and CODE arguments"); + } return false; } - const std::string code = cmJoin(cmMakeRange(++code_iter, args.end()), " "); + const std::string code = + cmJoin(cmMakeRange(expandedArgs.begin() + 2, expandedArgs.end()), " "); result = makefile.ReadListFileAsString( code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL")); } else { diff --git a/Tests/RunCMake/cmake_command/RunCMakeTest.cmake b/Tests/RunCMake/cmake_command/RunCMakeTest.cmake index 0f12b80..a6b2efe 100644 --- a/Tests/RunCMake/cmake_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_command/RunCMakeTest.cmake @@ -2,11 +2,20 @@ include(RunCMake) run_cmake(cmake_command_no_parameters) run_cmake(cmake_command_unknown_meta_operation) +run_cmake(cmake_command_invoke_double_evaluation) +run_cmake(cmake_command_invoke_expanded_command) +run_cmake(cmake_command_invoke_expanded_command_and_arguments) +run_cmake(cmake_command_invoke_expanded_command_with_explicit_argument) +run_cmake(cmake_command_invoke_expand_command_name) +run_cmake(cmake_command_invoke_expand_function_name) run_cmake(cmake_command_invoke_message) run_cmake(cmake_command_invoke_message_fatal_error) run_cmake(cmake_command_invoke_no_parameters) run_cmake(cmake_command_invoke_preserve_arguments) run_cmake(cmake_command_invoke_unknown_function) +run_cmake(cmake_command_eval_expand_command_name) +run_cmake(cmake_command_eval_expanded_command_and_arguments) +run_cmake(cmake_command_eval_extra_parameters_between_eval_and_code) run_cmake(cmake_command_eval_message) run_cmake(cmake_command_eval_message_fatal_error) run_cmake(cmake_command_eval_no_code) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name-stderr.txt new file mode 100644 index 0000000..d640661 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name-stderr.txt @@ -0,0 +1 @@ +OK! diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name.cmake new file mode 100644 index 0000000..4cea393 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_expand_command_name.cmake @@ -0,0 +1,2 @@ +set (my_eval "EVAL") +cmake_command (${my_eval} CODE message("OK!")) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments-stderr.txt new file mode 100644 index 0000000..d640661 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments-stderr.txt @@ -0,0 +1 @@ +OK! diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments.cmake new file mode 100644 index 0000000..fcc399b --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_expanded_command_and_arguments.cmake @@ -0,0 +1,2 @@ +set(cmd EVAL CODE [[message("OK!")]]) +cmake_command(${cmd}) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-stderr.txt new file mode 100644 index 0000000..13c114e --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at cmake_command_eval_extra_parameters_between_eval_and_code.cmake:1 \(cmake_command\): + cmake_command called with unsupported arguments between EVAL and CODE + arguments +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code.cmake new file mode 100644 index 0000000..0927631 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_extra_parameters_between_eval_and_code.cmake @@ -0,0 +1 @@ +cmake_command(EVAL BAD CODE "message(BAD CODE)") diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation-stderr.txt new file mode 100644 index 0000000..59a70bd --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation-stderr.txt @@ -0,0 +1 @@ +var='\${foo}' diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation.cmake new file mode 100644 index 0000000..10970fc --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_double_evaluation.cmake @@ -0,0 +1,2 @@ +set(var [[${foo}]]) +cmake_command(INVOKE cmake_command INVOKE message "var='${var}'") diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name-stderr.txt new file mode 100644 index 0000000..d640661 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name-stderr.txt @@ -0,0 +1 @@ +OK! diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name.cmake new file mode 100644 index 0000000..d59afe4 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_command_name.cmake @@ -0,0 +1,2 @@ +set (my_invoke "INVOKE") +cmake_command (${my_invoke} message "OK!") diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name-stderr.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name-stderr.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name.cmake new file mode 100644 index 0000000..923ddaa --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expand_function_name.cmake @@ -0,0 +1,11 @@ +function(some_function_1) + message(1) +endfunction() + +function(some_function_2) + message(2) +endfunction() + +set(function_version 1) + +cmake_command(INVOKE some_function_${function_version}) diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command-stderr.txt new file mode 100644 index 0000000..d640661 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command-stderr.txt @@ -0,0 +1 @@ +OK! diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command.cmake new file mode 100644 index 0000000..bca7d2f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command.cmake @@ -0,0 +1,6 @@ +function (itsok) + message(OK!) +endfunction() + +set (cmd INVOKE itsok) +cmake_command (${cmd}) diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-result.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-stderr.txt new file mode 100644 index 0000000..6d0e241 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at cmake_command_invoke_expanded_command_and_arguments.cmake:2 \(cmake_command\): + cmake_command called with incorrect number of arguments +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments.cmake new file mode 100644 index 0000000..6bfa3a7 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_and_arguments.cmake @@ -0,0 +1,2 @@ +set(invoke_message INVOKE message a b) +cmake_command(${invoke_message}) diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument-stderr.txt new file mode 100644 index 0000000..d640661 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument-stderr.txt @@ -0,0 +1 @@ +OK! diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument.cmake new file mode 100644 index 0000000..eb0411f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_expanded_command_with_explicit_argument.cmake @@ -0,0 +1,2 @@ +set (cmd INVOKE message) +cmake_command (${cmd} "OK!") -- cgit v0.12