diff options
Diffstat (limited to 'bitbake-dev/lib/bb/utils.py')
| -rw-r--r-- | bitbake-dev/lib/bb/utils.py | 431 | 
1 files changed, 0 insertions, 431 deletions
| diff --git a/bitbake-dev/lib/bb/utils.py b/bitbake-dev/lib/bb/utils.py deleted file mode 100644 index 5fc1463e67..0000000000 --- a/bitbake-dev/lib/bb/utils.py +++ /dev/null @@ -1,431 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -""" -BitBake Utility Functions -""" - -# Copyright (C) 2004 Michael Lauer -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -digits = "0123456789" -ascii_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -separators = ".-" - -import re, fcntl, os, types - -def explode_version(s): -    r = [] -    alpha_regexp = re.compile('^([a-zA-Z]+)(.*)$') -    numeric_regexp = re.compile('^(\d+)(.*)$') -    while (s != ''): -        if s[0] in digits: -            m = numeric_regexp.match(s) -            r.append(int(m.group(1))) -            s = m.group(2) -            continue -        if s[0] in ascii_letters: -            m = alpha_regexp.match(s) -            r.append(m.group(1)) -            s = m.group(2) -            continue -        r.append(s[0]) -        s = s[1:] -    return r - -def vercmp_part(a, b): -    va = explode_version(a) -    vb = explode_version(b) -    sa = False -    sb = False -    while True: -        if va == []: -            ca = None -        else: -            ca = va.pop(0) -        if vb == []: -            cb = None -        else: -            cb = vb.pop(0) -        if ca == None and cb == None: -            return 0 - -        if type(ca) is types.StringType: -            sa = ca in separators -        if type(cb) is types.StringType: -            sb = cb in separators -        if sa and not sb: -            return -1 -        if not sa and sb: -            return 1 - -        if ca > cb: -            return 1 -        if ca < cb: -            return -1 - -def vercmp(ta, tb): -    (ea, va, ra) = ta -    (eb, vb, rb) = tb - -    r = int(ea)-int(eb) -    if (r == 0): -        r = vercmp_part(va, vb) -    if (r == 0): -        r = vercmp_part(ra, rb) -    return r - -def explode_deps(s): -    """ -    Take an RDEPENDS style string of format: -    "DEPEND1 (optional version) DEPEND2 (optional version) ..." -    and return a list of dependencies. -    Version information is ignored. -    """ -    r = [] -    l = s.split() -    flag = False -    for i in l: -        if i[0] == '(': -            flag = True -            #j = [] -        if not flag: -            r.append(i) -        #else: -        #    j.append(i) -        if flag and i.endswith(')'): -            flag = False -            # Ignore version -            #r[-1] += ' ' + ' '.join(j) -    return r - -def explode_dep_versions(s): -    """ -    Take an RDEPENDS style string of format: -    "DEPEND1 (optional version) DEPEND2 (optional version) ..." -    and return a dictonary of dependencies and versions. -    """ -    r = {} -    l = s.split() -    lastdep = None -    lastver = "" -    inversion = False -    for i in l: -        if i[0] == '(': -            inversion = True -            lastver = i[1:] or "" -            #j = [] -        elif inversion and i.endswith(')'): -            inversion = False -            lastver = lastver + " " + (i[:-1] or "") -            r[lastdep] = lastver -        elif not inversion: -            r[i] = None -            lastdep = i -            lastver = "" -        elif inversion: -            lastver = lastver + " " + i - -    return r - -def _print_trace(body, line): -    """ -    Print the Environment of a Text Body -    """ -    import bb - -    # print the environment of the method -    bb.msg.error(bb.msg.domain.Util, "Printing the environment of the function") -    min_line = max(1,line-4) -    max_line = min(line+4,len(body)-1) -    for i in range(min_line,max_line+1): -        bb.msg.error(bb.msg.domain.Util, "\t%.4d:%s" % (i, body[i-1]) ) - - -def better_compile(text, file, realfile): -    """ -    A better compile method. This method -    will print  the offending lines. -    """ -    try: -        return compile(text, file, "exec") -    except Exception, e: -        import bb,sys - -        # split the text into lines again -        body = text.split('\n') -        bb.msg.error(bb.msg.domain.Util, "Error in compiling python function in: ", realfile) -        bb.msg.error(bb.msg.domain.Util, "The lines resulting into this error were:") -        bb.msg.error(bb.msg.domain.Util, "\t%d:%s:'%s'" % (e.lineno, e.__class__.__name__, body[e.lineno-1])) - -        _print_trace(body, e.lineno) - -        # exit now -        sys.exit(1) - -def better_exec(code, context, text, realfile): -    """ -    Similiar to better_compile, better_exec will -    print the lines that are responsible for the -    error. -    """ -    import bb,sys -    try: -        exec code in context -    except: -        (t,value,tb) = sys.exc_info() - -        if t in [bb.parse.SkipPackage, bb.build.FuncFailed]: -            raise - -        # print the Header of the Error Message -        bb.msg.error(bb.msg.domain.Util, "Error in executing python function in: %s" % realfile) -        bb.msg.error(bb.msg.domain.Util, "Exception:%s Message:%s" % (t,value) ) - -        # let us find the line number now -        while tb.tb_next: -            tb = tb.tb_next - -        import traceback -        line = traceback.tb_lineno(tb) - -        _print_trace( text.split('\n'), line ) -         -        raise - -def Enum(*names): -   """ -   A simple class to give Enum support -   """ - -   assert names, "Empty enums are not supported" - -   class EnumClass(object): -      __slots__ = names -      def __iter__(self):        return iter(constants) -      def __len__(self):         return len(constants) -      def __getitem__(self, i):  return constants[i] -      def __repr__(self):        return 'Enum' + str(names) -      def __str__(self):         return 'enum ' + str(constants) - -   class EnumValue(object): -      __slots__ = ('__value') -      def __init__(self, value): self.__value = value -      Value = property(lambda self: self.__value) -      EnumType = property(lambda self: EnumType) -      def __hash__(self):        return hash(self.__value) -      def __cmp__(self, other): -         # C fans might want to remove the following assertion -         # to make all enums comparable by ordinal value {;)) -         assert self.EnumType is other.EnumType, "Only values from the same enum are comparable" -         return cmp(self.__value, other.__value) -      def __invert__(self):      return constants[maximum - self.__value] -      def __nonzero__(self):     return bool(self.__value) -      def __repr__(self):        return str(names[self.__value]) - -   maximum = len(names) - 1 -   constants = [None] * len(names) -   for i, each in enumerate(names): -      val = EnumValue(i) -      setattr(EnumClass, each, val) -      constants[i] = val -   constants = tuple(constants) -   EnumType = EnumClass() -   return EnumType - -def lockfile(name): -    """ -    Use the file fn as a lock file, return when the lock has been acquired. -    Returns a variable to pass to unlockfile(). -    """ -    path = os.path.dirname(name) -    if not os.path.isdir(path): -        import bb, sys -        bb.msg.error(bb.msg.domain.Util, "Error, lockfile path does not exist!: %s" % path) -        sys.exit(1) - -    while True: -        # If we leave the lockfiles lying around there is no problem -        # but we should clean up after ourselves. This gives potential -        # for races though. To work around this, when we acquire the lock  -        # we check the file we locked was still the lock file on disk.  -        # by comparing inode numbers. If they don't match or the lockfile  -        # no longer exists, we start again. - -        # This implementation is unfair since the last person to request the  -        # lock is the most likely to win it. - -        try: -            lf = open(name, "a+") -            fcntl.flock(lf.fileno(), fcntl.LOCK_EX) -            statinfo = os.fstat(lf.fileno()) -            if os.path.exists(lf.name): -               statinfo2 = os.stat(lf.name) -               if statinfo.st_ino == statinfo2.st_ino: -                   return lf -            # File no longer exists or changed, retry -            lf.close -        except Exception, e: -            continue - -def unlockfile(lf): -    """ -    Unlock a file locked using lockfile()				 -    """ -    os.unlink(lf.name) -    fcntl.flock(lf.fileno(), fcntl.LOCK_UN) -    lf.close - -def md5_file(filename): -    """ -    Return the hex string representation of the MD5 checksum of filename. -    """ -    try: -        import hashlib -        m = hashlib.md5() -    except ImportError: -        import md5 -        m = md5.new() -     -    for line in open(filename): -        m.update(line) -    return m.hexdigest() - -def sha256_file(filename): -    """ -    Return the hex string representation of the 256-bit SHA checksum of -    filename.  On Python 2.4 this will return None, so callers will need to -    handle that by either skipping SHA checks, or running a standalone sha256sum -    binary. -    """ -    try: -        import hashlib -    except ImportError: -        return None - -    s = hashlib.sha256() -    for line in open(filename): -        s.update(line) -    return s.hexdigest() - -def preserved_envvars_list(): -    return [ -        'BBPATH', -        'BB_PRESERVE_ENV', -        'BB_ENV_WHITELIST', -        'BB_ENV_EXTRAWHITE', -        'COLORTERM', -        'DBUS_SESSION_BUS_ADDRESS', -        'DESKTOP_SESSION', -        'DESKTOP_STARTUP_ID', -        'DISPLAY', -        'GNOME_KEYRING_PID', -        'GNOME_KEYRING_SOCKET', -        'GPG_AGENT_INFO', -        'GTK_RC_FILES', -        'HOME', -        'LANG', -        'LOGNAME', -        'PATH', -        'PWD', -        'SESSION_MANAGER', -        'SHELL', -        'SSH_AUTH_SOCK', -        'TERM', -        'USER', -        'USERNAME', -        '_', -        'XAUTHORITY', -        'XDG_DATA_DIRS', -        'XDG_SESSION_COOKIE', -    ] - -def filter_environment(good_vars): -    """ -    Create a pristine environment for bitbake. This will remove variables that -    are not known and may influence the build in a negative way. -    """ - -    import bb - -    removed_vars = [] -    for key in os.environ.keys(): -        if key in good_vars: -            continue -         -        removed_vars.append(key) -        os.unsetenv(key) -        del os.environ[key] - -    if len(removed_vars): -        bb.debug(1, "Removed the following variables from the environment:", ",".join(removed_vars)) - -    return removed_vars - -def clean_environment(): -    """ -    Clean up any spurious environment variables. This will remove any -    variables the user hasn't chose to preserve. -    """ -    if 'BB_PRESERVE_ENV' not in os.environ: -        if 'BB_ENV_WHITELIST' in os.environ: -            good_vars = os.environ['BB_ENV_WHITELIST'].split() -        else: -            good_vars = preserved_envvars_list() -        if 'BB_ENV_EXTRAWHITE' in os.environ: -            good_vars.extend(os.environ['BB_ENV_EXTRAWHITE'].split()) -        filter_environment(good_vars) - -def empty_environment(): -    """ -    Remove all variables from the environment. -    """ -    for s in os.environ.keys(): -        os.unsetenv(s) -        del os.environ[s] - -def build_environment(d): -    """ -    Build an environment from all exported variables. -    """ -    import bb -    for var in bb.data.keys(d): -        export = bb.data.getVarFlag(var, "export", d) -        if export: -            os.environ[var] = bb.data.getVar(var, d, True) - -def prunedir(topdir): -    # Delete everything reachable from the directory named in 'topdir'. -    # CAUTION:  This is dangerous! -    for root, dirs, files in os.walk(topdir, topdown=False): -        for name in files: -            os.remove(os.path.join(root, name)) -        for name in dirs: -            if os.path.islink(os.path.join(root, name)): -                os.remove(os.path.join(root, name)) -            else: -                os.rmdir(os.path.join(root, name)) -    os.rmdir(topdir) - -# -# Could also use return re.compile("(%s)" % "|".join(map(re.escape, suffixes))).sub(lambda mo: "", var) -# but thats possibly insane and suffixes is probably going to be small -# -def prune_suffix(var, suffixes, d): -    # See if var ends with any of the suffixes listed and  -    # remove it if found -    for suffix in suffixes: -        if var.endswith(suffix): -            return var.replace(suffix, "") -    return var | 
