summaryrefslogtreecommitdiff
path: root/waflib/Utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'waflib/Utils.py')
-rw-r--r--waflib/Utils.py615
1 files changed, 615 insertions, 0 deletions
diff --git a/waflib/Utils.py b/waflib/Utils.py
new file mode 100644
index 0000000..924d1f1
--- /dev/null
+++ b/waflib/Utils.py
@@ -0,0 +1,615 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+from __future__ import with_statement
+import atexit,os,sys,errno,inspect,re,datetime,platform,base64,signal,functools,time
+try:
+ import cPickle
+except ImportError:
+ import pickle as cPickle
+if os.name=='posix'and sys.version_info[0]<3:
+ try:
+ import subprocess32 as subprocess
+ except ImportError:
+ import subprocess
+else:
+ import subprocess
+try:
+ TimeoutExpired=subprocess.TimeoutExpired
+except AttributeError:
+ class TimeoutExpired(Exception):
+ pass
+from collections import deque,defaultdict
+try:
+ import _winreg as winreg
+except ImportError:
+ try:
+ import winreg
+ except ImportError:
+ winreg=None
+from waflib import Errors
+try:
+ from hashlib import md5
+except ImportError:
+ try:
+ from md5 import md5
+ except ImportError:
+ pass
+try:
+ import threading
+except ImportError:
+ if not'JOBS'in os.environ:
+ os.environ['JOBS']='1'
+ class threading(object):
+ pass
+ class Lock(object):
+ def acquire(self):
+ pass
+ def release(self):
+ pass
+ threading.Lock=threading.Thread=Lock
+SIG_NIL='SIG_NIL_SIG_NIL_'.encode()
+O644=420
+O755=493
+rot_chr=['\\','|','/','-']
+rot_idx=0
+class ordered_iter_dict(dict):
+ def __init__(self,*k,**kw):
+ self.lst=deque()
+ dict.__init__(self,*k,**kw)
+ def clear(self):
+ dict.clear(self)
+ self.lst=deque()
+ def __setitem__(self,key,value):
+ if key in dict.keys(self):
+ self.lst.remove(key)
+ dict.__setitem__(self,key,value)
+ self.lst.append(key)
+ def __delitem__(self,key):
+ dict.__delitem__(self,key)
+ try:
+ self.lst.remove(key)
+ except ValueError:
+ pass
+ def __iter__(self):
+ return reversed(self.lst)
+ def keys(self):
+ return reversed(self.lst)
+class lru_node(object):
+ __slots__=('next','prev','key','val')
+ def __init__(self):
+ self.next=self
+ self.prev=self
+ self.key=None
+ self.val=None
+class lru_cache(object):
+ __slots__=('maxlen','table','head')
+ def __init__(self,maxlen=100):
+ self.maxlen=maxlen
+ self.table={}
+ self.head=lru_node()
+ self.head.next=self.head
+ self.head.prev=self.head
+ def __getitem__(self,key):
+ node=self.table[key]
+ if node is self.head:
+ return node.val
+ node.prev.next=node.next
+ node.next.prev=node.prev
+ node.next=self.head.next
+ node.prev=self.head
+ self.head=node.next.prev=node.prev.next=node
+ return node.val
+ def __setitem__(self,key,val):
+ if key in self.table:
+ node=self.table[key]
+ node.val=val
+ self.__getitem__(key)
+ else:
+ if len(self.table)<self.maxlen:
+ node=lru_node()
+ node.prev=self.head
+ node.next=self.head.next
+ node.prev.next=node.next.prev=node
+ else:
+ node=self.head=self.head.next
+ try:
+ del self.table[node.key]
+ except KeyError:
+ pass
+ node.key=key
+ node.val=val
+ self.table[key]=node
+class lazy_generator(object):
+ def __init__(self,fun,params):
+ self.fun=fun
+ self.params=params
+ def __iter__(self):
+ return self
+ def __next__(self):
+ try:
+ it=self.it
+ except AttributeError:
+ it=self.it=self.fun(*self.params)
+ return next(it)
+ next=__next__
+is_win32=os.sep=='\\'or sys.platform=='win32'
+def readf(fname,m='r',encoding='latin-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ m+='b'
+ with open(fname,m)as f:
+ txt=f.read()
+ if encoding:
+ txt=txt.decode(encoding)
+ else:
+ txt=txt.decode()
+ else:
+ with open(fname,m)as f:
+ txt=f.read()
+ return txt
+def writef(fname,data,m='w',encoding='latin-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ data=data.encode(encoding)
+ m+='b'
+ with open(fname,m)as f:
+ f.write(data)
+def h_file(fname):
+ m=md5()
+ with open(fname,'rb')as f:
+ while fname:
+ fname=f.read(200000)
+ m.update(fname)
+ return m.digest()
+def readf_win32(f,m='r',encoding='latin-1'):
+ flags=os.O_NOINHERIT|os.O_RDONLY
+ if'b'in m:
+ flags|=os.O_BINARY
+ if'+'in m:
+ flags|=os.O_RDWR
+ try:
+ fd=os.open(f,flags)
+ except OSError:
+ raise IOError('Cannot read from %r'%f)
+ if sys.hexversion>0x3000000 and not'b'in m:
+ m+='b'
+ with os.fdopen(fd,m)as f:
+ txt=f.read()
+ if encoding:
+ txt=txt.decode(encoding)
+ else:
+ txt=txt.decode()
+ else:
+ with os.fdopen(fd,m)as f:
+ txt=f.read()
+ return txt
+def writef_win32(f,data,m='w',encoding='latin-1'):
+ if sys.hexversion>0x3000000 and not'b'in m:
+ data=data.encode(encoding)
+ m+='b'
+ flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT
+ if'b'in m:
+ flags|=os.O_BINARY
+ if'+'in m:
+ flags|=os.O_RDWR
+ try:
+ fd=os.open(f,flags)
+ except OSError:
+ raise OSError('Cannot write to %r'%f)
+ with os.fdopen(fd,m)as f:
+ f.write(data)
+def h_file_win32(fname):
+ try:
+ fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
+ except OSError:
+ raise OSError('Cannot read from %r'%fname)
+ m=md5()
+ with os.fdopen(fd,'rb')as f:
+ while fname:
+ fname=f.read(200000)
+ m.update(fname)
+ return m.digest()
+readf_unix=readf
+writef_unix=writef
+h_file_unix=h_file
+if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000:
+ readf=readf_win32
+ writef=writef_win32
+ h_file=h_file_win32
+try:
+ x=''.encode('hex')
+except LookupError:
+ import binascii
+ def to_hex(s):
+ ret=binascii.hexlify(s)
+ if not isinstance(ret,str):
+ ret=ret.decode('utf-8')
+ return ret
+else:
+ def to_hex(s):
+ return s.encode('hex')
+to_hex.__doc__="""
+Return the hexadecimal representation of a string
+
+:param s: string to convert
+:type s: string
+"""
+def listdir_win32(s):
+ if not s:
+ try:
+ import ctypes
+ except ImportError:
+ return[x+':\\'for x in'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
+ else:
+ dlen=4
+ maxdrives=26
+ buf=ctypes.create_string_buffer(maxdrives*dlen)
+ ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf))
+ return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))]
+ if len(s)==2 and s[1]==":":
+ s+=os.sep
+ if not os.path.isdir(s):
+ e=OSError('%s is not a directory'%s)
+ e.errno=errno.ENOENT
+ raise e
+ return os.listdir(s)
+listdir=os.listdir
+if is_win32:
+ listdir=listdir_win32
+def num2ver(ver):
+ if isinstance(ver,str):
+ ver=tuple(ver.split('.'))
+ if isinstance(ver,tuple):
+ ret=0
+ for i in range(4):
+ if i<len(ver):
+ ret+=256**(3-i)*int(ver[i])
+ return ret
+ return ver
+def to_list(val):
+ if isinstance(val,str):
+ return val.split()
+ else:
+ return val
+def console_encoding():
+ try:
+ import ctypes
+ except ImportError:
+ pass
+ else:
+ try:
+ codepage=ctypes.windll.kernel32.GetConsoleCP()
+ except AttributeError:
+ pass
+ else:
+ if codepage:
+ return'cp%d'%codepage
+ return sys.stdout.encoding or('cp1252'if is_win32 else'latin-1')
+def split_path_unix(path):
+ return path.split('/')
+def split_path_cygwin(path):
+ if path.startswith('//'):
+ ret=path.split('/')[2:]
+ ret[0]='/'+ret[0]
+ return ret
+ return path.split('/')
+re_sp=re.compile('[/\\\\]+')
+def split_path_win32(path):
+ if path.startswith('\\\\'):
+ ret=re_sp.split(path)[1:]
+ ret[0]='\\\\'+ret[0]
+ if ret[0]=='\\\\?':
+ return ret[1:]
+ return ret
+ return re_sp.split(path)
+msysroot=None
+def split_path_msys(path):
+ if path.startswith(('/','\\'))and not path.startswith(('//','\\\\')):
+ global msysroot
+ if not msysroot:
+ msysroot=subprocess.check_output(['cygpath','-w','/']).decode(sys.stdout.encoding or'latin-1')
+ msysroot=msysroot.strip()
+ path=os.path.normpath(msysroot+os.sep+path)
+ return split_path_win32(path)
+if sys.platform=='cygwin':
+ split_path=split_path_cygwin
+elif is_win32:
+ if os.environ.get('MSYSTEM'):
+ split_path=split_path_msys
+ else:
+ split_path=split_path_win32
+else:
+ split_path=split_path_unix
+split_path.__doc__="""
+Splits a path by / or \\; do not confuse this function with with ``os.path.split``
+
+:type path: string
+:param path: path to split
+:return: list of string
+"""
+def check_dir(path):
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if not os.path.isdir(path):
+ raise Errors.WafError('Cannot create the folder %r'%path,ex=e)
+def check_exe(name,env=None):
+ if not name:
+ raise ValueError('Cannot execute an empty string!')
+ def is_exe(fpath):
+ return os.path.isfile(fpath)and os.access(fpath,os.X_OK)
+ fpath,fname=os.path.split(name)
+ if fpath and is_exe(name):
+ return os.path.abspath(name)
+ else:
+ env=env or os.environ
+ for path in env['PATH'].split(os.pathsep):
+ path=path.strip('"')
+ exe_file=os.path.join(path,name)
+ if is_exe(exe_file):
+ return os.path.abspath(exe_file)
+ return None
+def def_attrs(cls,**kw):
+ for k,v in kw.items():
+ if not hasattr(cls,k):
+ setattr(cls,k,v)
+def quote_define_name(s):
+ fu=re.sub('[^a-zA-Z0-9]','_',s)
+ fu=re.sub('_+','_',fu)
+ fu=fu.upper()
+ return fu
+re_sh=re.compile('\\s|\'|"')
+def shell_escape(cmd):
+ if isinstance(cmd,str):
+ return cmd
+ return' '.join(repr(x)if re_sh.search(x)else x for x in cmd)
+def h_list(lst):
+ return md5(repr(lst).encode()).digest()
+def h_fun(fun):
+ try:
+ return fun.code
+ except AttributeError:
+ if isinstance(fun,functools.partial):
+ code=list(fun.args)
+ code.extend(sorted(fun.keywords.items()))
+ code.append(h_fun(fun.func))
+ fun.code=h_list(code)
+ return fun.code
+ try:
+ h=inspect.getsource(fun)
+ except EnvironmentError:
+ h='nocode'
+ try:
+ fun.code=h
+ except AttributeError:
+ pass
+ return h
+def h_cmd(ins):
+ if isinstance(ins,str):
+ ret=ins
+ elif isinstance(ins,list)or isinstance(ins,tuple):
+ ret=str([h_cmd(x)for x in ins])
+ else:
+ ret=str(h_fun(ins))
+ if sys.hexversion>0x3000000:
+ ret=ret.encode('latin-1','xmlcharrefreplace')
+ return ret
+reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
+def subst_vars(expr,params):
+ def repl_var(m):
+ if m.group(1):
+ return'\\'
+ if m.group(2):
+ return'$'
+ try:
+ return params.get_flat(m.group(3))
+ except AttributeError:
+ return params[m.group(3)]
+ return reg_subst.sub(repl_var,expr)
+def destos_to_binfmt(key):
+ if key=='darwin':
+ return'mac-o'
+ elif key in('win32','cygwin','uwin','msys'):
+ return'pe'
+ return'elf'
+def unversioned_sys_platform():
+ s=sys.platform
+ if s.startswith('java'):
+ from java.lang import System
+ s=System.getProperty('os.name')
+ if s=='Mac OS X':
+ return'darwin'
+ elif s.startswith('Windows '):
+ return'win32'
+ elif s=='OS/2':
+ return'os2'
+ elif s=='HP-UX':
+ return'hp-ux'
+ elif s in('SunOS','Solaris'):
+ return'sunos'
+ else:s=s.lower()
+ if s=='powerpc':
+ return'darwin'
+ if s=='win32'or s=='os2':
+ return s
+ if s=='cli'and os.name=='nt':
+ return'win32'
+ return re.split('\d+$',s)[0]
+def nada(*k,**kw):
+ pass
+class Timer(object):
+ def __init__(self):
+ self.start_time=self.now()
+ def __str__(self):
+ delta=self.now()-self.start_time
+ if not isinstance(delta,datetime.timedelta):
+ delta=datetime.timedelta(seconds=delta)
+ days=delta.days
+ hours,rem=divmod(delta.seconds,3600)
+ minutes,seconds=divmod(rem,60)
+ seconds+=delta.microseconds*1e-6
+ result=''
+ if days:
+ result+='%dd'%days
+ if days or hours:
+ result+='%dh'%hours
+ if days or hours or minutes:
+ result+='%dm'%minutes
+ return'%s%.3fs'%(result,seconds)
+ def now(self):
+ return datetime.datetime.utcnow()
+ if hasattr(time,'perf_counter'):
+ def now(self):
+ return time.perf_counter()
+def read_la_file(path):
+ sp=re.compile(r'^([^=]+)=\'(.*)\'$')
+ dc={}
+ for line in readf(path).splitlines():
+ try:
+ _,left,right,_=sp.split(line.strip())
+ dc[left]=right
+ except ValueError:
+ pass
+ return dc
+def run_once(fun):
+ cache={}
+ def wrap(*k):
+ try:
+ return cache[k]
+ except KeyError:
+ ret=fun(*k)
+ cache[k]=ret
+ return ret
+ wrap.__cache__=cache
+ wrap.__name__=fun.__name__
+ return wrap
+def get_registry_app_path(key,filename):
+ if not winreg:
+ return None
+ try:
+ result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0])
+ except OSError:
+ pass
+ else:
+ if os.path.isfile(result):
+ return result
+def lib64():
+ if os.sep=='/':
+ if platform.architecture()[0]=='64bit':
+ if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'):
+ return'64'
+ return''
+def sane_path(p):
+ return os.path.abspath(os.path.expanduser(p))
+process_pool=[]
+def get_process():
+ try:
+ return process_pool.pop()
+ except IndexError:
+ filepath=os.path.dirname(os.path.abspath(__file__))+os.sep+'processor.py'
+ cmd=[sys.executable,'-c',readf(filepath)]
+ return subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE,bufsize=0)
+def run_prefork_process(cmd,kwargs,cargs):
+ if not'env'in kwargs:
+ kwargs['env']=dict(os.environ)
+ try:
+ obj=base64.b64encode(cPickle.dumps([cmd,kwargs,cargs]))
+ except(TypeError,AttributeError):
+ return run_regular_process(cmd,kwargs,cargs)
+ proc=get_process()
+ if not proc:
+ return run_regular_process(cmd,kwargs,cargs)
+ proc.stdin.write(obj)
+ proc.stdin.write('\n'.encode())
+ proc.stdin.flush()
+ obj=proc.stdout.readline()
+ if not obj:
+ raise OSError('Preforked sub-process %r died'%proc.pid)
+ process_pool.append(proc)
+ lst=cPickle.loads(base64.b64decode(obj))
+ assert len(lst)==5
+ ret,out,err,ex,trace=lst
+ if ex:
+ if ex=='OSError':
+ raise OSError(trace)
+ elif ex=='ValueError':
+ raise ValueError(trace)
+ elif ex=='TimeoutExpired':
+ exc=TimeoutExpired(cmd,timeout=cargs['timeout'],output=out)
+ exc.stderr=err
+ raise exc
+ else:
+ raise Exception(trace)
+ return ret,out,err
+def lchown(path,user=-1,group=-1):
+ if isinstance(user,str):
+ import pwd
+ entry=pwd.getpwnam(user)
+ if not entry:
+ raise OSError('Unknown user %r'%user)
+ user=entry[2]
+ if isinstance(group,str):
+ import grp
+ entry=grp.getgrnam(group)
+ if not entry:
+ raise OSError('Unknown group %r'%group)
+ group=entry[2]
+ return os.lchown(path,user,group)
+def run_regular_process(cmd,kwargs,cargs={}):
+ proc=subprocess.Popen(cmd,**kwargs)
+ if kwargs.get('stdout')or kwargs.get('stderr'):
+ try:
+ out,err=proc.communicate(**cargs)
+ except TimeoutExpired:
+ if kwargs.get('start_new_session')and hasattr(os,'killpg'):
+ os.killpg(proc.pid,signal.SIGKILL)
+ else:
+ proc.kill()
+ out,err=proc.communicate()
+ exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out)
+ exc.stderr=err
+ raise exc
+ status=proc.returncode
+ else:
+ out,err=(None,None)
+ try:
+ status=proc.wait(**cargs)
+ except TimeoutExpired as e:
+ if kwargs.get('start_new_session')and hasattr(os,'killpg'):
+ os.killpg(proc.pid,signal.SIGKILL)
+ else:
+ proc.kill()
+ proc.wait()
+ raise e
+ return status,out,err
+def run_process(cmd,kwargs,cargs={}):
+ if kwargs.get('stdout')and kwargs.get('stderr'):
+ return run_prefork_process(cmd,kwargs,cargs)
+ else:
+ return run_regular_process(cmd,kwargs,cargs)
+def alloc_process_pool(n,force=False):
+ global run_process,get_process,alloc_process_pool
+ if not force:
+ n=max(n-len(process_pool),0)
+ try:
+ lst=[get_process()for x in range(n)]
+ except OSError:
+ run_process=run_regular_process
+ get_process=alloc_process_pool=nada
+ else:
+ for x in lst:
+ process_pool.append(x)
+def atexit_pool():
+ for k in process_pool:
+ try:
+ os.kill(k.pid,9)
+ except OSError:
+ pass
+ else:
+ k.wait()
+if(sys.hexversion<0x207000f and not is_win32)or sys.hexversion>=0x306000f:
+ atexit.register(atexit_pool)
+if os.environ.get('WAF_NO_PREFORK')or sys.platform=='cli'or not sys.executable:
+ run_process=run_regular_process
+ get_process=alloc_process_pool=nada