summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-21 20:01:56 (GMT)
committerBrad King <brad.king@kitware.com>2020-09-29 14:00:24 (GMT)
commit4f33f3dcff83f796e94f5e606b5776fe4336a1bc (patch)
treecb5d4d167eff716a4ba3c43c4f0075a2cb654fd6 /Source
parent4ebe9c4ce15734ee9a167f7b48b8ed8931adb0ca (diff)
downloadCMake-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.cxx128
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;
}