[PATCH] D29940: Allow use of spaces in Bugpoint ‘--compile-command’ argument
Owen Reynolds via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 20 07:02:17 PST 2017
gbreynoo updated this revision to Diff 89115.
gbreynoo added a comment.
Fixed code in response to MatzeB comments
https://reviews.llvm.org/D29940
Files:
ToolRunner.cpp
Index: ToolRunner.cpp
===================================================================
--- ToolRunner.cpp
+++ ToolRunner.cpp
@@ -355,37 +355,62 @@
// Tokenize the CommandLine to the command and the args to allow
// defining a full command line as the command instead of just the
// executed program. We cannot just pass the whole string after the command
-// as a single argument because then program sees only a single
+// as a single argument because then the program sees only a single
// command line argument (with spaces in it: "foo bar" instead
// of "foo" and "bar").
//
-// code borrowed from:
-// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
+// Spaces are used as a delimiter; however repeated, leading, and trailing
+// whitespace are ignored. Simple escaping is allowed via the '\'
+// character, as seen below:
+//
+// Two consecutive '\' evaluate to a single '\'.
+// A space after a '\' evaluates to a space that is not interpreted as a
+// delimiter.
+// Any other instances of the '\' character are removed.
+//
+// Example:
+// '\\' -> '\'
+// '\ ' -> ' '
+// 'exa\mple' -> 'example'
+//
static void lexCommand(std::string &Message, const std::string &CommandLine,
std::string &CmdPath, std::vector<std::string> &Args) {
- std::string Command = "";
- std::string delimiters = " ";
-
- std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
- std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
+ std::string Token;
+ std::string Command;
+ bool FoundPath = false;
+
+ // first argument is the PATH.
+ // Skip repeated whitespace, leading whitespace and trailing whitespace.
+ for (std::size_t Pos = 0u; Pos <= CommandLine.size(); ++Pos) {
+ if ('\\' == CommandLine[Pos]) {
+ if (Pos + 1 < CommandLine.size())
+ Token.push_back(CommandLine[++Pos]);
- while (std::string::npos != pos || std::string::npos != lastPos) {
- std::string token = CommandLine.substr(lastPos, pos - lastPos);
- if (Command == "")
- Command = token;
- else
- Args.push_back(token);
- // Skip delimiters. Note the "not_of"
- lastPos = CommandLine.find_first_not_of(delimiters, pos);
- // Find next "non-delimiter"
- pos = CommandLine.find_first_of(delimiters, lastPos);
+ continue;
+ }
+ if (' ' == CommandLine[Pos] || CommandLine.size() == Pos) {
+ if (Token.empty())
+ continue;
+
+ if (!FoundPath) {
+ Command = Token;
+ FoundPath = true;
+ Token.clear();
+ continue;
+ }
+
+ Args.push_back(Token);
+ Token.clear();
+ continue;
+ }
+ Token.push_back(CommandLine[Pos]);
}
auto Path = sys::findProgramByName(Command);
if (!Path) {
- Message = std::string("Cannot find '") + Command + "' in PATH: " +
- Path.getError().message() + "\n";
+ Message = std::string("Cannot find '") + Command +
+ "' in PATH: " + Path.getError().message() + "\n";
return;
}
CmdPath = *Path;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29940.89115.patch
Type: text/x-patch
Size: 3154 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170220/c2e139d8/attachment.bin>
More information about the llvm-commits
mailing list