import os
import SCons.Node.FS
-from SCons.Util import PathList, scons_str2nodes, scons_varrepl
+from SCons.Util import PathList, scons_str2nodes, scons_subst
import string
import types
self.command = string
def execute(self, **kw):
- try:
- t = kw['target']
- if type(t) is types.StringType:
- t = [t]
- tgt = PathList(map(os.path.normpath, t))
- except:
- tgt = PathList()
- try:
- s = kw['source']
- if type(s) is types.StringType:
- s = [s]
- src = PathList(map(os.path.normpath, s))
- except:
- src = PathList()
- cmd = scons_varrepl(self.command, tgt, src)
+ loc = {}
+ if kw.has_key('target'):
+ t = kw['target']
+ if type(t) is type(""):
+ t = [t]
+ loc['targets'] = PathList(map(os.path.normpath, t))
+ loc['target'] = loc['targets'][0]
+ if kw.has_key('source'):
+ s = kw['source']
+ if type(s) is type(""):
+ s = [s]
+ loc['sources'] = PathList(map(os.path.normpath, s))
+
+ try:
+ glob = self.env.Dictionary()
+ except:
+ glob = {}
+
+ cmd = scons_subst(self.command, loc, glob)
if print_actions:
self.show(cmd)
ret = 0
-_cv = re.compile(r'%([_a-zA-Z]\w*|{[_a-zA-Z]\w*})')
-
-
-
def _deepcopy_atomic(x, memo):
return x
copy._deepcopy_dispatch[types.ModuleType] = _deepcopy_atomic
def subst(self, string):
"""Recursively interpolates construction variables from the
Environment into the specified string, returning the expanded
- result. Construction variables are specified by a % prefix
+ 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.
"""
- def repl(m, _self=self):
- key = m.group(1)
- if key[:1] == '{' and key[-1:] == '}':
- key = key[1:-1]
- if _self._dict.has_key(key): return _self._dict[key]
- else: return ''
- n = 1
- while n != 0:
- string, n = _cv.subn(repl, string)
- return string
+ return SCons.Util.scons_subst(string, self._dict, {})
"""Test the Command() method."""
env = Environment()
t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
- action='buildfoo %(target)s %(source)s')
+ action='buildfoo $target $source')
assert t.derived
assert t.builder.action.__class__.__name__ == 'CommandAction'
- assert t.builder.action.command == 'buildfoo %(target)s %(source)s'
+ assert t.builder.action.command == 'buildfoo $target $source'
assert 'foo1.in' in map(lambda x: x.path, t.sources)
assert 'foo2.in' in map(lambda x: x.path, t.sources)
of variables into other variables.
"""
env = Environment(AAA = 'a', BBB = 'b')
- str = env.subst("%AAA %{AAA}A %BBBB %BBB")
+ str = env.subst("$AAA ${AAA}A $BBBB $BBB")
assert str == "a aA b", str
- env = Environment(AAA = '%BBB', BBB = 'b', BBBA = 'foo')
- str = env.subst("%AAA %{AAA}A %{AAA}B %BBB")
+ env = Environment(AAA = '$BBB', BBB = 'b', BBBA = 'foo')
+ str = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
assert str == "b foo b", str
- env = Environment(AAA = '%BBB', BBB = '%CCC', CCC = 'c')
- str = env.subst("%AAA %{AAA}A %{AAA}B %BBB")
+ env = Environment(AAA = '$BBB', BBB = '$CCC', CCC = 'c')
+ str = env.subst("$AAA ${AAA}A ${AAA}B $BBB")
assert str == "c c", str
return self.__class__([ UserList.__getitem__(self, item), ])
-__tcv = re.compile(r'\$(\{?targets?(\[[0-9:]+\])?(\.[a-z]+)?\}?)')
-__scv = re.compile(r'\$(\{?sources(\[[0-9:]+\])?(\.[a-z]+)?\}?)')
-def scons_varrepl(command, targets, sources):
- """This routine handles variable interpolation for the $targets and
- $sources variables in the 'command' argument. The targets and sources
- given in the other arguements must be lists containing 'Node's."""
-
- def repl(m, targets=targets, sources=sources):
- globals = {}
- key = m.group(1)
- if key[0] == '{':
- if key[-1] == '}':
- key = key[1:-1]
- else:
- raise SyntaxError, "Bad regular expression"
-
- if key[:6] == 'target':
- globals['targets'] = targets
- globals['target'] = targets[0]
- if key[:7] == 'sources':
- globals['sources'] = sources
- if globals:
- return str(eval(key, globals ))
-
- command = __tcv.sub(repl, command)
- command = __scv.sub(repl, command)
- return command
+_tok = r'[_a-zA-Z]\w*'
+_cv = re.compile(r'\$(%s|{%s(\[[-0-9:]*\])?(\.\w+)?})' % (_tok, _tok))
+
+def scons_subst(string, locals, globals):
+ """Recursively interpolates dictionary variables into
+ the specified string, returning the expanded result.
+ 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.
+ """
+ def repl(m, locals=locals, globals=globals):
+ key = m.group(1)
+ if key[:1] == '{' and key[-1:] == '}':
+ key = key[1:-1]
+ try:
+ s = str(eval(key, locals, globals))
+ except NameError:
+ s = ''
+ return s
+ n = 1
+ while n != 0:
+ string, n = _cv.subn(repl, string)
+ return string
import unittest
import SCons.Node
import SCons.Node.FS
-from SCons.Util import scons_str2nodes, scons_varrepl, PathList
+from SCons.Util import scons_str2nodes, scons_subst, PathList
class UtilTestCase(unittest.TestCase):
node = scons_str2nodes(OtherNode())
- def test_varrepl(self):
- """Test the varrepl function."""
- targets = PathList(map(os.path.normpath, [ "./foo/bar.exe",
- "/bar/baz.obj",
- "../foo/baz.obj" ]))
- sources = PathList(map(os.path.normpath, [ "./foo/blah.cpp",
- "/bar/ack.cpp",
- "../foo/ack.c" ]))
+ def test_subst(self):
+ """Test the subst function."""
+ loc = {}
+ loc['targets'] = PathList(map(os.path.normpath, [ "./foo/bar.exe",
+ "/bar/baz.obj",
+ "../foo/baz.obj" ]))
+ loc['target'] = loc['targets'][0]
+ loc['sources'] = PathList(map(os.path.normpath, [ "./foo/blah.cpp",
+ "/bar/ack.cpp",
+ "../foo/ack.c" ]))
- newcom = scons_varrepl("test $targets $sources", targets, sources)
+ newcom = scons_subst("test $targets $sources", loc, {})
assert newcom == "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp /bar/ack.cpp ../foo/ack.c"
- newcom = scons_varrepl("test $targets[:] $sources[0]", targets, sources)
+ newcom = scons_subst("test ${targets[:]} ${sources[0]}", loc, {})
assert newcom == "test foo/bar.exe /bar/baz.obj ../foo/baz.obj foo/blah.cpp"
- newcom = scons_varrepl("test ${targets[1:]}v", targets, sources)
+ newcom = scons_subst("test ${targets[1:]}v", loc, {})
assert newcom == "test /bar/baz.obj ../foo/baz.objv"
- newcom = scons_varrepl("test $target", targets, sources)
+ newcom = scons_subst("test $target", loc, {})
assert newcom == "test foo/bar.exe"
- newcom = scons_varrepl("test $target$source[0]", targets, sources)
- assert newcom == "test foo/bar.exe$source[0]"
+ newcom = scons_subst("test $target$source[0]", loc, {})
+ assert newcom == "test foo/bar.exe[0]"
- newcom = scons_varrepl("test ${target.file}", targets, sources)
+ newcom = scons_subst("test ${target.file}", loc, {})
assert newcom == "test bar.exe"
- newcom = scons_varrepl("test ${target.filebase}", targets, sources)
+ newcom = scons_subst("test ${target.filebase}", loc, {})
assert newcom == "test bar"
- newcom = scons_varrepl("test ${target.suffix}", targets, sources)
+ newcom = scons_subst("test ${target.suffix}", loc, {})
assert newcom == "test .exe"
- newcom = scons_varrepl("test ${target.base}", targets, sources)
+ newcom = scons_subst("test ${target.base}", loc, {})
assert newcom == "test foo/bar"
- newcom = scons_varrepl("test ${target.dir}", targets, sources)
+ newcom = scons_subst("test ${target.dir}", loc, {})
assert newcom == "test foo"