diff options
author | Brad King <brad.king@kitware.com> | 2007-02-01 16:45:37 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2007-02-01 16:45:37 (GMT) |
commit | d37abb6b5d013ffcdd88d001e95be4f08e19e4f7 (patch) | |
tree | 8c0e31081fb57e0a3e8624f4ab63a29c67eee22d | |
parent | f46704fefe53b81285a545e0214feda64e383648 (diff) | |
download | CMake-d37abb6b5d013ffcdd88d001e95be4f08e19e4f7.zip CMake-d37abb6b5d013ffcdd88d001e95be4f08e19e4f7.tar.gz CMake-d37abb6b5d013ffcdd88d001e95be4f08e19e4f7.tar.bz2 |
ENH: Added EscapeWindowsShellArgument and ParseWindowsCommandLine methods to cmSystemTools.
-rw-r--r-- | Source/cmSystemTools.cxx | 90 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 11 |
2 files changed, 100 insertions, 1 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 3144f5a..7af78fb 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -21,6 +21,7 @@ #include <cmsys/RegularExpression.hxx> #include <cmsys/Directory.hxx> +#include <cmsys/System.h> // support for realpath call #ifndef _WIN32 @@ -370,6 +371,95 @@ bool cmSystemTools::IsOff(const char* val) v == "N" || cmSystemTools::IsNOTFOUND(v.c_str()) || v == "IGNORE"); } +//---------------------------------------------------------------------------- +void cmSystemTools::ParseWindowsCommandLine(const char* command, + std::vector<std::string>& args) +{ + // See the MSDN document "Parsing C Command-Line Arguments" at + // http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx for rules + // of parsing the windows command line. + + bool in_argument = false; + bool in_quotes = false; + int backslashes = 0; + std::string arg; + for(const char* c = command;*c; ++c) + { + if(*c == '\\') + { + ++backslashes; + in_argument = true; + } + else if(*c == '"') + { + int backslash_pairs = backslashes >> 1; + int backslash_escaped = backslashes & 1; + arg.append(backslash_pairs, '\\'); + backslashes = 0; + if(backslash_escaped) + { + /* An odd number of backslashes precede this quote. + It is escaped. */ + arg.append(1, '"'); + } + else + { + /* An even number of backslashes precede this quote. + It is not escaped. */ + in_quotes = !in_quotes; + } + in_argument = true; + } + else + { + arg.append(backslashes, '\\'); + backslashes = 0; + if(isspace(*c)) + { + if(in_quotes) + { + arg.append(1, *c); + } + else if(in_argument) + { + args.push_back(arg); + arg = ""; + in_argument = false; + } + } + else + { + in_argument = true; + arg.append(1, *c); + } + } + } + arg.append(backslashes, '\\'); + if(in_argument) + { + args.push_back(arg); + } +} + +std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg, + int shell_flags) +{ + char local_buffer[1024]; + char* buffer = local_buffer; + int size = cmsysSystem_Shell_GetArgumentSizeForWindows(arg, shell_flags); + if(size > 1024) + { + buffer = new char[size]; + } + cmsysSystem_Shell_GetArgumentForWindows(arg, buffer, shell_flags); + std::string result(buffer); + if(buffer != local_buffer) + { + delete [] buffer; + } + return result; +} + std::vector<cmStdString> cmSystemTools::ParseArguments(const char* command) { std::vector<cmStdString> args; diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 4997bc3..6165d98 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -211,7 +211,16 @@ public: * Parse arguments out of a single string command */ static std::vector<cmStdString> ParseArguments(const char* command); - + + /** Parse arguments out of a windows command line string. */ + static void ParseWindowsCommandLine(const char* command, + std::vector<std::string>& args); + + /** Compute an escaped version of the given argument for use in a + windows shell. See kwsys/System.h.in for details. */ + static std::string EscapeWindowsShellArgument(const char* arg, + int shell_flags); + static void EnableMessages() { s_DisableMessages = false; } static void DisableMessages() { s_DisableMessages = true; } static void DisableRunCommandOutput() {s_DisableRunCommandOutput = true; } |