~ubuntu-branches/ubuntu/trusty/mapnik/trusty

« back to all changes in this revision

Viewing changes to scons/scons-local-0.97.0d20071212/SCons/PathList.py

  • Committer: Bazaar Package Importer
  • Author(s): Andres Rodriguez
  • Date: 2009-05-20 15:39:58 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090520153958-cf6z1ql9zva4y4dq
Tags: 0.6.0-1ubuntu1
* Merge from debian unstable (LP: #378819), remaining changes:
  - debian/control:
    + Change bdeps from python2.5-dev to python-all-dev (>= 2.5)
    + Change XS-Python-Version from 2.5 to >= 2.5
  - debian/rules:
    + Various changes to enable python2.5 and python2.6 builds
* debian/patches/libtool2_2.diff Dropped. Included upsteam.
* Removed quilt support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
3
 
#
4
 
# Permission is hereby granted, free of charge, to any person obtaining
5
 
# a copy of this software and associated documentation files (the
6
 
# "Software"), to deal in the Software without restriction, including
7
 
# without limitation the rights to use, copy, modify, merge, publish,
8
 
# distribute, sublicense, and/or sell copies of the Software, and to
9
 
# permit persons to whom the Software is furnished to do so, subject to
10
 
# the following conditions:
11
 
#
12
 
# The above copyright notice and this permission notice shall be included
13
 
# in all copies or substantial portions of the Software.
14
 
#
15
 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16
 
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17
 
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
 
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
 
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
 
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 
#
23
 
 
24
 
__revision__ = "src/engine/SCons/PathList.py 2523 2007/12/12 09:37:41 knight"
25
 
 
26
 
__doc__ = """SCons.PathList
27
 
 
28
 
A module for handling lists of directory paths (the sort of things
29
 
that get set as CPPPATH, LIBPATH, etc.) with as much caching of data and
30
 
efficiency as we can while still keeping the evaluation delayed so that we
31
 
Do the Right Thing (almost) regardless of how the variable is specified.
32
 
 
33
 
"""
34
 
 
35
 
import os
36
 
import string
37
 
 
38
 
import SCons.Memoize
39
 
import SCons.Node
40
 
import SCons.Util
41
 
 
42
 
#
43
 
# Variables to specify the different types of entries in a PathList object:
44
 
#
45
 
 
46
 
TYPE_STRING_NO_SUBST = 0        # string with no '$'
47
 
TYPE_STRING_SUBST = 1           # string containing '$'
48
 
TYPE_OBJECT = 2                 # other object
49
 
 
50
 
def node_conv(obj):
51
 
    """
52
 
    This is the "string conversion" routine that we have our substitutions
53
 
    use to return Nodes, not strings.  This relies on the fact that an
54
 
    EntryProxy object has a get() method that returns the underlying
55
 
    Node that it wraps, which is a bit of architectural dependence
56
 
    that we might need to break or modify in the future in response to
57
 
    additional requirements.
58
 
    """
59
 
    try:
60
 
        get = obj.get
61
 
    except AttributeError:
62
 
        if isinstance(obj, SCons.Node.Node):
63
 
            result = obj
64
 
        else:
65
 
            result = str(obj)
66
 
    else:
67
 
        result = get()
68
 
    return result
69
 
 
70
 
class _PathList:
71
 
    """
72
 
    An actual PathList object.
73
 
    """
74
 
    def __init__(self, pathlist):
75
 
        """
76
 
        Initializes a PathList object, canonicalizing the input and
77
 
        pre-processing it for quicker substitution later.
78
 
 
79
 
        The stored representation of the PathList is a list of tuples
80
 
        containing (type, value), where the "type" is one of the TYPE_*
81
 
        variables defined above.  We distinguish between:
82
 
 
83
 
            strings that contain no '$' and therefore need no
84
 
            delayed-evaluation string substitution (we expect that there
85
 
            will be many of these and that we therefore get a pretty
86
 
            big win from avoiding string substitution)
87
 
 
88
 
            strings that contain '$' and therefore need substitution
89
 
            (the hard case is things like '${TARGET.dir}/include',
90
 
            which require re-evaluation for every target + source)
91
 
 
92
 
            other objects (which may be something like an EntryProxy
93
 
            that needs a method called to return a Node)
94
 
 
95
 
        Pre-identifying the type of each element in the PathList up-front
96
 
        and storing the type in the list of tuples is intended to reduce
97
 
        the amount of calculation when we actually do the substitution
98
 
        over and over for each target.
99
 
        """
100
 
        if SCons.Util.is_String(pathlist):
101
 
            pathlist = string.split(pathlist, os.pathsep)
102
 
        elif not SCons.Util.is_Sequence(pathlist):
103
 
            pathlist = [pathlist]
104
 
 
105
 
        pl = []
106
 
        for p in pathlist:
107
 
            try:
108
 
                index = string.find(p, '$')
109
 
            except (AttributeError, TypeError):
110
 
                type = TYPE_OBJECT
111
 
            else:
112
 
                if index == -1:
113
 
                    type = TYPE_STRING_NO_SUBST
114
 
                else:
115
 
                    type = TYPE_STRING_SUBST
116
 
            pl.append((type, p))
117
 
 
118
 
        self.pathlist = tuple(pl)
119
 
 
120
 
    def __len__(self): return len(self.pathlist)
121
 
 
122
 
    def __getitem__(self, i): return self.pathlist[i]
123
 
 
124
 
    def subst_path(self, env, target, source):
125
 
        """
126
 
        Performs construction variable substitution on a pre-digested
127
 
        PathList for a specific target and source.
128
 
        """
129
 
        result = []
130
 
        for type, value in self.pathlist:
131
 
            if type == TYPE_STRING_SUBST:
132
 
                value = env.subst(value, target=target, source=source,
133
 
                                  conv=node_conv)
134
 
                if SCons.Util.is_Sequence(value):
135
 
                    # It came back as a string or tuple, which in this
136
 
                    # case usually means some variable expanded to an
137
 
                    # actually Dir node.  Concatenate the values.
138
 
                    value = string.join(map(str, value), '')
139
 
            elif type == TYPE_OBJECT:
140
 
                value = node_conv(value)
141
 
            if value:
142
 
                result.append(value)
143
 
        return tuple(result)
144
 
 
145
 
 
146
 
class PathListCache:
147
 
    """
148
 
    A class to handle caching of PathList lookups.
149
 
 
150
 
    This class gets instantiated once and then deleted from the namespace,
151
 
    so it's used as a Singleton (although we don't enforce that in the
152
 
    usual Pythonic ways).  We could have just made the cache a dictionary
153
 
    in the module namespace, but putting it in this class allows us to
154
 
    use the same Memoizer pattern that we use elsewhere to count cache
155
 
    hits and misses, which is very valuable.
156
 
 
157
 
    Lookup keys in the cache are computed by the _PathList_key() method.
158
 
    Cache lookup should be quick, so we don't spend cycles canonicalizing
159
 
    all forms of the same lookup key.  For example, 'x:y' and ['x',
160
 
    'y'] logically represent the same list, but we don't bother to
161
 
    split string representations and treat those two equivalently.
162
 
    (Note, however, that we do, treat lists and tuples the same.)
163
 
 
164
 
    The main type of duplication we're trying to catch will come from
165
 
    looking up the same path list from two different clones of the
166
 
    same construction environment.  That is, given
167
 
    
168
 
        env2 = env1.Clone()
169
 
 
170
 
    both env1 and env2 will have the same CPPPATH value, and we can
171
 
    cheaply avoid re-parsing both values of CPPPATH by using the
172
 
    common value from this cache.
173
 
    """
174
 
    if SCons.Memoize.use_memoizer:
175
 
        __metaclass__ = SCons.Memoize.Memoized_Metaclass
176
 
 
177
 
    memoizer_counters = []
178
 
 
179
 
    def __init__(self):
180
 
        self._memo = {}
181
 
 
182
 
    def _PathList_key(self, pathlist):
183
 
        """
184
 
        Returns the key for memoization of PathLists.
185
 
 
186
 
        Note that we want this to be pretty quick, so we don't completely
187
 
        canonicalize all forms of the same list.  For example,
188
 
        'dir1:$ROOT/dir2' and ['$ROOT/dir1', 'dir'] may logically
189
 
        represent the same list if you're executing from $ROOT, but
190
 
        we're not going to bother splitting strings into path elements,
191
 
        or massaging strings into Nodes, to identify that equivalence.
192
 
        We just want to eliminate obvious redundancy from the normal
193
 
        case of re-using exactly the same cloned value for a path.
194
 
        """
195
 
        if SCons.Util.is_Sequence(pathlist):
196
 
            pathlist = tuple(SCons.Util.flatten(pathlist))
197
 
        return pathlist
198
 
 
199
 
    memoizer_counters.append(SCons.Memoize.CountDict('PathList', _PathList_key))
200
 
 
201
 
    def PathList(self, pathlist):
202
 
        """
203
 
        Returns the cached _PathList object for the specified pathlist,
204
 
        creating and caching a new object as necessary.
205
 
        """
206
 
        pathlist = self._PathList_key(pathlist)
207
 
        try:
208
 
            memo_dict = self._memo['PathList']
209
 
        except KeyError:
210
 
            memo_dict = {}
211
 
            self._memo['PathList'] = memo_dict
212
 
        else:
213
 
            try:
214
 
                return memo_dict[pathlist]
215
 
            except KeyError:
216
 
                pass
217
 
 
218
 
        result = _PathList(pathlist)
219
 
 
220
 
        memo_dict[pathlist] = result
221
 
 
222
 
        return result
223
 
 
224
 
PathList = PathListCache().PathList
225
 
 
226
 
 
227
 
del PathListCache