summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-10-26 20:29:27 +0000
committerReid Kleckner <rnk@google.com>2016-10-26 20:29:27 +0000
commit9b4e8286785f538e73d2e3eaa96f88c3d98b9960 (patch)
tree2ebfe6e5c30d111e38ccf609b17bf6c33d744249 /utils
parent9434af136bb0e553dfd1894a86fd14497615f0f9 (diff)
downloadllvm-9b4e8286785f538e73d2e3eaa96f88c3d98b9960.tar.gz
[lit] Work around Windows MSys command line tokenization bug
Summary: This will allow us to revert LLD r284768, which added spaces to get MSys echo to print what we want. Reviewers: ruiu, inglorion, rafael Subscribers: modocache, llvm-commits Differential Revision: https://reviews.llvm.org/D26009 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285237 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/lit/lit/TestRunner.py61
1 files changed, 61 insertions, 0 deletions
diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py
index 41af9da26385..b242f8fb0215 100644
--- a/utils/lit/lit/TestRunner.py
+++ b/utils/lit/lit/TestRunner.py
@@ -140,6 +140,62 @@ def executeShCmd(cmd, shenv, results, timeout=0):
return (finalExitCode, timeoutInfo)
+def quote_windows_command(seq):
+ """
+ Reimplement Python's private subprocess.list2cmdline for MSys compatibility
+
+ Based on CPython implementation here:
+ https://hg.python.org/cpython/file/849826a900d2/Lib/subprocess.py#l422
+
+ Some core util distributions (MSys) don't tokenize command line arguments
+ the same way that MSVC CRT does. Lit rolls its own quoting logic similar to
+ the stock CPython logic to paper over these quoting and tokenization rule
+ differences.
+
+ We use the same algorithm from MSDN as CPython
+ (http://msdn.microsoft.com/en-us/library/17w5ykft.aspx), but we treat more
+ characters as needing quoting, such as double quotes themselves.
+ """
+ result = []
+ needquote = False
+ for arg in seq:
+ bs_buf = []
+
+ # Add a space to separate this argument from the others
+ if result:
+ result.append(' ')
+
+ # This logic differs from upstream list2cmdline.
+ needquote = (" " in arg) or ("\t" in arg) or ("\"" in arg) or not arg
+ if needquote:
+ result.append('"')
+
+ for c in arg:
+ if c == '\\':
+ # Don't know if we need to double yet.
+ bs_buf.append(c)
+ elif c == '"':
+ # Double backslashes.
+ result.append('\\' * len(bs_buf)*2)
+ bs_buf = []
+ result.append('\\"')
+ else:
+ # Normal char
+ if bs_buf:
+ result.extend(bs_buf)
+ bs_buf = []
+ result.append(c)
+
+ # Add remaining backslashes, if any.
+ if bs_buf:
+ result.extend(bs_buf)
+
+ if needquote:
+ result.extend(bs_buf)
+ result.append('"')
+
+ return ''.join(result)
+
def _executeShCmd(cmd, shenv, results, timeoutHelper):
if timeoutHelper.timeoutReached():
# Prevent further recursion if the timeout has been hit
@@ -315,6 +371,11 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
named_temp_files.append(f.name)
args[i] = f.name
+ # On Windows, do our own command line quoting for better compatibility
+ # with some core utility distributions.
+ if kIsWindows:
+ args = quote_windows_command(args)
+
try:
procs.append(subprocess.Popen(args, cwd=cmd_shenv.cwd,
executable = executable,