diff options
author | Steven Knight <knight@baldmt.com> | 2004-03-05 09:49:04 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2004-03-05 09:49:04 (GMT) |
commit | aede9c91b7e76c5dd1bf90d7677d10592f9a9ba5 (patch) | |
tree | bc5b96fdcd04e1f2bda812416b47d940dfe828ed /src | |
parent | bb42c27bfa1a4208fc3cdc7b583b8093305fc4c0 (diff) | |
download | SCons-aede9c91b7e76c5dd1bf90d7677d10592f9a9ba5.zip SCons-aede9c91b7e76c5dd1bf90d7677d10592f9a9ba5.tar.gz SCons-aede9c91b7e76c5dd1bf90d7677d10592f9a9ba5.tar.bz2 |
Fix use of things like ${TARGET.dir} in *PATH expansions.
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 2 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 51 | ||||
-rw-r--r-- | src/engine/SCons/EnvironmentTests.py | 16 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 35 | ||||
-rw-r--r-- | src/engine/SCons/UtilTests.py | 26 |
5 files changed, 102 insertions, 28 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 76f08b5..1060939 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -192,6 +192,8 @@ RELEASE 0.95 - XXX - Initialize all *FLAGS variables with objects do the right thing with appending flags as strings or lists. + - Make things like ${TARGET.dir} work in *PATH construction variables. + From Vincent Risi: - Add support for the bcc32, ilink32 and tlib Borland tools. diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 2235ace..da455bc 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -366,17 +366,17 @@ class Base: return scanner return None - def subst(self, string, raw=0, target=None, source=None, dict=None): - """Recursively interpolates construction variables from the - Environment into the specified string, returning the expanded - result. Construction variables are specified by a $ prefix - in the string and begin with an initial underscore or - alphabetic character followed by any number of underscores - or alphanumeric characters. The construction variable names - may be surrounded by curly braces to separate the name from - trailing characters. - """ - return SCons.Util.scons_subst(string, self, raw, target, source, dict) + def subst(self, string, raw=0, target=None, source=None, dict=None, conv=None): + """Recursively interpolates construction variables from the + Environment into the specified string, returning the expanded + result. Construction variables are specified by a $ prefix + in the string and begin with an initial underscore or + alphabetic character followed by any number of underscores + or alphanumeric characters. The construction variable names + may be surrounded by curly braces to separate the name from + trailing characters. + """ + return SCons.Util.scons_subst(string, self, raw, target, source, dict, conv) def subst_kw(self, kw, raw=0, target=None, source=None, dict=None): nkw = {} @@ -387,21 +387,42 @@ class Base: nkw[k] = v return nkw - def subst_list(self, string, raw=0, target=None, source=None, dict=None): + def subst_list(self, string, raw=0, target=None, source=None, dict=None, conv=None): """Calls through to SCons.Util.scons_subst_list(). See the documentation for that function.""" - return SCons.Util.scons_subst_list(string, self, raw, target, source, dict) + return SCons.Util.scons_subst_list(string, self, raw, target, source, dict, conv) + def subst_path(self, path): - """Substitute a path list.""" + """Substitute a path list, turning EntryProxies into Nodes + and leaving Nodes (and other objects) as-is.""" if not SCons.Util.is_List(path): path = [path] + def s(obj): + """This is the "string conversion" routine that we have our + substitutions use to return Nodes, not strings. This relies + on the fact that an EntryProxy object has a get() method that + returns the underlying Node that it wraps, which is a bit of + architectural dependence that we might need to break or modify + in the future in response to additional requirements.""" + try: + get = obj.get + except AttributeError: + pass + else: + obj = get() + return obj + r = [] for p in path: if SCons.Util.is_String(p): - p = self.subst(p) + p = self.subst(p, conv=s) + if SCons.Util.is_List(p): + p = p[0] + else: + p = s(p) r.append(p) return r diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 45f5fdb..d450075 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -419,7 +419,16 @@ class EnvironmentTestCase(unittest.TestCase): def test_subst_path(self): """Test substituting a path list """ - env = Environment(FOO='foo', BAR='bar') + class MyProxy: + def __init__(self, val): + self.val = val + def get(self): + return self.val + '-proxy' + + class MyObj: + pass + + env = Environment(FOO='foo', BAR='bar', PROXY=MyProxy('my1')) r = env.subst_path('$FOO') assert r == ['foo'], r @@ -427,6 +436,11 @@ class EnvironmentTestCase(unittest.TestCase): r = env.subst_path(['$FOO', 'xxx', '$BAR']) assert r == ['foo', 'xxx', 'bar'], r + n = MyObj() + + r = env.subst_path(['$PROXY', MyProxy('my2'), n]) + assert r == ['my1-proxy', 'my2-proxy', n], r + def test_Builder_calls(self): """Test Builder calls through different environments """ diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 97ba8b5..1722f3a 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -501,7 +501,7 @@ _separate_args = re.compile(r'(\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}|\s+|[^\s\ # 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, dict=None): +def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=None, conv=None): """Expand a string containing construction variable substitutions. This is the work-horse function for substitutions in file names @@ -516,14 +516,14 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=No source with two methods (substitute() and expand()) that handle the expansion. """ - def __init__(self, env, mode, target, source): + def __init__(self, env, mode, target, source, conv): self.env = env self.mode = mode self.target = target self.source = source self.gvars = env.Dictionary() - self.str = _strconv[mode] + self.conv = conv def expand(self, s, lvars): """Expand a single "token" as necessary, returning an @@ -570,7 +570,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=No elif is_List(s): r = [] for l in s: - r.append(self.str(self.substitute(l, lvars))) + r.append(self.conv(self.substitute(l, lvars))) return string.join(r) elif callable(s): s = s(target=self.target, @@ -593,15 +593,21 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=No args = _separate_args.findall(args) result = [] for a in args: - result.append(self.str(self.expand(a, lvars))) - return string.join(result, '') + result.append(self.conv(self.expand(a, lvars))) + try: + result = string.join(result, '') + except TypeError: + pass + return result else: return self.expand(args, lvars) if dict is None: dict = subst_dict(target, source) + if conv is None: + conv = _strconv[mode] - ss = StringSubber(env, mode, target, source) + ss = StringSubber(env, mode, target, source, conv) result = ss.substitute(strSubst, dict) if is_String(result): @@ -617,7 +623,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=No return result -def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=None): +def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=None, conv=None): """Substitute construction variables in a string (or list or other object) and separate the arguments into a command list. @@ -641,7 +647,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di and the rest of the object takes care of doing the right thing internally. """ - def __init__(self, env, mode, target, source): + def __init__(self, env, mode, target, source, conv): UserList.UserList.__init__(self, []) self.env = env self.mode = mode @@ -654,7 +660,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di self.add_strip = lambda x, s=self: s.append(x) else: self.add_strip = lambda x, s=self: None - self.str = _strconv[mode] + self.conv = conv self.in_strip = None self.next_line() @@ -768,7 +774,10 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di literal = None else: literal = l() - self[-1].append(CmdStringHolder(self.str(x), literal)) + x = self.conv(x) + if is_String(x): + x = CmdStringHolder(x, literal) + self[-1].append(x) self.append = self.add_to_current_word def open_strip(self, x): @@ -782,8 +791,10 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di if dict is None: dict = subst_dict(target, source) + if conv is None: + conv = _strconv[mode] - ls = ListSubber(env, mode, target, source) + ls = ListSubber(env, mode, target, source, conv) ls.substitute(strSubst, dict, 0) return ls.data diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index c96f124..38e8c30 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -429,6 +429,19 @@ class UtilTestCase(unittest.TestCase): else: raise AssertionError, "did not catch expected UserError" + # Test we handle overriding the internal conversion routines. + def s(obj): + return obj + + n1 = MyNode('n1') + env = DummyEnv({'NODE' : n1}) + node = scons_subst("$NODE", env, mode=SUBST_RAW, conv=s) + assert node == [n1], node + node = scons_subst("$NODE", env, mode=SUBST_CMD, conv=s) + assert node == [n1], node + node = scons_subst("$NODE", env, mode=SUBST_SIG, conv=s) + assert node == [n1], node + # Test returning a function. #env = DummyEnv({'FUNCTION' : foo}) #func = scons_subst("$FUNCTION", env, mode=SUBST_RAW, call=None) @@ -771,6 +784,19 @@ class UtilTestCase(unittest.TestCase): else: raise AssertionError, "did not catch expected SyntaxError" + # Test we handle overriding the internal conversion routines. + def s(obj): + return obj + + n1 = MyNode('n1') + env = DummyEnv({'NODE' : n1}) + node = scons_subst_list("$NODE", env, mode=SUBST_RAW, conv=s) + assert node == [[n1]], node + node = scons_subst_list("$NODE", env, mode=SUBST_CMD, conv=s) + assert node == [[n1]], node + node = scons_subst_list("$NODE", env, mode=SUBST_SIG, conv=s) + assert node == [[n1]], node + def test_subst_once(self): """Testing the scons_subst_once() method""" |