summaryrefslogtreecommitdiff
path: root/Source/cmSeparateArgumentsCommand.cxx
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2020-09-22 16:31:29 +0200
committerMarc Chevrier <marc.chevrier@gmail.com>2020-09-22 16:32:34 +0200
commitd832c1cc7d717623b2eb07a940c85ca427a8084e (patch)
treeb6df341db1b3a8b8e323efb5676cb9ba50711cff /Source/cmSeparateArgumentsCommand.cxx
parentf4c21d4953afe1c638226a0e8db2f0a887665f38 (diff)
downloadcmake-d832c1cc7d717623b2eb07a940c85ca427a8084e.tar.gz
separate_arguments: add option PROGRAM
Fixes: #21217
Diffstat (limited to 'Source/cmSeparateArgumentsCommand.cxx')
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx51
1 files changed, 50 insertions, 1 deletions
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index e179bc6401..7e501a2e04 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -41,13 +41,17 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
bool UnixCommand = false;
bool WindowsCommand = false;
bool NativeCommand = false;
+ bool Program = false;
+ bool SeparateArgs = false;
};
static auto const parser =
cmArgumentParser<Arguments>{}
.Bind("UNIX_COMMAND"_s, &Arguments::UnixCommand)
.Bind("WINDOWS_COMMAND"_s, &Arguments::WindowsCommand)
- .Bind("NATIVE_COMMAND"_s, &Arguments::NativeCommand);
+ .Bind("NATIVE_COMMAND"_s, &Arguments::NativeCommand)
+ .Bind("PROGRAM"_s, &Arguments::Program)
+ .Bind("SEPARATE_ARGS"_s, &Arguments::SeparateArgs);
std::vector<std::string> unparsedArguments;
Arguments arguments =
@@ -66,6 +70,10 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
"are mutually exclusive");
return false;
}
+ if (arguments.SeparateArgs && !arguments.Program) {
+ status.SetError("`SEPARATE_ARGS` option requires `PROGRAM' option");
+ return false;
+ }
if (unparsedArguments.size() > 1) {
status.SetError("given unexpected argument(s)");
@@ -79,6 +87,35 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
return true;
}
+ if (arguments.Program && !arguments.SeparateArgs) {
+ std::string program;
+ std::string programArgs;
+
+ // First assume the path to the program was specified with no
+ // arguments and with no quoting or escaping for spaces.
+ // Only bother doing this if there is non-whitespace.
+ if (!cmTrimWhitespace(command).empty()) {
+ program = cmSystemTools::FindProgram(command);
+ }
+
+ // If that failed then assume a command-line string was given
+ // and split the program part from the rest of the arguments.
+ if (program.empty()) {
+ if (cmSystemTools::SplitProgramFromArgs(command, program, programArgs)) {
+ if (!cmSystemTools::FileExists(program)) {
+ program = cmSystemTools::FindProgram(program);
+ }
+ }
+ }
+
+ if (!program.empty()) {
+ program += cmStrCat(';', programArgs);
+ }
+
+ status.GetMakefile().AddDefinition(var, program);
+ return true;
+ }
+
// split command given
std::vector<std::string> values;
@@ -96,6 +133,18 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
cmSystemTools::ParseWindowsCommandLine(command.c_str(), values);
}
+ if (arguments.Program) {
+ // check program exist
+ if (!cmSystemTools::FileExists(values.front())) {
+ auto result = cmSystemTools::FindProgram(values.front());
+ if (result.empty()) {
+ values.clear();
+ } else {
+ values.front() = result;
+ }
+ }
+ }
+
// preserve semicolons in arguments
std::for_each(values.begin(), values.end(), [](std::string& value) {
std::string::size_type pos = 0;