summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-09-14 11:39:08 (GMT)
committerKitware Robot <kwrobot@kitware.com>2017-09-14 11:39:24 (GMT)
commit01b9d039e71aaaf69cf23330fc4129e888e40ea0 (patch)
treeaa45ef102376d63ecc7789fedc87bb03dba2572f /Source
parent9c7bf6974f7e50e795e0ca960834909e14cdd7a0 (diff)
parent31f73eb12dd0888efc61c0333539d1354c7268ce (diff)
downloadCMake-01b9d039e71aaaf69cf23330fc4129e888e40ea0.zip
CMake-01b9d039e71aaaf69cf23330fc4129e888e40ea0.tar.gz
CMake-01b9d039e71aaaf69cf23330fc4129e888e40ea0.tar.bz2
Merge topic 'get_filename_component-fix-program-split'
31f73eb1 get_filename_component: Revise PROGRAM/PROGRAM_ARGS split semantics Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1251
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx25
-rw-r--r--Source/cmSystemTools.cxx50
-rw-r--r--Source/cmSystemTools.h5
3 files changed, 79 insertions, 1 deletions
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index c23684c..1b358ab 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -60,7 +60,30 @@ bool cmGetFilenameComponentCommand::InitialPass(
}
}
}
- cmSystemTools::SplitProgramFromArgs(filename, result, 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 (!cmSystemTools::TrimWhitespace(filename).empty()) {
+ result = cmSystemTools::FindProgram(filename);
+ }
+
+ // If that failed then assume a command-line string was given
+ // and split the program part from the rest of the arguments.
+ if (result.empty()) {
+ std::string program;
+ if (cmSystemTools::SplitProgramFromArgs(filename, program,
+ programArgs)) {
+ if (cmSystemTools::FileExists(program)) {
+ result = program;
+ } else {
+ result = cmSystemTools::FindProgram(program);
+ }
+ }
+ if (result.empty()) {
+ programArgs.clear();
+ }
+ }
} else if (args[2] == "EXT") {
result = cmSystemTools::GetFilenameExtension(filename);
} else if (args[2] == "NAME_WE") {
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index fd9fb5e..4118664 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -603,6 +603,56 @@ std::vector<std::string> cmSystemTools::ParseArguments(const char* command)
return args;
}
+bool cmSystemTools::SplitProgramFromArgs(std::string const& command,
+ std::string& program,
+ std::string& args)
+{
+ const char* c = command.c_str();
+
+ // Skip leading whitespace.
+ while (isspace(static_cast<unsigned char>(*c))) {
+ ++c;
+ }
+
+ // Parse one command-line element up to an unquoted space.
+ bool in_escape = false;
+ bool in_double = false;
+ bool in_single = false;
+ for (; *c; ++c) {
+ if (in_single) {
+ if (*c == '\'') {
+ in_single = false;
+ } else {
+ program += *c;
+ }
+ } else if (in_escape) {
+ in_escape = false;
+ program += *c;
+ } else if (*c == '\\') {
+ in_escape = true;
+ } else if (in_double) {
+ if (*c == '"') {
+ in_double = false;
+ } else {
+ program += *c;
+ }
+ } else if (*c == '"') {
+ in_double = true;
+ } else if (*c == '\'') {
+ in_single = true;
+ } else if (isspace(static_cast<unsigned char>(*c))) {
+ break;
+ } else {
+ program += *c;
+ }
+ }
+
+ // The remainder of the command line holds unparsed arguments.
+ args = c;
+
+ return !in_single && !in_escape && !in_double;
+}
+
size_t cmSystemTools::CalculateCommandLineLengthLimit()
{
size_t sz =
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 9bec361..e7082e6 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -255,6 +255,11 @@ public:
static void ParseUnixCommandLine(const char* command,
std::vector<std::string>& args);
+ /** Split a command-line string into the parsed command and the unparsed
+ arguments. Returns false on unfinished quoting or escaping. */
+ static bool SplitProgramFromArgs(std::string const& command,
+ std::string& program, std::string& args);
+
/**
* Handle response file in an argument list and return a new argument list
* **/