from __future__ import print_function
import errno
import itertools
import math
import numbers
import os
import platform
import signal
import subprocess
import sys
import threading
def is_string(value):
try:
return isinstance(value, basestring)
except NameError:
return isinstance(value, str)
def pythonize_bool(value):
if value is None:
return False
if type(value) is bool:
return value
if isinstance(value, numbers.Number):
return value != 0
if is_string(value):
if value.lower() in ('1', 'true', 'on', 'yes'):
return True
if value.lower() in ('', '0', 'false', 'off', 'no'):
return False
raise ValueError('"{}" is not a valid boolean'.format(value))
def make_word_regex(word):
return r'\b' + word + r'\b'
def to_bytes(s):
if isinstance(s, bytes):
return s
return s.encode('utf-8')
def to_string(b):
if isinstance(b, str):
return b
if isinstance(b, bytes):
try:
return b.decode('utf-8')
except UnicodeDecodeError:
return str(b)
try:
return b.encode('utf-8')
except AttributeError:
raise TypeError('not sure how to convert %s to %s' % (type(b), str))
def to_unicode(s):
if isinstance(s, bytes):
return s.decode('utf-8')
return s
def usable_core_count():
try:
n = len(os.sched_getaffinity(0))
except AttributeError:
n = os.cpu_count() or 1
if platform.system() == 'Windows':
return min(n, 60)
return n
def mkdir(path):
try:
if platform.system() == 'Windows':
from ctypes import windll
from ctypes import GetLastError, WinError
path = os.path.abspath(path)
path = path.replace('/', '\\')
NTPath = to_unicode(r'\\?\%s' % path)
if not windll.kernel32.CreateDirectoryW(NTPath, None):
raise WinError(GetLastError())
else:
os.mkdir(path)
except OSError:
e = sys.exc_info()[1]
if e.errno != errno.EEXIST:
raise
def mkdir_p(path):
if not path or os.path.exists(path):
return
parent = os.path.dirname(path)
if parent != path:
mkdir_p(parent)
mkdir(path)
def listdir_files(dirname, suffixes=None, exclude_filenames=None):
if exclude_filenames is None:
exclude_filenames = set()
if suffixes is None:
suffixes = {''}
for filename in os.listdir(dirname):
if (os.path.isdir(os.path.join(dirname, filename)) or
filename.startswith('.') or
filename in exclude_filenames or
not any(filename.endswith(sfx) for sfx in suffixes)):
continue
yield filename
def which(command, paths=None):
if paths is None:
paths = os.environ.get('PATH', '')
if os.path.isabs(command) and os.path.isfile(command):
return os.path.normcase(os.path.normpath(command))
if not paths:
paths = os.defpath
if os.pathsep == ';':
pathext = os.environ.get('PATHEXT', '').split(';')
else:
pathext = ['']
for path in paths.split(os.pathsep):
for ext in pathext:
p = os.path.join(path, command + ext)
if os.path.exists(p) and not os.path.isdir(p):
return os.path.normcase(os.path.abspath(p))
return None
def checkToolsPath(dir, tools):
for tool in tools:
if not os.path.exists(os.path.join(dir, tool)):
return False
return True
def whichTools(tools, paths):
for path in paths.split(os.pathsep):
if checkToolsPath(path, tools):
return path
return None
def printHistogram(items, title='Items'):
items.sort(key=lambda item: item[1])
maxValue = max([v for _, v in items])
power = int(math.ceil(math.log(maxValue, 10)))
for inc in itertools.cycle((5, 2, 2.5, 1)):
barH = inc * 10**power
N = int(math.ceil(maxValue / barH))
if N > 10:
break
elif inc == 1:
power -= 1
histo = [set() for i in range(N)]
for name, v in items:
bin = min(int(N * v / maxValue), N - 1)
histo[bin].add(name)
barW = 40
hr = '-' * (barW + 34)
print('Slowest %s:' % title)
print(hr)
for name, value in reversed(items[-20:]):
print('%.2fs: %s' % (value, name))
print('\n%s Times:' % title)
print(hr)
pDigits = int(math.ceil(math.log(maxValue, 10)))
pfDigits = max(0, 3 - pDigits)
if pfDigits:
pDigits += pfDigits + 1
cDigits = int(math.ceil(math.log(len(items), 10)))
print('[%s] :: [%s] :: [%s]' % ('Range'.center((pDigits + 1) * 2 + 3),
'Percentage'.center(barW),
'Count'.center(cDigits * 2 + 1)))
print(hr)
for i, row in reversed(list(enumerate(histo))):
pct = float(len(row)) / len(items)
w = int(barW * pct)
print('[%*.*fs,%*.*fs) :: [%s%s] :: [%*d/%*d]' % (
pDigits, pfDigits, i * barH, pDigits, pfDigits, (i + 1) * barH,
'*' * w, ' ' * (barW - w), cDigits, len(row), cDigits, len(items)))
print(hr)
class ExecuteCommandTimeoutException(Exception):
def __init__(self, msg, out, err, exitCode):
assert isinstance(msg, str)
assert isinstance(out, str)
assert isinstance(err, str)
assert isinstance(exitCode, int)
self.msg = msg
self.out = out
self.err = err
self.exitCode = exitCode
kUseCloseFDs = not (platform.system() == 'Windows')
def executeCommand(command, cwd=None, env=None, input=None, timeout=0,
redirect_stderr=False):
if input is not None:
input = to_bytes(input)
err_out = subprocess.STDOUT if redirect_stderr else subprocess.PIPE
p = subprocess.Popen(command, cwd=cwd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=err_out,
env=env, close_fds=kUseCloseFDs)
timerObject = None
hitTimeOut = [False]
try:
if timeout > 0:
def killProcess():
hitTimeOut[0] = True
killProcessAndChildren(p.pid)
timerObject = threading.Timer(timeout, killProcess)
timerObject.start()
out, err = p.communicate(input=input)
exitCode = p.wait()
finally:
if timerObject != None:
timerObject.cancel()
out = to_string(out)
err = '' if redirect_stderr else to_string(err)
if hitTimeOut[0]:
raise ExecuteCommandTimeoutException(
msg='Reached timeout of {} seconds'.format(timeout),
out=out,
err=err,
exitCode=exitCode
)
if exitCode == -signal.SIGINT:
raise KeyboardInterrupt
return out, err, exitCode
def isMacOSTriple(target_triple):
return 'darwin' in target_triple or 'macos' in target_triple
def usePlatformSdkOnDarwin(config, lit_config):
if isMacOSTriple(config.target_triple):
try:
cmd = subprocess.Popen(['xcrun', '--show-sdk-path', '--sdk', 'macosx'],
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.decode()
lit_config.note('using SDKROOT: %r' % sdk_path)
config.environment['SDKROOT'] = sdk_path
def findPlatformSdkVersionOnMacOS(config, lit_config):
if isMacOSTriple(config.target_triple):
try:
cmd = subprocess.Popen(['xcrun', '--show-sdk-version', '--sdk', 'macosx'],
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:
return out.decode()
return None
def killProcessAndChildrenIsSupported():
if platform.system() == 'AIX':
return (True, "")
try:
import psutil return (True, "")
except ImportError:
return (False, "Requires the Python psutil module but it could"
" not be found. Try installing it via pip or via"
" your operating system's package manager.")
def killProcessAndChildren(pid):
if platform.system() == 'AIX':
subprocess.call('kill -kill $(ps -o pid= -L{})'.format(pid), shell=True)
else:
import psutil
try:
psutilProc = psutil.Process(pid)
try:
children_iterator = psutilProc.children(recursive=True)
except AttributeError:
children_iterator = psutilProc.get_children(recursive=True)
for child in children_iterator:
try:
child.kill()
except psutil.NoSuchProcess:
pass
psutilProc.kill()
except psutil.NoSuchProcess:
pass