config/expandlibs.py

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 # This Source Code Form is subject to the terms of the Mozilla Public
     2 # License, v. 2.0. If a copy of the MPL was not distributed with this
     3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5 '''Expandlibs is a system that allows to replace some libraries with a
     6 descriptor file containing some linking information about them.
     8 The descriptor file format is as follows:
     9 ---8<-----
    10 OBJS = a.o b.o ...
    11 LIBS = libfoo.a libbar.a ...
    12 --->8-----
    14 (In the example above, OBJ_SUFFIX is o and LIB_SUFFIX is a).
    16 Expandlibs also canonicalizes how to pass libraries to the linker, such
    17 that only the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} form needs to be used:
    18 given a list of files, expandlibs will replace items with the form
    19 ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} following these rules:
    21 - If a ${DLL_PREFIX}${ROOT}.${DLL_SUFFIX} or
    22   ${DLL_PREFIX}${ROOT}.${IMPORT_LIB_SUFFIX} file exists, use that instead
    23 - If the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} file exists, use it
    24 - If a ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX}.${LIB_DESC_SUFFIX} file exists,
    25   replace ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} with the OBJS and LIBS the
    26   descriptor contains. And for each of these LIBS, also apply the same
    27   rules.
    28 '''
    29 from __future__ import with_statement
    30 import sys, os, errno
    31 import expandlibs_config as conf
    33 def ensureParentDir(file):
    34     '''Ensures the directory parent to the given file exists'''
    35     dir = os.path.dirname(file)
    36     if dir and not os.path.exists(dir):
    37         try:
    38             os.makedirs(dir)
    39         except OSError, error:
    40             if error.errno != errno.EEXIST:
    41                 raise
    43 def relativize(path):
    44     '''Returns a path relative to the current working directory, if it is
    45     shorter than the given path'''
    46     def splitpath(path):
    47         dir, file = os.path.split(path)
    48         if os.path.splitdrive(dir)[1] == os.sep:
    49             return [file]
    50         return splitpath(dir) + [file]
    52     if not os.path.exists(path):
    53         return path
    54     curdir = splitpath(os.path.abspath(os.curdir))
    55     abspath = splitpath(os.path.abspath(path))
    56     while curdir and abspath and curdir[0] == abspath[0]:
    57         del curdir[0]
    58         del abspath[0]
    59     if not curdir and not abspath:
    60         return '.'
    61     relpath = os.path.join(*[os.pardir for i in curdir] + abspath)
    62     if len(path) > len(relpath):
    63         return relpath
    64     return path
    66 def isObject(path):
    67     '''Returns whether the given path points to an object file, that is,
    68     ends with OBJ_SUFFIX or .i_o'''
    69     return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
    71 def isDynamicLib(path):
    72     '''Returns whether the given path points to a dynamic library, that is,
    73     ends with DLL_SUFFIX.'''
    74     # On mac, the xul library is named XUL, instead of libxul.dylib. Assume any
    75     # file by that name is a dynamic library.
    76     return os.path.splitext(path)[1] == conf.DLL_SUFFIX or os.path.basename(path) == 'XUL'
    78 class LibDescriptor(dict):
    79     KEYS = ['OBJS', 'LIBS']
    81     def __init__(self, content=None):
    82         '''Creates an instance of a lib descriptor, initialized with contents
    83         from a list of strings when given. This is intended for use with
    84         file.readlines()'''
    85         if isinstance(content, list) and all([isinstance(item, str) for item in content]):
    86             pass
    87         elif content is not None:
    88             raise TypeError("LibDescriptor() arg 1 must be None or a list of strings")
    89         super(LibDescriptor, self).__init__()
    90         for key in self.KEYS:
    91             self[key] = []
    92         if not content:
    93             return
    94         for key, value in [(s.strip() for s in item.split('=', 2)) for item in content if item.find('=') >= 0]:
    95             if key in self.KEYS:
    96                 self[key] = value.split()
    98     def __str__(self):
    99         '''Serializes the lib descriptor'''
   100         return '\n'.join('%s = %s' % (k, ' '.join(self[k])) for k in self.KEYS if len(self[k]))
   102 class ExpandArgs(list):
   103     def __init__(self, args):
   104         '''Creates a clone of the |args| list and performs file expansion on
   105         each item it contains'''
   106         super(ExpandArgs, self).__init__()
   107         for arg in args:
   108             self += self._expand(arg)
   110     def _expand(self, arg):
   111         '''Internal function doing the actual work'''
   112         (root, ext) = os.path.splitext(arg)
   113         if ext != conf.LIB_SUFFIX or not os.path.basename(root).startswith(conf.LIB_PREFIX):
   114             return [relativize(arg)]
   115         if len(conf.IMPORT_LIB_SUFFIX):
   116             dll = root + conf.IMPORT_LIB_SUFFIX
   117         else:
   118             dll = root.replace(conf.LIB_PREFIX, conf.DLL_PREFIX, 1) + conf.DLL_SUFFIX
   119         if os.path.exists(dll):
   120             return [relativize(dll)]
   121         if os.path.exists(arg):
   122             return [relativize(arg)]
   123         return self._expand_desc(arg)
   125     def _expand_desc(self, arg):
   126         '''Internal function taking care of lib descriptor expansion only'''
   127         if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
   128             with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
   129                 desc = LibDescriptor(f.readlines())
   130             objs = [relativize(o) for o in desc['OBJS']]
   131             for lib in desc['LIBS']:
   132                 objs += self._expand(lib)
   133             return objs
   134         return [arg]
   136 class ExpandLibsDeps(ExpandArgs):
   137     '''Same as ExpandArgs, but also adds the library descriptor to the list'''
   138     def _expand_desc(self, arg):
   139         objs = super(ExpandLibsDeps, self)._expand_desc(arg)
   140         if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
   141             objs += [relativize(arg + conf.LIBS_DESC_SUFFIX)]
   142         return objs
   144 if __name__ == '__main__':
   145     print " ".join(ExpandArgs(sys.argv[1:]))

mercurial