[lit] Fix bug where ``lit.util.which()`` would return a directory
[oota-llvm.git] / utils / lit / lit / util.py
index 2b1010c1870cef3ed60a0d1e57e769ac106d5e35..224509ab840b610bf773b4f85eca8911f6f97720 100644 (file)
@@ -7,6 +7,21 @@ import signal
 import subprocess
 import sys
 
+def to_bytes(str):
+    # Encode to UTF-8 to get binary data.
+    return str.encode('utf-8')
+
+def to_string(bytes):
+    if isinstance(bytes, str):
+        return bytes
+    return to_bytes(bytes)
+
+def convert_string(bytes):
+    try:
+        return to_string(bytes.decode('utf-8'))
+    except UnicodeError:
+        return str(bytes)
+
 def detectCPUs():
     """
     Detects the number of CPUs on a system. Cribbed from pp.
@@ -33,7 +48,7 @@ def mkdir_p(path):
     if not path or os.path.exists(path):
         return
 
-    parent = os.path.dirname(path) 
+    parent = os.path.dirname(path)
     if parent != path:
         mkdir_p(parent)
 
@@ -51,7 +66,7 @@ def capture(args, env=None):
     p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                          env=env)
     out,_ = p.communicate()
-    return out
+    return convert_string(out)
 
 def which(command, paths = None):
     """which(command, [paths]) - Look up the given command in the paths string
@@ -79,7 +94,7 @@ def which(command, paths = None):
     for path in paths.split(os.pathsep):
         for ext in pathext:
             p = os.path.join(path, command + ext)
-            if os.path.exists(p):
+            if os.path.exists(p) and not os.path.isdir(p):
                 return p
 
     return None
@@ -143,13 +158,13 @@ def printHistogram(items, title = 'Items'):
 # Close extra file handles on UNIX (on Windows this cannot be done while
 # also redirecting input).
 kUseCloseFDs = not (platform.system() == 'Windows')
-def executeCommand(command, cwd=None, env=None):
+def executeCommand(command, cwd=None, env=None, input=None):
     p = subprocess.Popen(command, cwd=cwd,
                          stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          env=env, close_fds=kUseCloseFDs)
-    out,err = p.communicate()
+    out,err = p.communicate(input=input)
     exitCode = p.wait()
 
     # Detect Ctrl-C in subprocess.
@@ -157,13 +172,24 @@ def executeCommand(command, cwd=None, env=None):
         raise KeyboardInterrupt
 
     # Ensure the resulting output is always of string type.
-    try:
-        out = str(out.decode('ascii'))
-    except:
-        out = str(out)
-    try:
-        err = str(err.decode('ascii'))
-    except:
-        err = str(err)
+    out = convert_string(out)
+    err = convert_string(err)
 
     return out, err, exitCode
+
+def usePlatformSdkOnDarwin(config, lit_config):
+    # On Darwin, support relocatable SDKs by providing Clang with a
+    # default system root path.
+    if 'darwin' in config.target_triple:
+        try:
+            cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
+                                   stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            out, err = cmd.communicate()
+            out = out.strip()
+            res = cmd.wait()
+        except OSError:
+            res = -1
+        if res == 0 and out:
+            sdk_path = out
+            lit_config.note('using SDKROOT: %r' % sdk_path)
+            config.environment['SDKROOT'] = sdk_path