| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """ Set of basic operations/utilities that are used by the build. """ | 5 """ Set of basic operations/utilities that are used by the build. """ |
| 6 | 6 |
| 7 from contextlib import contextmanager | 7 from contextlib import contextmanager |
| 8 import ast | 8 import ast |
| 9 import base64 | 9 import base64 |
| 10 import cStringIO | 10 import cStringIO |
| (...skipping 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2032 return False | 2032 return False |
| 2033 # Matches e.g. "cl_x86 = path/to/clang-cl.exe" | 2033 # Matches e.g. "cl_x86 = path/to/clang-cl.exe" |
| 2034 clang_cl_re = re.compile( | 2034 clang_cl_re = re.compile( |
| 2035 r'^cl_x\d\d\s+\=\s+(?P<compiler_path>[^ ]+)\s.*$', | 2035 r'^cl_x\d\d\s+\=\s+(?P<compiler_path>[^ ]+)\s.*$', |
| 2036 re.VERBOSE) | 2036 re.VERBOSE) |
| 2037 for line in open(build_file): | 2037 for line in open(build_file): |
| 2038 m = clang_cl_re.match(line) | 2038 m = clang_cl_re.match(line) |
| 2039 if m: | 2039 if m: |
| 2040 return 'clang' in m.group('compiler_path') | 2040 return 'clang' in m.group('compiler_path') |
| 2041 return False | 2041 return False |
| 2042 |
| 2043 # Everything below this point has been copied from the Python-3.3 sources with |
| 2044 # the following modifications: |
| 2045 # |
| 2046 # The variable, "dir", was renamed to "pathcomp", since "dir" is a Python |
| 2047 # reserved word. |
| 2048 def Which(cmd, mode=os.F_OK | os.X_OK, path=None): |
| 2049 """Given a command, mode, and a PATH string, return the path which |
| 2050 conforms to the given mode on the PATH, or None if there is no such |
| 2051 file. |
| 2052 `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result |
| 2053 of os.environ.get("PATH"), or can be overridden with a custom search |
| 2054 path. |
| 2055 """ |
| 2056 # Check that a given file can be accessed with the correct mode. |
| 2057 # Additionally check that `file` is not a directory, as on Windows |
| 2058 # directories pass the os.access check. |
| 2059 def _access_check(fn, mode): |
| 2060 return (os.path.exists(fn) and os.access(fn, mode) |
| 2061 and not os.path.isdir(fn)) |
| 2062 |
| 2063 # Short circuit. If we're given a full path which matches the mode |
| 2064 # and it exists, we're done here. |
| 2065 if _access_check(cmd, mode): |
| 2066 return cmd |
| 2067 |
| 2068 path = (path or os.environ.get("PATH", os.defpath)).split(os.pathsep) |
| 2069 |
| 2070 if sys.platform == "win32": |
| 2071 # The current directory takes precedence on Windows. |
| 2072 if not os.curdir in path: |
| 2073 path.insert(0, os.curdir) |
| 2074 |
| 2075 # PATHEXT is necessary to check on Windows. |
| 2076 pathext = os.environ.get("PATHEXT", "").split(os.pathsep) |
| 2077 # See if the given file matches any of the expected path extensions. |
| 2078 # This will allow us to short circuit when given "python.exe". |
| 2079 matches = [cmd for ext in pathext if cmd.lower().endswith(ext.lower())] |
| 2080 # If it does match, only test that one, otherwise we have to try |
| 2081 # others. |
| 2082 files = [cmd] if matches else [cmd + ext.lower() for ext in pathext] |
| 2083 else: |
| 2084 # On other platforms you don't have things like PATHEXT to tell you |
| 2085 # what file suffixes are executable, so just pass on cmd as-is. |
| 2086 files = [cmd] |
| 2087 |
| 2088 seen = set() |
| 2089 for pathcomp in path: |
| 2090 pathcomp = os.path.normcase(pathcomp) |
| 2091 if not pathcomp in seen: |
| 2092 seen.add(pathcomp) |
| 2093 for thefile in files: |
| 2094 name = os.path.join(pathcomp, thefile) |
| 2095 if _access_check(name, mode): |
| 2096 return name |
| 2097 return None |
| OLD | NEW |