diff options
author | Micah Anderson <micah@leap.se> | 2014-01-15 18:04:21 +0000 |
---|---|---|
committer | drebs <drebs@leap.se> | 2014-01-17 08:48:11 -0200 |
commit | 8bd863936ead4243f58fb99e11d1221e1af0a71e (patch) | |
tree | 920c356f5c9e46c7578194026a7b03656df3981a /couchjs/scons/scons-local-2.0.1/SCons/Subst.py | |
parent | f0f5a107c0b895dd72187c10baedec24b85329a9 (diff) |
remove unnecessary embedded things: scons, rebar
Diffstat (limited to 'couchjs/scons/scons-local-2.0.1/SCons/Subst.py')
-rw-r--r-- | couchjs/scons/scons-local-2.0.1/SCons/Subst.py | 904 |
1 files changed, 0 insertions, 904 deletions
diff --git a/couchjs/scons/scons-local-2.0.1/SCons/Subst.py b/couchjs/scons/scons-local-2.0.1/SCons/Subst.py deleted file mode 100644 index 84e71503..00000000 --- a/couchjs/scons/scons-local-2.0.1/SCons/Subst.py +++ /dev/null @@ -1,904 +0,0 @@ -"""SCons.Subst - -SCons string substitution. - -""" - -# -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -__revision__ = "src/engine/SCons/Subst.py 5134 2010/08/16 23:02:40 bdeegan" - -import collections -import re - -import SCons.Errors - -from SCons.Util import is_String, is_Sequence - -# Indexed by the SUBST_* constants below. -_strconv = [SCons.Util.to_String_for_subst, - SCons.Util.to_String_for_subst, - SCons.Util.to_String_for_signature] - - - -AllowableExceptions = (IndexError, NameError) - -def SetAllowableExceptions(*excepts): - global AllowableExceptions - AllowableExceptions = [_f for _f in excepts if _f] - -def raise_exception(exception, target, s): - name = exception.__class__.__name__ - msg = "%s `%s' trying to evaluate `%s'" % (name, exception, s) - if target: - raise SCons.Errors.BuildError(target[0], msg) - else: - raise SCons.Errors.UserError(msg) - - - -class Literal(object): - """A wrapper for a string. If you use this object wrapped - around a string, then it will be interpreted as literal. - When passed to the command interpreter, all special - characters will be escaped.""" - def __init__(self, lstr): - self.lstr = lstr - - def __str__(self): - return self.lstr - - def escape(self, escape_func): - return escape_func(self.lstr) - - def for_signature(self): - return self.lstr - - def is_literal(self): - return 1 - -class SpecialAttrWrapper(object): - """This is a wrapper for what we call a 'Node special attribute.' - This is any of the attributes of a Node that we can reference from - Environment variable substitution, such as $TARGET.abspath or - $SOURCES[1].filebase. We implement the same methods as Literal - so we can handle special characters, plus a for_signature method, - such that we can return some canonical string during signature - calculation to avoid unnecessary rebuilds.""" - - def __init__(self, lstr, for_signature=None): - """The for_signature parameter, if supplied, will be the - canonical string we return from for_signature(). Else - we will simply return lstr.""" - self.lstr = lstr - if for_signature: - self.forsig = for_signature - else: - self.forsig = lstr - - def __str__(self): - return self.lstr - - def escape(self, escape_func): - return escape_func(self.lstr) - - def for_signature(self): - return self.forsig - - def is_literal(self): - return 1 - -def quote_spaces(arg): - """Generic function for putting double quotes around any string that - has white space in it.""" - if ' ' in arg or '\t' in arg: - return '"%s"' % arg - else: - return str(arg) - -class CmdStringHolder(collections.UserString): - """This is a special class used to hold strings generated by - scons_subst() and scons_subst_list(). It defines a special method - escape(). When passed a function with an escape algorithm for a - particular platform, it will return the contained string with the - proper escape sequences inserted. - """ - def __init__(self, cmd, literal=None): - collections.UserString.__init__(self, cmd) - self.literal = literal - - def is_literal(self): - return self.literal - - def escape(self, escape_func, quote_func=quote_spaces): - """Escape the string with the supplied function. The - function is expected to take an arbitrary string, then - return it with all special characters escaped and ready - for passing to the command interpreter. - - After calling this function, the next call to str() will - return the escaped string. - """ - - if self.is_literal(): - return escape_func(self.data) - elif ' ' in self.data or '\t' in self.data: - return quote_func(self.data) - else: - return self.data - -def escape_list(mylist, escape_func): - """Escape a list of arguments by running the specified escape_func - on every object in the list that has an escape() method.""" - def escape(obj, escape_func=escape_func): - try: - e = obj.escape - except AttributeError: - return obj - else: - return e(escape_func) - return list(map(escape, mylist)) - -class NLWrapper(object): - """A wrapper class that delays turning a list of sources or targets - into a NodeList until it's needed. The specified function supplied - when the object is initialized is responsible for turning raw nodes - into proxies that implement the special attributes like .abspath, - .source, etc. This way, we avoid creating those proxies just - "in case" someone is going to use $TARGET or the like, and only - go through the trouble if we really have to. - - In practice, this might be a wash performance-wise, but it's a little - cleaner conceptually... - """ - - def __init__(self, list, func): - self.list = list - self.func = func - def _return_nodelist(self): - return self.nodelist - def _gen_nodelist(self): - mylist = self.list - if mylist is None: - mylist = [] - elif not is_Sequence(mylist): - mylist = [mylist] - # The map(self.func) call is what actually turns - # a list into appropriate proxies. - self.nodelist = SCons.Util.NodeList(list(map(self.func, mylist))) - self._create_nodelist = self._return_nodelist - return self.nodelist - _create_nodelist = _gen_nodelist - - -class Targets_or_Sources(collections.UserList): - """A class that implements $TARGETS or $SOURCES expansions by in turn - wrapping a NLWrapper. This class handles the different methods used - to access the list, calling the NLWrapper to create proxies on demand. - - Note that we subclass collections.UserList purely so that the - is_Sequence() function will identify an object of this class as - a list during variable expansion. We're not really using any - collections.UserList methods in practice. - """ - def __init__(self, nl): - self.nl = nl - def __getattr__(self, attr): - nl = self.nl._create_nodelist() - return getattr(nl, attr) - def __getitem__(self, i): - nl = self.nl._create_nodelist() - return nl[i] - def __getslice__(self, i, j): - nl = self.nl._create_nodelist() - i = max(i, 0); j = max(j, 0) - return nl[i:j] - def __str__(self): - nl = self.nl._create_nodelist() - return str(nl) - def __repr__(self): - nl = self.nl._create_nodelist() - return repr(nl) - -class Target_or_Source(object): - """A class that implements $TARGET or $SOURCE expansions by in turn - wrapping a NLWrapper. This class handles the different methods used - to access an individual proxy Node, calling the NLWrapper to create - a proxy on demand. - """ - def __init__(self, nl): - self.nl = nl - def __getattr__(self, attr): - nl = self.nl._create_nodelist() - try: - nl0 = nl[0] - except IndexError: - # 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" % attr) - return getattr(nl0, attr) - def __str__(self): - nl = self.nl._create_nodelist() - if nl: - return str(nl[0]) - return '' - def __repr__(self): - nl = self.nl._create_nodelist() - if nl: - return repr(nl[0]) - return '' - -class NullNodeList(SCons.Util.NullSeq): - def __call__(self, *args, **kwargs): return '' - def __str__(self): return '' - -NullNodesList = NullNodeList() - -def subst_dict(target, source): - """Create a dictionary for substitution of special - construction variables. - - This translates the following special arguments: - - target - the target (object or array of objects), - used to generate the TARGET and TARGETS - construction variables - - source - the source (object or array of objects), - used to generate the SOURCES and SOURCE - construction variables - """ - dict = {} - - if target: - def get_tgt_subst_proxy(thing): - try: - subst_proxy = thing.get_subst_proxy() - except AttributeError: - subst_proxy = thing # probably a string, just return it - return subst_proxy - tnl = NLWrapper(target, get_tgt_subst_proxy) - dict['TARGETS'] = Targets_or_Sources(tnl) - dict['TARGET'] = Target_or_Source(tnl) - - # This is a total cheat, but hopefully this dictionary goes - # away soon anyway. We just let these expand to $TARGETS - # because that's "good enough" for the use of ToolSurrogates - # (see test/ToolSurrogate.py) to generate documentation. - dict['CHANGED_TARGETS'] = '$TARGETS' - dict['UNCHANGED_TARGETS'] = '$TARGETS' - else: - dict['TARGETS'] = NullNodesList - dict['TARGET'] = NullNodesList - - if source: - def get_src_subst_proxy(node): - try: - rfile = node.rfile - except AttributeError: - pass - else: - node = rfile() - try: - return node.get_subst_proxy() - except AttributeError: - return node # probably a String, just return it - snl = NLWrapper(source, get_src_subst_proxy) - dict['SOURCES'] = Targets_or_Sources(snl) - dict['SOURCE'] = Target_or_Source(snl) - - # This is a total cheat, but hopefully this dictionary goes - # away soon anyway. We just let these expand to $TARGETS - # because that's "good enough" for the use of ToolSurrogates - # (see test/ToolSurrogate.py) to generate documentation. - dict['CHANGED_SOURCES'] = '$SOURCES' - dict['UNCHANGED_SOURCES'] = '$SOURCES' - else: - dict['SOURCES'] = NullNodesList - dict['SOURCE'] = NullNodesList - - return dict - -# Constants for the "mode" parameter to scons_subst_list() and -# scons_subst(). SUBST_RAW gives the raw command line. SUBST_CMD -# gives a command line suitable for passing to a shell. SUBST_SIG -# gives a command line appropriate for calculating the signature -# of a command line...if this changes, we should rebuild. -SUBST_CMD = 0 -SUBST_RAW = 1 -SUBST_SIG = 2 - -_rm = re.compile(r'\$[()]') -_remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') - -# Indexed by the SUBST_* constants above. -_regex_remove = [ _rm, None, _remove ] - -def _rm_list(list): - #return [ l for l in list if not l in ('$(', '$)') ] - return [l for l in list if not l in ('$(', '$)')] - -def _remove_list(list): - result = [] - do_append = result.append - for l in list: - if l == '$(': - do_append = lambda x: None - elif l == '$)': - do_append = result.append - else: - do_append(l) - return result - -# Indexed by the SUBST_* constants above. -_list_remove = [ _rm_list, None, _remove_list ] - -# Regular expressions for splitting strings and handling substitutions, -# for use by the scons_subst() and scons_subst_list() functions: -# -# The first expression compiled matches all of the $-introduced tokens -# that we need to process in some way, and is used for substitutions. -# The expressions it matches are: -# -# "$$" -# "$(" -# "$)" -# "$variable" [must begin with alphabetic or underscore] -# "${any stuff}" -# -# The second expression compiled is used for splitting strings into tokens -# to be processed, and it matches all of the tokens listed above, plus -# the following that affect how arguments do or don't get joined together: -# -# " " [white space] -# "non-white-space" [without any dollar signs] -# "$" [single dollar sign] -# -_dollar_exps_str = r'\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}' -_dollar_exps = re.compile(r'(%s)' % _dollar_exps_str) -_separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str) - -# This regular expression is used to replace strings of multiple white -# space characters in the string result from the scons_subst() function. -_space_sep = re.compile(r'[\t ]+(?![^{]*})') - -def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None): - """Expand a string or list containing construction variable - substitutions. - - This is the work-horse function for substitutions in file names - and the like. The companion scons_subst_list() function (below) - handles separating command lines into lists of arguments, so see - that function if that's what you're looking for. - """ - if isinstance(strSubst, str) and strSubst.find('$') < 0: - return strSubst - - class StringSubber(object): - """A class to construct the results of a scons_subst() call. - - This binds a specific construction environment, mode, target and - source with two methods (substitute() and expand()) that handle - the expansion. - """ - def __init__(self, env, mode, conv, gvars): - self.env = env - self.mode = mode - self.conv = conv - self.gvars = gvars - - def expand(self, s, lvars): - """Expand a single "token" as necessary, returning an - appropriate string containing the expansion. - - This handles expanding different types of things (strings, - lists, callables) appropriately. It calls the wrapper - substitute() method to re-expand things as necessary, so that - the results of expansions of side-by-side strings still get - re-evaluated separately, not smushed together. - """ - if is_String(s): - try: - s0, s1 = s[:2] - except (IndexError, ValueError): - return s - if s0 != '$': - return s - if s1 == '$': - return '$' - elif s1 in '()': - return s - else: - key = s[1:] - if key[0] == '{' or key.find('.') >= 0: - if key[0] == '{': - key = key[1:-1] - try: - s = eval(key, self.gvars, lvars) - except KeyboardInterrupt: - raise - except Exception, e: - if e.__class__ in AllowableExceptions: - return '' - raise_exception(e, lvars['TARGETS'], s) - else: - if key in lvars: - s = lvars[key] - elif key in self.gvars: - s = self.gvars[key] - elif not NameError in AllowableExceptions: - raise_exception(NameError(key), lvars['TARGETS'], s) - else: - return '' - - # Before re-expanding the result, handle - # recursive expansion by copying the local - # variable dictionary and overwriting a null - # string for the value of the variable name - # we just expanded. - # - # This could potentially be optimized by only - # copying lvars when s contains more expansions, - # but lvars is usually supposed to be pretty - # small, and deeply nested variable expansions - # are probably more the exception than the norm, - # so it should be tolerable for now. - lv = lvars.copy() - var = key.split('.')[0] - lv[var] = '' - return self.substitute(s, lv) - elif is_Sequence(s): - def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): - return conv(substitute(l, lvars)) - return list(map(func, s)) - elif callable(s): - try: - s = s(target=lvars['TARGETS'], - source=lvars['SOURCES'], - env=self.env, - for_signature=(self.mode != SUBST_CMD)) - except TypeError: - # This probably indicates that it's a callable - # object that doesn't match our calling arguments - # (like an Action). - if self.mode == SUBST_RAW: - return s - s = self.conv(s) - return self.substitute(s, lvars) - elif s is None: - return '' - else: - return s - - def substitute(self, args, lvars): - """Substitute expansions in an argument or list of arguments. - - This serves as a wrapper for splitting up a string into - separate tokens. - """ - if is_String(args) and not isinstance(args, CmdStringHolder): - args = str(args) # In case it's a UserString. - try: - def sub_match(match): - return self.conv(self.expand(match.group(1), lvars)) - result = _dollar_exps.sub(sub_match, args) - except TypeError: - # If the internal conversion routine doesn't return - # strings (it could be overridden to return Nodes, for - # example), then the 1.5.2 re module will throw this - # exception. Back off to a slower, general-purpose - # algorithm that works for all data types. - args = _separate_args.findall(args) - result = [] - for a in args: - result.append(self.conv(self.expand(a, lvars))) - if len(result) == 1: - result = result[0] - else: - result = ''.join(map(str, result)) - return result - else: - return self.expand(args, lvars) - - if conv is None: - conv = _strconv[mode] - - # Doing this every time is a bit of a waste, since the Executor - # has typically already populated the OverrideEnvironment with - # $TARGET/$SOURCE variables. We're keeping this (for now), though, - # because it supports existing behavior that allows us to call - # an Action directly with an arbitrary target+source pair, which - # we use in Tool/tex.py to handle calling $BIBTEX when necessary. - # If we dropped that behavior (or found another way to cover it), - # we could get rid of this call completely and just rely on the - # Executor setting the variables. - if 'TARGET' not in lvars: - d = subst_dict(target, source) - if d: - lvars = lvars.copy() - lvars.update(d) - - # We're (most likely) going to eval() things. If Python doesn't - # find a __builtins__ value in the global dictionary used for eval(), - # it copies the current global values for you. Avoid this by - # setting it explicitly and then deleting, so we don't pollute the - # construction environment Dictionary(ies) that are typically used - # for expansion. - gvars['__builtins__'] = __builtins__ - - ss = StringSubber(env, mode, conv, gvars) - result = ss.substitute(strSubst, lvars) - - try: - del gvars['__builtins__'] - except KeyError: - pass - - if is_String(result): - # Remove $(-$) pairs and any stuff in between, - # if that's appropriate. - remove = _regex_remove[mode] - if remove: - result = remove.sub('', result) - if mode != SUBST_RAW: - # Compress strings of white space characters into - # a single space. - result = _space_sep.sub(' ', result).strip() - elif is_Sequence(result): - remove = _list_remove[mode] - if remove: - result = remove(result) - - return result - -#Subst_List_Strings = {} - -def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None): - """Substitute construction variables in a string (or list or other - object) and separate the arguments into a command list. - - The companion scons_subst() function (above) handles basic - substitutions within strings, so see that function instead - if that's what you're looking for. - """ -# try: -# Subst_List_Strings[strSubst] = Subst_List_Strings[strSubst] + 1 -# except KeyError: -# Subst_List_Strings[strSubst] = 1 -# import SCons.Debug -# SCons.Debug.caller_trace(1) - class ListSubber(collections.UserList): - """A class to construct the results of a scons_subst_list() call. - - Like StringSubber, this class binds a specific construction - environment, mode, target and source with two methods - (substitute() and expand()) that handle the expansion. - - In addition, however, this class is used to track the state of - the result(s) we're gathering so we can do the appropriate thing - whenever we have to append another word to the result--start a new - line, start a new word, append to the current word, etc. We do - this by setting the "append" attribute to the right method so - that our wrapper methods only need ever call ListSubber.append(), - and the rest of the object takes care of doing the right thing - internally. - """ - def __init__(self, env, mode, conv, gvars): - collections.UserList.__init__(self, []) - self.env = env - self.mode = mode - self.conv = conv - self.gvars = gvars - - if self.mode == SUBST_RAW: - self.add_strip = lambda x: self.append(x) - else: - self.add_strip = lambda x: None - self.in_strip = None - self.next_line() - - def expand(self, s, lvars, within_list): - """Expand a single "token" as necessary, appending the - expansion to the current result. - - This handles expanding different types of things (strings, - lists, callables) appropriately. It calls the wrapper - substitute() method to re-expand things as necessary, so that - the results of expansions of side-by-side strings still get - re-evaluated separately, not smushed together. - """ - - if is_String(s): - try: - s0, s1 = s[:2] - except (IndexError, ValueError): - self.append(s) - return - if s0 != '$': - self.append(s) - return - if s1 == '$': - self.append('$') - elif s1 == '(': - self.open_strip('$(') - elif s1 == ')': - self.close_strip('$)') - else: - key = s[1:] - if key[0] == '{' or key.find('.') >= 0: - if key[0] == '{': - key = key[1:-1] - try: - s = eval(key, self.gvars, lvars) - except KeyboardInterrupt: - raise - except Exception, e: - if e.__class__ in AllowableExceptions: - return - raise_exception(e, lvars['TARGETS'], s) - else: - if key in lvars: - s = lvars[key] - elif key in self.gvars: - s = self.gvars[key] - elif not NameError in AllowableExceptions: - raise_exception(NameError(), lvars['TARGETS'], s) - else: - return - - # Before re-expanding the result, handle - # recursive expansion by copying the local - # variable dictionary and overwriting a null - # string for the value of the variable name - # we just expanded. - lv = lvars.copy() - var = key.split('.')[0] - lv[var] = '' - self.substitute(s, lv, 0) - self.this_word() - elif is_Sequence(s): - for a in s: - self.substitute(a, lvars, 1) - self.next_word() - elif callable(s): - try: - s = s(target=lvars['TARGETS'], - source=lvars['SOURCES'], - env=self.env, - for_signature=(self.mode != SUBST_CMD)) - except TypeError: - # This probably indicates that it's a callable - # object that doesn't match our calling arguments - # (like an Action). - if self.mode == SUBST_RAW: - self.append(s) - return - s = self.conv(s) - self.substitute(s, lvars, within_list) - elif s is None: - self.this_word() - else: - self.append(s) - - def substitute(self, args, lvars, within_list): - """Substitute expansions in an argument or list of arguments. - - This serves as a wrapper for splitting up a string into - separate tokens. - """ - - if is_String(args) and not isinstance(args, CmdStringHolder): - args = str(args) # In case it's a UserString. - args = _separate_args.findall(args) - for a in args: - if a[0] in ' \t\n\r\f\v': - if '\n' in a: - self.next_line() - elif within_list: - self.append(a) - else: - self.next_word() - else: - self.expand(a, lvars, within_list) - else: - self.expand(args, lvars, within_list) - - def next_line(self): - """Arrange for the next word to start a new line. This - is like starting a new word, except that we have to append - another line to the result.""" - collections.UserList.append(self, []) - self.next_word() - - def this_word(self): - """Arrange for the next word to append to the end of the - current last word in the result.""" - self.append = self.add_to_current_word - - def next_word(self): - """Arrange for the next word to start a new word.""" - self.append = self.add_new_word - - def add_to_current_word(self, x): - """Append the string x to the end of the current last word - in the result. If that is not possible, then just add - it as a new word. Make sure the entire concatenated string - inherits the object attributes of x (in particular, the - escape function) by wrapping it as CmdStringHolder.""" - - if not self.in_strip or self.mode != SUBST_SIG: - try: - current_word = self[-1][-1] - except IndexError: - self.add_new_word(x) - else: - # All right, this is a hack and it should probably - # be refactored out of existence in the future. - # The issue is that we want to smoosh words together - # and make one file name that gets escaped if - # we're expanding something like foo$EXTENSION, - # but we don't want to smoosh them together if - # it's something like >$TARGET, because then we'll - # treat the '>' like it's part of the file name. - # So for now, just hard-code looking for the special - # command-line redirection characters... - try: - last_char = str(current_word)[-1] - except IndexError: - last_char = '\0' - if last_char in '<>|': - self.add_new_word(x) - else: - y = current_word + x - - # We used to treat a word appended to a literal - # as a literal itself, but this caused problems - # with interpreting quotes around space-separated - # targets on command lines. Removing this makes - # none of the "substantive" end-to-end tests fail, - # so we'll take this out but leave it commented - # for now in case there's a problem not covered - # by the test cases and we need to resurrect this. - #literal1 = self.literal(self[-1][-1]) - #literal2 = self.literal(x) - y = self.conv(y) - if is_String(y): - #y = CmdStringHolder(y, literal1 or literal2) - y = CmdStringHolder(y, None) - self[-1][-1] = y - - def add_new_word(self, x): - if not self.in_strip or self.mode != SUBST_SIG: - literal = self.literal(x) - x = self.conv(x) - if is_String(x): - x = CmdStringHolder(x, literal) - self[-1].append(x) - self.append = self.add_to_current_word - - def literal(self, x): - try: - l = x.is_literal - except AttributeError: - return None - else: - return l() - - def open_strip(self, x): - """Handle the "open strip" $( token.""" - self.add_strip(x) - self.in_strip = 1 - - def close_strip(self, x): - """Handle the "close strip" $) token.""" - self.add_strip(x) - self.in_strip = None - - if conv is None: - conv = _strconv[mode] - - # Doing this every time is a bit of a waste, since the Executor - # has typically already populated the OverrideEnvironment with - # $TARGET/$SOURCE variables. We're keeping this (for now), though, - # because it supports existing behavior that allows us to call - # an Action directly with an arbitrary target+source pair, which - # we use in Tool/tex.py to handle calling $BIBTEX when necessary. - # If we dropped that behavior (or found another way to cover it), - # we could get rid of this call completely and just rely on the - # Executor setting the variables. - if 'TARGET' not in lvars: - d = subst_dict(target, source) - if d: - lvars = lvars.copy() - lvars.update(d) - - # We're (most likely) going to eval() things. If Python doesn't - # find a __builtins__ value in the global dictionary used for eval(), - # it copies the current global values for you. Avoid this by - # setting it explicitly and then deleting, so we don't pollute the - # construction environment Dictionary(ies) that are typically used - # for expansion. - gvars['__builtins__'] = __builtins__ - - ls = ListSubber(env, mode, conv, gvars) - ls.substitute(strSubst, lvars, 0) - - try: - del gvars['__builtins__'] - except KeyError: - pass - - return ls.data - -def scons_subst_once(strSubst, env, key): - """Perform single (non-recursive) substitution of a single - construction variable keyword. - - This is used when setting a variable when copying or overriding values - in an Environment. We want to capture (expand) the old value before - we override it, so people can do things like: - - env2 = env.Clone(CCFLAGS = '$CCFLAGS -g') - - We do this with some straightforward, brute-force code here... - """ - if isinstance(strSubst, str) and strSubst.find('$') < 0: - return strSubst - - matchlist = ['$' + key, '${' + key + '}'] - val = env.get(key, '') - def sub_match(match, val=val, matchlist=matchlist): - a = match.group(1) - if a in matchlist: - a = val - if is_Sequence(a): - return ' '.join(map(str, a)) - else: - return str(a) - - if is_Sequence(strSubst): - result = [] - for arg in strSubst: - if is_String(arg): - if arg in matchlist: - arg = val - if is_Sequence(arg): - result.extend(arg) - else: - result.append(arg) - else: - result.append(_dollar_exps.sub(sub_match, arg)) - else: - result.append(arg) - return result - elif is_String(strSubst): - return _dollar_exps.sub(sub_match, strSubst) - else: - return strSubst - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: |