diff options
author | Brad King <brad.king@kitware.com> | 2020-09-21 20:01:56 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-09-29 14:00:24 (GMT) |
commit | 4f33f3dcff83f796e94f5e606b5776fe4336a1bc (patch) | |
tree | cb5d4d167eff716a4ba3c43c4f0075a2cb654fd6 /Source | |
parent | 4ebe9c4ce15734ee9a167f7b48b8ed8931adb0ca (diff) | |
download | CMake-4f33f3dcff83f796e94f5e606b5776fe4336a1bc.zip CMake-4f33f3dcff83f796e94f5e606b5776fe4336a1bc.tar.gz CMake-4f33f3dcff83f796e94f5e606b5776fe4336a1bc.tar.bz2 |
cmake_language(CALL): Accept empty ${var} expansions
Factor out an internal helper. Generalize partial argument expansion
and call the helper on a clean boundary between raw arguments.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCMakeLanguageCommand.cxx | 128 |
1 files changed, 65 insertions, 63 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; } |