| Index: third_party/scons/scons-local/SCons/Util.py
|
| ===================================================================
|
| --- third_party/scons/scons-local/SCons/Util.py (revision 9094)
|
| +++ third_party/scons/scons-local/SCons/Util.py (working copy)
|
| @@ -5,7 +5,7 @@
|
| """
|
|
|
| #
|
| -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
| +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
|
| #
|
| # Permission is hereby granted, free of charge, to any person obtaining
|
| # a copy of this software and associated documentation files (the
|
| @@ -27,7 +27,7 @@
|
| # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| #
|
|
|
| -__revision__ = "src/engine/SCons/Util.py 3842 2008/12/20 22:59:52 scons"
|
| +__revision__ = "src/engine/SCons/Util.py 3897 2009/01/13 06:45:54 scons"
|
|
|
| import copy
|
| import os
|
| @@ -107,18 +107,6 @@
|
| path = string.upper(drive) + rest
|
| return path
|
|
|
| -class CallableComposite(UserList):
|
| - """A simple composite callable class that, when called, will invoke all
|
| - of its contained callables with the same arguments."""
|
| - def __call__(self, *args, **kwargs):
|
| - retvals = map(lambda x, args=args, kwargs=kwargs: apply(x,
|
| - args,
|
| - kwargs),
|
| - self.data)
|
| - if self.data and (len(self.data) == len(filter(callable, retvals))):
|
| - return self.__class__(retvals)
|
| - return NodeList(retvals)
|
| -
|
| class NodeList(UserList):
|
| """This class is almost exactly like a regular list of Nodes
|
| (actually it can hold any object), with one important difference.
|
| @@ -135,24 +123,21 @@
|
| def __str__(self):
|
| return string.join(map(str, self.data))
|
|
|
| + def __iter__(self):
|
| + return iter(self.data)
|
| +
|
| + def __call__(self, *args, **kwargs):
|
| + result = map(lambda x, args=args, kwargs=kwargs: apply(x,
|
| + args,
|
| + kwargs),
|
| + self.data)
|
| + return self.__class__(result)
|
| +
|
| def __getattr__(self, name):
|
| - if not self.data:
|
| - # If there is nothing in the list, then we have no attributes to
|
| - # pass through, so raise AttributeError for everything.
|
| - raise AttributeError, "NodeList has no attribute: %s" % name
|
| + result = map(lambda x, n=name: getattr(x, n), self.data)
|
| + return self.__class__(result)
|
|
|
| - # Return a list of the attribute, gotten from every element
|
| - # in the list
|
| - attrList = map(lambda x, n=name: getattr(x, n), self.data)
|
|
|
| - # Special case. If the attribute is callable, we do not want
|
| - # to return a list of callables. Rather, we want to return a
|
| - # single callable that, when called, will invoke the function on
|
| - # all elements of this list.
|
| - if self.data and (len(self.data) == len(filter(callable, attrList))):
|
| - return CallableComposite(attrList)
|
| - return self.__class__(attrList)
|
| -
|
| _get_env_var = re.compile(r'^\$([_a-zA-Z]\w*|{[_a-zA-Z]\w*})$')
|
|
|
| def get_environment_var(varstr):
|
| @@ -844,7 +829,8 @@
|
| continue
|
| return None
|
|
|
| -def PrependPath(oldpath, newpath, sep = os.pathsep, delete_existing=1):
|
| +def PrependPath(oldpath, newpath, sep = os.pathsep,
|
| + delete_existing=1, canonicalize=None):
|
| """This prepends newpath elements to the given oldpath. Will only
|
| add any particular path once (leaving the first one it encounters
|
| and ignoring the rest, to preserve path order), and will
|
| @@ -861,6 +847,9 @@
|
| If delete_existing is 0, then adding a path that exists will
|
| not move it to the beginning; it will stay where it is in the
|
| list.
|
| +
|
| + If canonicalize is not None, it is applied to each element of
|
| + newpath before use.
|
| """
|
|
|
| orig = oldpath
|
| @@ -870,11 +859,16 @@
|
| paths = string.split(paths, sep)
|
| is_list = 0
|
|
|
| - if is_List(newpath) or is_Tuple(newpath):
|
| + if is_String(newpath):
|
| + newpaths = string.split(newpath, sep)
|
| + elif not is_List(newpath) and not is_Tuple(newpath):
|
| + newpaths = [ newpath ] # might be a Dir
|
| + else:
|
| newpaths = newpath
|
| - else:
|
| - newpaths = string.split(newpath, sep)
|
|
|
| + if canonicalize:
|
| + newpaths=map(canonicalize, newpaths)
|
| +
|
| if not delete_existing:
|
| # First uniquify the old paths, making sure to
|
| # preserve the first instance (in Unix/Linux,
|
| @@ -917,7 +911,8 @@
|
| else:
|
| return string.join(paths, sep)
|
|
|
| -def AppendPath(oldpath, newpath, sep = os.pathsep, delete_existing=1):
|
| +def AppendPath(oldpath, newpath, sep = os.pathsep,
|
| + delete_existing=1, canonicalize=None):
|
| """This appends new path elements to the given old path. Will
|
| only add any particular path once (leaving the last one it
|
| encounters and ignoring the rest, to preserve path order), and
|
| @@ -933,6 +928,9 @@
|
|
|
| If delete_existing is 0, then adding a path that exists
|
| will not move it to the end; it will stay where it is in the list.
|
| +
|
| + If canonicalize is not None, it is applied to each element of
|
| + newpath before use.
|
| """
|
|
|
| orig = oldpath
|
| @@ -942,11 +940,16 @@
|
| paths = string.split(paths, sep)
|
| is_list = 0
|
|
|
| - if is_List(newpath) or is_Tuple(newpath):
|
| + if is_String(newpath):
|
| + newpaths = string.split(newpath, sep)
|
| + elif not is_List(newpath) and not is_Tuple(newpath):
|
| + newpaths = [ newpath ] # might be a Dir
|
| + else:
|
| newpaths = newpath
|
| - else:
|
| - newpaths = string.split(newpath, sep)
|
|
|
| + if canonicalize:
|
| + newpaths=map(canonicalize, newpaths)
|
| +
|
| if not delete_existing:
|
| # add old paths to result, then
|
| # add new paths if not already present
|
| @@ -1089,12 +1092,13 @@
|
| """A callable ordered dictionary that maps file suffixes to
|
| dictionary values. We preserve the order in which items are added
|
| so that get_suffix() calls always return the first suffix added."""
|
| - def __call__(self, env, source):
|
| + def __call__(self, env, source, ext=None):
|
| + if ext is None:
|
| + try:
|
| + ext = source[0].suffix
|
| + except IndexError:
|
| + ext = ""
|
| try:
|
| - ext = source[0].suffix
|
| - except IndexError:
|
| - ext = ""
|
| - try:
|
| return self[ext]
|
| except KeyError:
|
| # Try to perform Environment substitution on the keys of
|
| @@ -1549,9 +1553,10 @@
|
| # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/68205
|
| # ASPN: Python Cookbook: Null Object Design Pattern
|
|
|
| +# TODO(1.5):
|
| +#class Null(object):
|
| class Null:
|
| - """ Null objects always and reliably "do nothging." """
|
| -
|
| + """ Null objects always and reliably "do nothing." """
|
| def __new__(cls, *args, **kwargs):
|
| if not '_inst' in vars(cls):
|
| #cls._inst = type.__new__(cls, *args, **kwargs)
|
| @@ -1562,16 +1567,27 @@
|
| def __call__(self, *args, **kwargs):
|
| return self
|
| def __repr__(self):
|
| - return "Null()"
|
| + return "Null(0x%08X)" % id(self)
|
| def __nonzero__(self):
|
| return False
|
| - def __getattr__(self, mname):
|
| + def __getattr__(self, name):
|
| return self
|
| def __setattr__(self, name, value):
|
| return self
|
| def __delattr__(self, name):
|
| return self
|
|
|
| +class NullSeq(Null):
|
| + def __len__(self):
|
| + return 0
|
| + def __iter__(self):
|
| + return iter(())
|
| + def __getitem__(self, i):
|
| + return self
|
| + def __delitem__(self, i):
|
| + return self
|
| + def __setitem__(self, i, v):
|
| + return self
|
|
|
|
|
| del __revision__
|
|
|