- Accomodate alphanumeric version strings in EnsurePythonVersion().
+ - Support arbitrary expansion of construction variables within
+ file and directory arguments to Builder calls and Environment methods.
+
From Bram Moolenaar:
- Split the non-SCons-specific functionality from SConf.py to a new,
Please note the following important changes since release 0.92:
+ - Construction variables are now expanded anywhere within a
+ target or source name, as well as in the arguments to the following
+ Environment methods: AlwaysBuild(), Depends(), Ignore(), Install(),
+ InstallAs(), Precious(), SideEffect() and SourceCode().
+
+ If you have any files or directories that actually contain one or
+ more dollar signs ($), you must now precede the dollar sign with
+ another dollar sign ($$) when referring to the file or directory
+ as part of calling a Builder, or any of the above methods.
+
Please note the following important changes since release 0.91:
- The Debian package available from the SCons web site now
import SCons.Action
from SCons.Errors import InternalError, UserError
import SCons.Executor
-import SCons.Node
import SCons.Node.FS
import SCons.Util
import SCons.Warnings
src_suf = self.get_src_suffix(env)
source = adjustixes(source, None, src_suf)
- slist = SCons.Node.arg2nodes(source, self.source_factory)
+ slist = env.arg2nodes(source, self.source_factory)
pre = self.get_prefix(env, slist)
suf = self.get_suffix(env, slist)
tlist = [ t_from_s(pre, suf, self.splitext) ]
else:
target = adjustixes(target, pre, suf)
- tlist = SCons.Node.arg2nodes(target, self.target_factory)
+ tlist = env.arg2nodes(target, self.target_factory)
if self.emitter:
# The emitter is going to do str(node), but because we're
# Have to call arg2nodes yet again, since it is legal for
# emitters to spit out strings as well as Node instances.
- slist = SCons.Node.arg2nodes(source, self.source_factory)
- tlist = SCons.Node.arg2nodes(target, self.target_factory)
+ slist = env.arg2nodes(source, self.source_factory)
+ tlist = env.arg2nodes(target, self.target_factory)
return tlist, slist
source = target
target = None
- slist = SCons.Node.arg2nodes(source, self.source_factory)
+ slist = env.arg2nodes(source, self.source_factory)
final_sources = []
try:
scons_env = SCons.Environment.Environment()
+env_arg2nodes_called = None
+
class Environment:
def __init__(self, **kw):
self.d = {}
self.d['ESCAPE'] = scons_env['ESCAPE']
for k, v in kw.items():
self.d[k] = v
+ global env_arg2nodes_called
+ env_arg2nodes_called = None
def subst(self, s):
if not SCons.Util.is_String(s):
return s
except IndexError:
pass
return self.d.get(s, s)
+ def arg2nodes(self, args, factory):
+ global env_arg2nodes_called
+ env_arg2nodes_called = 1
+ if not SCons.Util.is_List(args):
+ args = [args]
+ list = []
+ for a in args:
+ if SCons.Util.is_String(a):
+ a = factory(a)
+ list.append(a)
+ return list
def get_scanner(self, ext):
return env_scanner
def Dictionary(self):
d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__']
d['SOURCE'] = d['SOURCES'][0]
return d
-
-env = Environment()
class MyNode_without_target_from_source:
def __init__(self, name):
def test__call__(self):
"""Test calling a builder to establish source dependencies
"""
+ env = Environment()
builder = SCons.Builder.Builder(action="foo", node_factory=MyNode)
n1 = MyNode("n1");
n2 = MyNode("n2");
builder(env, target = n1, source = n2)
+ assert env_arg2nodes_called
assert n1.env == env, n1.env
assert n1.builder == builder, n1.builder
assert n1.sources == [n2], n1.sources
Make sure that there is no '.' separator appended.
"""
+ env = Environment()
builder = SCons.Builder.Builder(prefix = 'lib.')
assert builder.get_prefix(env) == 'lib.'
builder = SCons.Builder.Builder(prefix = 'lib')
Make sure that the '.' separator is appended to the
beginning if it isn't already present.
"""
+ env = Environment()
builder = SCons.Builder.Builder(suffix = '.o')
assert builder.get_suffix(env) == '.o', builder.get_suffix(env)
builder = SCons.Builder.Builder(suffix = 'o')
open(t, 'w').write("function2\n")
return 1
+ env = Environment()
builder = SCons.Builder.Builder(action = function2)
tgts = builder(env, target = [outfile, outfile2], source = 'foo')
for t in tgts:
def test_MultiStepBuilder(self):
"""Testing MultiStepBuilder class."""
+ env = Environment()
builder1 = SCons.Builder.Builder(action='foo',
src_suffix='.bar',
suffix='.foo')
def func_action(target, source, env):
return 0
- env['BAR_SUFFIX'] = '.BAR2'
- env['FOO_SUFFIX'] = '.FOO2'
+ env = Environment(BAR_SUFFIX = '.BAR2', FOO_SUFFIX = '.FOO2')
builder = SCons.Builder.Builder(action={ '.foo' : func_action,
'.bar' : func_action,
'$BAR_SUFFIX' : func_action,
class TestScanner:
pass
scn = TestScanner()
+ env = Environment()
builder = SCons.Builder.Builder(scanner=scn)
tgt = builder(env, target='foo2', source='bar')
assert tgt.target_scanner == scn, tgt.target_scanner
def instance(self, env):
return self
env_scanner = TestScanner()
+ env = Environment()
builder = SCons.Builder.Builder(action='action')
tgt = builder(env, target='foo.x', source='bar')
src = tgt.sources[0]
source.append("baz")
return ( target, source )
+ env = Environment()
builder = SCons.Builder.Builder(action='foo',
emitter=emit,
node_factory=MyNode)
def test_no_target(self):
"""Test deducing the target from the source."""
+ env = Environment()
b = SCons.Builder.Builder(action='foo', suffix='.o')
tgt = b(env, 'aaa')
import SCons.Util
import SCons.Warnings
+class _Null:
+ pass
+
+_null = _Null
+
def installFunc(target, source, env):
"""Install a source file into a target using the function specified
as the INSTALL construction variable."""
options=None,
**kw):
self.fs = SCons.Node.FS.default_fs
+ self.lookup_list = SCons.Node.arg2nodes_lookups
self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
self._dict['BUILDERS'] = BuilderDict(self._dict['BUILDERS'], self)
def __cmp__(self, other):
return cmp(self._dict, other._dict)
+ def arg2nodes(self, args, node_factory=_null, lookup_list=_null):
+ if node_factory is _null:
+ node_factory = self.fs.File
+ if lookup_list is _null:
+ lookup_list = self.lookup_list
+
+ if not args:
+ return []
+
+ if not SCons.Util.is_List(args):
+ args = [args]
+
+ nodes = []
+ for v in args:
+ if SCons.Util.is_String(v):
+ n = None
+ for l in lookup_list:
+ n = l(v)
+ if not n is None:
+ break
+ if not n is None:
+ if SCons.Util.is_String(n):
+ n = self.subst(n, raw=1)
+ if node_factory:
+ n = node_factory(n)
+ nodes.append(n)
+ elif node_factory:
+ v = self.subst(v, raw=1)
+ nodes.append(node_factory(v))
+ else:
+ nodes.append(v)
+
+ return nodes
+
def Builders(self):
pass # XXX
self._dict[envname][name] = nv
- def Depends(self, target, dependency):
- """Explicity specify that 'target's depend on 'dependency'."""
- tlist = SCons.Node.arg2nodes(target, self.fs.File)
- dlist = SCons.Node.arg2nodes(dependency, self.fs.File)
- for t in tlist:
- t.add_dependency(dlist)
+ def Depends(self, target, dependency):
+ """Explicity specify that 'target's depend on 'dependency'."""
+ tlist = self.arg2nodes(target, self.fs.File)
+ dlist = self.arg2nodes(dependency, self.fs.File)
+ for t in tlist:
+ t.add_dependency(dlist)
- if len(tlist) == 1:
- tlist = tlist[0]
- return tlist
+ if len(tlist) == 1:
+ tlist = tlist[0]
+ return tlist
def Ignore(self, target, dependency):
"""Ignore a dependency."""
- tlist = SCons.Node.arg2nodes(target, self.fs.File)
- dlist = SCons.Node.arg2nodes(dependency, self.fs.File)
+ tlist = self.arg2nodes(target, self.fs.File)
+ dlist = self.arg2nodes(dependency, self.fs.File)
for t in tlist:
t.add_ignore(dlist)
def AlwaysBuild(self, *targets):
tlist = []
for t in targets:
- tlist.extend(SCons.Node.arg2nodes(t, self.fs.File))
+ tlist.extend(self.arg2nodes(t, self.fs.File))
for t in tlist:
t.set_always_build()
def Precious(self, *targets):
tlist = []
for t in targets:
- tlist.extend(SCons.Node.arg2nodes(t, self.fs.File))
+ tlist.extend(self.arg2nodes(t, self.fs.File))
for t in tlist:
t.set_precious()
def Install(self, dir, source):
"""Install specified files in the given directory."""
try:
- dnodes = SCons.Node.arg2nodes(dir, self.fs.Dir)
+ dnodes = self.arg2nodes(dir, self.fs.Dir)
except TypeError:
raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir)
try:
- sources = SCons.Node.arg2nodes(source, self.fs.File)
+ sources = self.arg2nodes(source, self.fs.File)
except TypeError:
if SCons.Util.is_List(source):
raise SCons.Errors.UserError, "Source `%s' of Install() contains one or more non-files. Install() source must be one or more files." % repr(map(str, source))
def InstallAs(self, target, source):
"""Install sources as targets."""
- sources = SCons.Node.arg2nodes(source, self.fs.File)
- targets = SCons.Node.arg2nodes(target, self.fs.File)
+ sources = self.arg2nodes(source, self.fs.File)
+ targets = self.arg2nodes(target, self.fs.File)
ret = []
for src, tgt in map(lambda x, y: (x, y), sources, targets):
ret.append(InstallBuilder(self, tgt, src))
def SourceCode(self, entry, builder):
"""Arrange for a source code builder for (part of) a tree."""
- entries = SCons.Node.arg2nodes(entry, self.fs.Entry)
+ entries = self.arg2nodes(entry, self.fs.Entry)
for entry in entries:
entry.set_src_builder(builder)
if len(entries) == 1:
def SideEffect(self, side_effect, target):
"""Tell scons that side_effects are built as side
effects of building targets."""
- side_effects = SCons.Node.arg2nodes(side_effect, self.fs.File)
- targets = SCons.Node.arg2nodes(target, self.fs.File)
+ side_effects = self.arg2nodes(side_effect, self.fs.File)
+ targets = self.arg2nodes(target, self.fs.File)
for side_effect in side_effects:
# A builder of 1 means the node is supposed to appear
env2.Replace(ONE = "won")
assert env2['ONE'] == "won"
assert env['ONE'] == 1
-
+
+ def test_arg2nodes(self):
+ """Test the arg2nodes method
+ """
+ env = Environment()
+ dict = {}
+ class X(SCons.Node.Node):
+ pass
+ def Factory(name, directory = None, create = 1, dict=dict, X=X):
+ if not dict.has_key(name):
+ dict[name] = X()
+ dict[name].name = name
+ return dict[name]
+
+ nodes = env.arg2nodes("Util.py UtilTests.py", Factory)
+ assert len(nodes) == 1, nodes
+ assert isinstance(nodes[0], X)
+ assert nodes[0].name == "Util.py UtilTests.py"
+
+ import types
+ if hasattr(types, 'UnicodeType'):
+ code = """if 1:
+ nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
+ assert len(nodes) == 1, nodes
+ assert isinstance(nodes[0], X)
+ assert nodes[0].name == u"Util.py UtilTests.py"
+ \n"""
+ exec code in globals(), locals()
+
+ nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory)
+ assert len(nodes) == 2, nodes
+ assert isinstance(nodes[0], X)
+ assert isinstance(nodes[1], X)
+ assert nodes[0].name == "Util.py"
+ assert nodes[1].name == "UtilTests.py"
+
+ n1 = Factory("Util.py")
+ nodes = env.arg2nodes([n1, "UtilTests.py"], Factory)
+ assert len(nodes) == 2, nodes
+ assert isinstance(nodes[0], X)
+ assert isinstance(nodes[1], X)
+ assert nodes[0].name == "Util.py"
+ assert nodes[1].name == "UtilTests.py"
+
+ class SConsNode(SCons.Node.Node):
+ pass
+ nodes = env.arg2nodes(SConsNode())
+ assert len(nodes) == 1, nodes
+ assert isinstance(nodes[0], SConsNode), node
+
+ class OtherNode:
+ pass
+ nodes = env.arg2nodes(OtherNode())
+ assert len(nodes) == 1, nodes
+ assert isinstance(nodes[0], OtherNode), node
+
+ def lookup_a(str, F=Factory):
+ if str[0] == 'a':
+ n = F(str)
+ n.a = 1
+ return n
+ else:
+ return None
+
+ def lookup_b(str, F=Factory):
+ if str[0] == 'b':
+ n = F(str)
+ n.b = 1
+ return n
+ else:
+ return None
+
+ env_ll = env.Copy()
+ env_ll.lookup_list = [lookup_a, lookup_b]
+
+ nodes = env_ll.arg2nodes(['aaa', 'bbb', 'ccc'], Factory)
+ assert len(nodes) == 3, nodes
+
+ assert nodes[0].name == 'aaa', nodes[0]
+ assert nodes[0].a == 1, nodes[0]
+ assert not hasattr(nodes[0], 'b'), nodes[0]
+
+ assert nodes[1].name == 'bbb'
+ assert not hasattr(nodes[1], 'a'), nodes[1]
+ assert nodes[1].b == 1, nodes[1]
+
+ assert nodes[2].name == 'ccc'
+ assert not hasattr(nodes[2], 'a'), nodes[1]
+ assert not hasattr(nodes[2], 'b'), nodes[1]
+
+ def lookup_bbbb(str, F=Factory):
+ if str == 'bbbb':
+ n = F(str)
+ n.bbbb = 1
+ return n
+ else:
+ return None
+
+ def lookup_c(str, F=Factory):
+ if str[0] == 'c':
+ n = F(str)
+ n.c = 1
+ return n
+ else:
+ return None
+
+ nodes = env.arg2nodes(['bbbb', 'ccc'], Factory,
+ [lookup_c, lookup_bbbb, lookup_b])
+ assert len(nodes) == 2, nodes
+
+ assert nodes[0].name == 'bbbb'
+ assert not hasattr(nodes[0], 'a'), nodes[1]
+ assert not hasattr(nodes[0], 'b'), nodes[1]
+ assert nodes[0].bbbb == 1, nodes[1]
+ assert not hasattr(nodes[0], 'c'), nodes[0]
+
+ assert nodes[1].name == 'ccc'
+ assert not hasattr(nodes[1], 'a'), nodes[1]
+ assert not hasattr(nodes[1], 'b'), nodes[1]
+ assert not hasattr(nodes[1], 'bbbb'), nodes[0]
+ assert nodes[1].c == 1, nodes[1]
+
def test_Builder_calls(self):
"""Test Builder calls through different environments
"""
def test_Install(self):
"""Test Install and InstallAs methods"""
- env=Environment()
+ env = Environment(FOO='iii', BAR='jjj')
+
tgt = env.Install('export', [ 'build/foo1', 'build/foo2' ])
paths = map(str, tgt)
paths.sort()
for tnode in tgt:
assert tnode.builder == InstallBuilder
+ tgt = env.Install('$FOO', [ 'build/${BAR}1', 'build/${BAR}2' ])
+ paths = map(str, tgt)
+ paths.sort()
+ expect = map(os.path.normpath, [ 'iii/jjj1', 'iii/jjj2' ])
+ assert paths == expect, paths
+ for tnode in tgt:
+ assert tnode.builder == InstallBuilder
+
exc_caught = None
try:
tgt = env.Install('export', 'export')
for tnode in tgt:
assert tnode.builder == InstallBuilder
+ tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')
+ assert tgt.path == 'iii.t'
+ assert tgt.sources[0].path == 'jjj.s'
+ assert tgt.builder == InstallBuilder
+
def test_ReservedVariables(self):
"""Test generation of warnings when reserved variable names
are set in an environment."""
def test_Depends(self):
"""Test the explicit Depends method."""
- env = Environment()
+ env = Environment(FOO = 'xxx', BAR='yyy')
t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
assert t.__class__.__name__ == 'File'
assert t.path == 'EnvironmentTest.py'
assert d.__class__.__name__ == 'File'
assert d.path == 'Environment.py'
+ t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')
+ assert t.__class__.__name__ == 'File'
+ assert t.path == 'xxx.py'
+ assert len(t.depends) == 1
+ d = t.depends[0]
+ assert d.__class__.__name__ == 'File'
+ assert d.path == 'yyy.py'
+
def test_Ignore(self):
"""Test the explicit Ignore method."""
- env = Environment()
+ env = Environment(FOO='yyy', BAR='zzz')
t = env.Ignore(target='targ.py', dependency='dep.py')
assert t.__class__.__name__ == 'File'
assert t.path == 'targ.py'
i = t.ignore[0]
assert i.__class__.__name__ == 'File'
assert i.path == 'dep.py'
+ t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')
+ assert t.__class__.__name__ == 'File'
+ assert t.path == 'yyyzzz'
+ assert len(t.ignore) == 1
+ i = t.ignore[0]
+ assert i.__class__.__name__ == 'File'
+ assert i.path == 'zzzyyy'
def test_AlwaysBuild(self):
"""Test the AlwaysBuild() method"""
- env = Environment()
- t = env.AlwaysBuild('a', 'b', ['c', 'd'])
+ env = Environment(FOO='fff', BAR='bbb')
+ t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR')
assert t[0].__class__.__name__ == 'File'
assert t[0].path == 'a'
assert t[0].always_build
assert t[1].__class__.__name__ == 'File'
- assert t[1].path == 'b'
+ assert t[1].path == 'bfff'
assert t[1].always_build
assert t[2].__class__.__name__ == 'File'
assert t[2].path == 'c'
assert t[3].__class__.__name__ == 'File'
assert t[3].path == 'd'
assert t[3].always_build
+ assert t[4].__class__.__name__ == 'File'
+ assert t[4].path == 'bbb'
+ assert t[4].always_build
def test_Precious(self):
"""Test the Precious() method."""
- env = Environment()
- t = env.Precious('a', 'b', ['c', 'd'])
+ env = Environment(FOO='ggg', BAR='hhh')
+ t = env.Precious('a', '${BAR}b', ['c', 'd'], '$FOO')
assert t[0].__class__.__name__ == 'File'
assert t[0].path == 'a'
assert t[0].precious
assert t[1].__class__.__name__ == 'File'
- assert t[1].path == 'b'
+ assert t[1].path == 'hhhb'
assert t[1].precious
assert t[2].__class__.__name__ == 'File'
assert t[2].path == 'c'
assert t[3].__class__.__name__ == 'File'
assert t[3].path == 'd'
assert t[3].precious
+ assert t[4].__class__.__name__ == 'File'
+ assert t[4].path == 'ggg'
+ assert t[4].precious
def test_Command(self):
"""Test the Command() method."""
def test_SourceCode(self):
"""Test the SourceCode() method."""
- env = Environment()
+ env = Environment(FOO='mmm', BAR='nnn')
e = env.SourceCode('foo', None)
+ assert e.path == 'foo'
s = e.src_builder()
assert s is None, s
b = Builder()
- env.SourceCode(e, b)
+ e = env.SourceCode(e, b)
+ assert e.path == 'foo'
s = e.src_builder()
assert s is b, s
+ e = env.SourceCode('$BAR$FOO', None)
+ assert e.path == 'nnnmmm'
+ s = e.src_builder()
+ assert s is None, s
+
def test_SideEffect(self):
"""Test the SideEffect() method"""
- env = Environment()
+ env = Environment(LIB='lll', FOO='fff', BAR='bbb')
+
foo = env.Object('foo.obj', 'foo.cpp')
bar = env.Object('bar.obj', 'bar.cpp')
s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])
+ assert s.path == 'mylib.pdb'
assert s.side_effect
assert foo.side_effects == [s]
assert bar.side_effects == [s]
assert s.depends_on([bar])
assert s.depends_on([foo])
+ fff = env.Object('fff.obj', 'fff.cpp')
+ bbb = env.Object('bbb.obj', 'bbb.cpp')
+ s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])
+ assert s.path == 'mylll.pdb'
+ assert s.side_effect
+ assert fff.side_effects == [s], fff.side_effects
+ assert bbb.side_effects == [s], bbb.side_effects
+ assert s.depends_on([bbb])
+ assert s.depends_on([fff])
+
def test_subst(self):
"""Test substituting construction variables within strings
strSubst = string.replace(string.replace(strSubst, '\0\4', '$'),
'\0\5', '')
# strip out redundant white-space
- return string.strip(_space_sep.sub(' ', strSubst))
+ if mode != SUBST_RAW:
+ strSubst = string.strip(_space_sep.sub(' ', strSubst))
+ return strSubst
def render_tree(root, child_func, prune=0, margin=[0], visited={}):
"""
assert newcom == cvt("test foo/blah.cppblah /bar/ack.cppblah"), newcom
newcom = scons_subst("test $xxx", env)
+ assert newcom == cvt("test "), newcom
+ newcom = scons_subst("test $xxx", env, mode=SUBST_CMD)
+ assert newcom == cvt("test"), newcom
+ newcom = scons_subst("test $xxx", env, mode=SUBST_SIG)
assert newcom == cvt("test"), newcom
newcom = scons_subst("test $($xxx$)", env)
assert newcom == cvt("test $($)"), newcom
-
- newcom = scons_subst("test $( $xxx $)", env)
- assert newcom == cvt("test $( $)"), newcom
-
+ newcom = scons_subst("test $($xxx$)", env, mode=SUBST_CMD)
+ assert newcom == cvt("test"), newcom
newcom = scons_subst("test $($xxx$)", env, mode=SUBST_SIG)
assert newcom == cvt("test"), newcom
+ newcom = scons_subst("test $( $xxx $)", env)
+ assert newcom == cvt("test $( $)"), newcom
+ newcom = scons_subst("test $( $xxx $)", env, mode=SUBST_CMD)
+ assert newcom == cvt("test"), newcom
newcom = scons_subst("test $( $xxx $)", env, mode=SUBST_SIG)
assert newcom == cvt("test"), newcom
test = TestSCons.TestSCons()
-test.write('SConstruct', """
+test.subdir('sub')
+
+test.write('SConstruct', """\
def bfunc(target, source, env):
import shutil
shutil.copyfile('f2.in', str(target[0]))
B = Builder(action=bfunc)
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(BUILDERS = { 'B' : B }, SUBDIR='sub')
env.B('f1.out', source='f1.in')
env.AlwaysBuild('f1.out')
-""")
+
+env.B(r'%s', source='f3.in')
+env.AlwaysBuild(r'%s')
+""" % (os.path.join('sub', 'f3.out'),
+ os.path.join('$SUBDIR', 'f3.out')
+ ))
test.write('f1.in', "f1.in\n")
test.write('f2.in', "1")
+test.write('f3.in', "f3.in\n")
test.run(arguments = ".")
test.fail_test(test.read('f1.out') != '1')
+test.fail_test(test.read(['sub', 'f3.out']) != '1')
test.write('f2.in', "2")
+
test.run(arguments = ".")
test.fail_test(test.read('f1.out') != '2')
+test.fail_test(test.read(['sub', 'f3.out']) != '2')
test.pass_test()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import sys
+import os.path
+
import TestSCons
python = TestSCons.python
test.write('SConstruct', """
Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep")
Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep")
-env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar })
-env.Depends(target = ['f1.out', 'f2.out'], dependency = 'subdir/foo.dep')
-env.Depends(target = 'f3.out', dependency = 'subdir/bar.dep')
+env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
+env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%s')
+env.Depends(target = r'%s', dependency = 'subdir/bar.dep')
env.Foo(target = 'f1.out', source = 'f1.in')
env.Foo(target = 'f2.out', source = 'f2.in')
-env.Bar(target = 'f3.out', source = 'f3.in')
+env.Bar(target = 'subdir/f3.out', source = 'f3.in')
SConscript('subdir/SConscript', "env")
-""" % (python, python))
+""" % (python,
+ python,
+ os.path.join('$SUBDIR', 'foo.dep'),
+ os.path.join('$SUBDIR', 'f3.out')))
test.write(['subdir', 'SConscript'], """
Import("env")
test.write(['subdir', 'bar.dep'], "subdir/bar.dep 1\n")
-test.run(arguments = '.')
+test.run(arguments = '--debug=dtree .')
test.fail_test(test.read('f1.out') != "f1.in\nsubdir/foo.dep 1\n")
test.fail_test(test.read('f2.out') != "f2.in\nsubdir/foo.dep 1\n")
-test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 1\n")
+test.fail_test(test.read(['subdir', 'f3.out']) != "f3.in\nsubdir/bar.dep 1\n")
test.fail_test(test.read(['subdir', 'f4.out']) !=
"subdir/f4.in\nsubdir/bar.dep 1\n")
test.fail_test(test.read('f1.out') != "f1.in\nsubdir/foo.dep 2\n")
test.fail_test(test.read('f2.out') != "f2.in\nsubdir/foo.dep 2\n")
-test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 2\n")
+test.fail_test(test.read(['subdir', 'f3.out']) != "f3.in\nsubdir/bar.dep 2\n")
test.fail_test(test.read(['subdir', 'f4.out']) !=
"subdir/f4.in\nsubdir/bar.dep 2\n")
test.fail_test(test.read('f1.out') != "f1.in\nsubdir/foo.dep 2\n")
test.fail_test(test.read('f2.out') != "f2.in\nsubdir/foo.dep 2\n")
-test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 3\n")
+test.fail_test(test.read(['subdir', 'f3.out']) != "f3.in\nsubdir/bar.dep 3\n")
test.fail_test(test.read(['subdir', 'f4.out']) !=
"subdir/f4.in\nsubdir/bar.dep 3\n")
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import sys
+import os.path
+
import TestSCons
python = TestSCons.python
file.close()
""")
-test.write('SConstruct', """
+test.write('SConstruct', """\
Foo = Builder(action = r"%s build.py $TARGET $SOURCES")
Bar = Builder(action = r"%s build.py $TARGET $SOURCES")
-env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar })
+env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
env.Foo(target = 'f1.out', source = ['f1a.in', 'f1b.in'])
env.Ignore(target = 'f1.out', dependency = 'f1b.in')
SConscript('subdir/SConscript', "env")
-""" % (python, python))
+env.Foo(target = 'subdir/f3.out', source = ['subdir/f3a.in', 'subdir/f3b.in'])
+env.Ignore(target = r'%s', dependency = r'%s')
+""" % (python,
+ python,
+ os.path.join('$SUBDIR', 'f3.out'),
+ os.path.join('$SUBDIR', 'f3b.in')))
test.write(['subdir', 'SConscript'], """
Import("env")
test.write(['subdir', 'f2a.in'], "subdir/f2a.in\n")
test.write(['subdir', 'f2b.in'], "subdir/f2b.in\n")
+test.write(['subdir', 'f3a.in'], "subdir/f3a.in\n")
+test.write(['subdir', 'f3b.in'], "subdir/f3b.in\n")
+
test.run(arguments = '.')
test.fail_test(test.read('f1.out') != "f1a.in\nf1b.in\n")
test.fail_test(test.read(['subdir', 'f2.out']) !=
"subdir/f2a.in\nsubdir/f2b.in\n")
+test.fail_test(test.read(['subdir', 'f3.out']) !=
+ "subdir/f3a.in\nsubdir/f3b.in\n")
test.up_to_date(arguments = '.')
test.write('f1b.in', "f1b.in 2\n")
test.write(['subdir', 'f2a.in'], "subdir/f2a.in 2\n")
+test.write(['subdir', 'f3b.in'], "subdir/f3b.in 2\n")
test.up_to_date(arguments = '.')
test.fail_test(test.read('f1.out') != "f1a.in\nf1b.in\n")
test.fail_test(test.read(['subdir', 'f2.out']) !=
"subdir/f2a.in\nsubdir/f2b.in\n")
+test.fail_test(test.read(['subdir', 'f3.out']) !=
+ "subdir/f3a.in\nsubdir/f3b.in\n")
test.write('f1a.in', "f1a.in 2\n")
test.write(['subdir', 'f2b.in'], "subdir/f2b.in 2\n")
+test.write(['subdir', 'f3a.in'], "subdir/f3a.in 2\n")
test.run(arguments = '.')
test.fail_test(test.read('f1.out') != "f1a.in 2\nf1b.in 2\n")
test.fail_test(test.read(['subdir', 'f2.out']) !=
"subdir/f2a.in 2\nsubdir/f2b.in 2\n")
+test.fail_test(test.read(['subdir', 'f3.out']) !=
+ "subdir/f3a.in 2\nsubdir/f3b.in 2\n")
test.up_to_date(arguments = '.')
test = TestSCons.TestSCons()
+test.subdir('sub')
+
f1_out = test.workpath('export', 'f1.out')
f2_out = test.workpath('export', 'f2.out')
f3_out = test.workpath('export', 'f3.out')
+f4_out = test.workpath('export', 'f4.out')
test.write('SConstruct', """\
def cat(env, source, target):
t = env3.Cat(target='f3.out', source='f3.in')
env3.Install(dir='export', source=t)
-""")
+
+env4 = env1.Copy(EXPORT='export', SUBDIR='sub')
+t = env4.Cat(target='sub/f4.out', source='sub/f4.in')
+env4.Install(dir='$EXPORT', source=r'%s')
+""" % (os.path.join('$SUBDIR', 'f4.out')))
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
test.write('f3.in', "f3.in\n")
+test.write(['sub', 'f4.in'], "sub/f4.in\n")
test.run(arguments = '.')
test.fail_test(test.read(f1_out) != "f1.in\n")
test.fail_test(test.read(f2_out) != "f2.in\n")
test.fail_test(test.read(f3_out) != "f3.in\n")
+test.fail_test(test.read(f4_out) != "sub/f4.in\n")
test.fail_test(test.read('my_install.out') != os.path.join('export', 'f3.out'))
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test the InstallAs() Environment method.
+"""
+
+import os.path
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('install', 'subdir')
+
+install = test.workpath('install')
+install_file1_out = test.workpath('install', 'file1.out')
+install_file2_out = test.workpath('install', 'file2.out')
+install_file3_out = test.workpath('install', 'file3.out')
+
+#
+test.write('SConstruct', r"""
+env = Environment(INSTALLDIR=r'%s', SUBDIR='subdir')
+env.InstallAs(r'%s', 'file1.in')
+env.InstallAs([r'%s', r'%s'], ['file2.in', r'%s'])
+""" % (install,
+ install_file1_out,
+ os.path.join('$INSTALLDIR', 'file2.out'),
+ install_file3_out,
+ os.path.join('$SUBDIR', 'file3.in')))
+
+test.write('file1.in', "file1.in\n")
+test.write('file2.in', "file2.in\n")
+test.write(['subdir', 'file3.in'], "subdir/file3.in\n")
+
+test.run(arguments = '.')
+
+test.fail_test(test.read(install_file1_out) != "file1.in\n")
+test.fail_test(test.read(install_file2_out) != "file2.in\n")
+test.fail_test(test.read(install_file3_out) != "subdir/file3.in\n")
+
+test.up_to_date(arguments = '.')
+
+#
+test.pass_test()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os
-import sys
+import os.path
+
import TestSCons
python = TestSCons.python
sys.exit(0)
""")
-test.write('SConstruct', """
+test.write('SConstruct', """\
B = Builder(action = r"%s build.py $TARGET $SOURCES")
-env = Environment(BUILDERS = { 'B' : B })
+env = Environment(BUILDERS = { 'B' : B }, SUBDIR = 'subdir')
f1 = env.B(target = 'f1.out', source = 'f1.in')
env.B(target = 'f2.out', source = 'f2.in')
env.B(target = 'f3.out', source = 'f3.in')
-env.Precious(f1, 'f2.out')
+env.B(target = 'subdir/f4.out', source = 'f4.in')
+env.Precious(f1, 'f2.out', r'%s')
SConscript('subdir/SConscript', "env")
-""" % python)
+""" % (python,
+ os.path.join('$SUBDIR', 'f4.out')))
test.write(['subdir', 'SConscript'], """
Import("env")
-env.B(target = 'f4.out', source = 'f4.in')
-f5 = env.B(target = 'f5.out', source = 'f5.in')
-env.B(target = 'f6.out', source = 'f6.in')
-env.Precious(['f4.out', f5])
+env.B(target = 'f5.out', source = 'f5.in')
+f6 = env.B(target = 'f6.out', source = 'f6.in')
+env.B(target = 'f7.out', source = 'f7.in')
+env.Precious(['f5.out', f6])
""")
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
test.write('f3.in', "f3.in\n")
+test.write('f4.in', "f4.in\n")
-test.write(['subdir', 'f4.in'], "subdir/f4.in\n")
test.write(['subdir', 'f5.in'], "subdir/f5.in\n")
test.write(['subdir', 'f6.in'], "subdir/f6.in\n")
+test.write(['subdir', 'f7.in'], "subdir/f7.in\n")
test.write('f1.out', "SHOULD NOT BE REMOVED\n")
test.write('f2.out', "SHOULD NOT BE REMOVED\n")
test.write('f3.out', "SHOULD BE REMOVED\n")
-
test.write(['subdir', 'f4.out'], "SHOULD NOT BE REMOVED\n")
+
test.write(['subdir', 'f5.out'], "SHOULD NOT BE REMOVED\n")
-test.write(['subdir', 'f6.out'], "SHOULD BE REMOVED\n")
+test.write(['subdir', 'f6.out'], "SHOULD NOT BE REMOVED\n")
+test.write(['subdir', 'f7.out'], "SHOULD BE REMOVED\n")
test.run(arguments = '.')
test.fail_test(not os.path.exists(test.workpath('f1.out')))
test.fail_test(not os.path.exists(test.workpath('f2.out')))
test.fail_test(os.path.exists(test.workpath('f3.out')))
-
test.fail_test(not os.path.exists(test.workpath('subdir', 'f4.out')))
+
test.fail_test(not os.path.exists(test.workpath('subdir', 'f5.out')))
-test.fail_test(os.path.exists(test.workpath('subdir', 'f6.out')))
+test.fail_test(not os.path.exists(test.workpath('subdir', 'f6.out')))
+test.fail_test(os.path.exists(test.workpath('subdir', 'f7.out')))
test.write('f3.out', "SHOULD BE REMOVED\n")
-test.write(['subdir', 'f6.out'], "SHOULD BE REMOVED\n")
+test.write(['subdir', 'f7.out'], "SHOULD BE REMOVED\n")
test.run(arguments = '.')
test.fail_test(not os.path.exists(test.workpath('f1.out')))
test.fail_test(not os.path.exists(test.workpath('f2.out')))
test.fail_test(not os.path.exists(test.workpath('f3.out')))
-
test.fail_test(not os.path.exists(test.workpath('subdir', 'f4.out')))
+
test.fail_test(not os.path.exists(test.workpath('subdir', 'f5.out')))
test.fail_test(not os.path.exists(test.workpath('subdir', 'f6.out')))
+test.fail_test(not os.path.exists(test.workpath('subdir', 'f7.out')))
test.write('f3.in', "f3.in 2\n")
-test.write(['subdir', 'f6.in'], "subdir/f6.in 2\n")
+test.write(['subdir', 'f7.in'], "subdir/f7.in 2\n")
test.run(arguments = '.')
test.fail_test(not os.path.exists(test.workpath('f1.out')))
test.fail_test(not os.path.exists(test.workpath('f2.out')))
test.fail_test(os.path.exists(test.workpath('f3.out')))
-
test.fail_test(not os.path.exists(test.workpath('subdir', 'f4.out')))
+
test.fail_test(not os.path.exists(test.workpath('subdir', 'f5.out')))
-test.fail_test(os.path.exists(test.workpath('subdir', 'f6.out')))
+test.fail_test(not os.path.exists(test.workpath('subdir', 'f6.out')))
+test.fail_test(os.path.exists(test.workpath('subdir', 'f7.out')))
test.pass_test()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import TestSCons
import os.path
+import TestSCons
+
test = TestSCons.TestSCons()
-test.write('SConstruct',
-"""
+test.write('SConstruct', """\
def copy(source, target):
open(target, "wb").write(open(source, "rb").read())
copy(str(source[0]), str(target[0]))
if target[0].side_effects:
side_effect = open(str(target[0].side_effects[0]), "ab")
- side_effect.write('%s -> %s\\n'%(str(source[0]), str(target[0])))
+ side_effect.write('%%s -> %%s\\n'%%(str(source[0]), str(target[0])))
Build = Builder(action=build)
-env = Environment(BUILDERS={'Build':Build})
+env = Environment(BUILDERS={'Build':Build}, SUBDIR='subdir')
env.Build('foo.out', 'foo.in')
env.Build('bar.out', 'bar.in')
env.Build('blat.out', 'blat.in')
env.SideEffect('log.txt', ['foo.out', 'bar.out', 'blat.out'])
env.Build('log.out', 'log.txt')
-""")
+env.Build('subdir/baz.out', 'baz.in')
+env.SideEffect(r'%s', ['blat.out', r'%s'])
+env.Build('subdir/out.out', 'subdir/out.txt')
+""" % (os.path.join('$SUBDIR', 'out.txt'),
+ os.path.join('$SUBDIR', 'baz.out')))
test.write('foo.in', 'foo.in\n')
test.write('bar.in', 'bar.in\n')
test.write('blat.in', 'blat.in\n')
+test.write('baz.in', 'baz.in\n')
test.run(arguments = 'foo.out bar.out', stdout=test.wrap_stdout("""\
build("foo.out", "foo.in")
test.run(arguments = ".", stdout=test.wrap_stdout("""\
build("foo.out", "foo.in")
build("log.out", "log.txt")
-"""))
+build("%s", "baz.in")
+build("%s", "%s")
+""" % (os.path.join('subdir', 'baz.out'),
+ os.path.join('subdir', 'out.out'),
+ os.path.join('subdir', 'out.txt'))))
expect = """\
foo.in -> foo.out
build("blat.out", "blat.in")
build("foo.out", "foo.in")
build("log.out", "log.txt")
-"""))
+build("%s", "baz.in")
+build("%s", "%s")
+""" % (os.path.join('subdir', 'baz.out'),
+ os.path.join('subdir', 'out.out'),
+ os.path.join('subdir', 'out.txt'))))
expect = """\
bar.in -> bar.out
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test fetching source files using the SourceCode() method.
+"""
+
+import os
+import stat
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('sub')
+
+test.write('SConstruct', """\
+import os.path
+
+def cat(env, source, target):
+ target = str(target[0])
+ source = map(str, source)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+
+def sc_cat(env, source, target):
+ source = []
+ for t in target:
+ head, tail = os.path.split(str(t))
+ source.append(os.path.join(head, 'sc-' + tail))
+ cat(env, source, target)
+
+env = Environment(BUILDERS={'Cat':Builder(action=cat)}, SUBDIR='sub')
+env.Cat('aaa.out', 'sub/aaa.in')
+env.Cat('bbb.out', 'sub/bbb.in')
+env.Cat('ccc.out', 'sub/ccc.in')
+env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out'])
+env.SourceCode('$SUBDIR', Builder(action=sc_cat, env=env))
+SConscript('sub/SConscript', "env")
+""")
+
+test.write(['sub', 'sc-aaa.in'], "sub/sc-aaa.in\n")
+test.write(['sub', 'sc-bbb.in'], "sub/sc-bbb.in\n")
+test.write(['sub', 'sc-ccc.in'], "sub/sc-ccc.in\n")
+
+test.write(['sub', 'sc-SConscript'], "'sub/sc-SConscript'\n")
+
+test.run(arguments = '.',
+ stdout = test.wrap_stdout(read_str = """\
+sc_cat("%s", [])
+""" % (os.path.join('sub', 'SConscript')),
+ build_str = """\
+sc_cat("%s", [])
+cat("aaa.out", "%s")
+sc_cat("%s", [])
+cat("bbb.out", "%s")
+sc_cat("%s", [])
+cat("ccc.out", "%s")
+cat("all", ["aaa.out", "bbb.out", "ccc.out"])
+""" % (os.path.join('sub', 'aaa.in'),
+ os.path.join('sub', 'aaa.in'),
+ os.path.join('sub', 'bbb.in'),
+ os.path.join('sub', 'bbb.in'),
+ os.path.join('sub', 'ccc.in'),
+ os.path.join('sub', 'ccc.in'))))
+
+test.fail_test(test.read(['sub', 'SConscript']) != "'sub/sc-SConscript'\n")
+test.fail_test(test.read('all') != "sub/sc-aaa.in\nsub/sc-bbb.in\nsub/sc-ccc.in\n")
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test construction variable expansion in Builder paths.
+"""
+
+import os.path
+import sys
+import time
+import TestSCons
+
+_exe = TestSCons._exe
+_obj = TestSCons._obj
+
+test = TestSCons.TestSCons()
+
+test.subdir('sub')
+
+test.write('SConstruct', """\
+env = Environment(SUBDIR = 'sub')
+env.Program(target = 'foo1', source = env.Object(source = r'%s'))
+env.Program(source = env.Object(target = r'%s', source = 'f2.c'))
+env.Program('foo3', r'%s')
+env.Program(r'%s')
+""" % (os.path.join('$SUBDIR', 'f1.c'),
+ os.path.join('$SUBDIR', 'foo2'),
+ os.path.join('$SUBDIR', 'f3.c'),
+ os.path.join('$SUBDIR', 'foo4.c')))
+
+test.write(['sub', 'f1.c'], r"""
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("sub/f1.c\n");
+ exit (0);
+}
+""")
+
+test.write('f2.c', r"""
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("f2.c\n");
+ exit (0);
+}
+""")
+
+test.write(['sub', 'f3.c'], r"""
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("sub/f3.c\n");
+ exit (0);
+}
+""")
+
+test.write(['sub', 'foo4.c'], r"""
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("sub/foo4.c\n");
+ exit (0);
+}
+""")
+
+test.run(arguments = '.')
+
+test.run(program = test.workpath('foo1' + _exe), stdout = "sub/f1.c\n")
+test.run(program = test.workpath('sub', 'foo2' + _exe), stdout = "f2.c\n")
+test.run(program = test.workpath('foo3' + _exe), stdout = "sub/f3.c\n")
+test.run(program = test.workpath('sub','foo4' + _exe), stdout = "sub/foo4.c\n")
+
+test.fail_test(not os.path.exists(test.workpath('sub', 'f1' + _obj)))
+test.fail_test(not os.path.exists(test.workpath('sub', 'foo2' + _obj)))
+test.fail_test(not os.path.exists(test.workpath('sub', 'f3' + _obj)))
+test.fail_test(not os.path.exists(test.workpath('sub', 'foo4' + _obj)))
+
+test.up_to_date(arguments = '.')
+
+test.pass_test()
"File&with&ersand",
"File?with?question",
"File\twith\ttab",
- "File$with$dollar",
+ "File$$with$$dollar",
"Combination '\"\n\\;<>?|*\t&"
]
file_names = []
for fn in attempt_file_names:
try:
- test.write(fn + '.in', fn + '\n')
+ in_name = string.replace(fn, '$$', '$') + '.in'
+ test.write(in_name, fn + '\n')
file_names.append(fn)
except IOError:
# if the Python interpreter can't handle it, don't bother
test.run(arguments='.')
for fn in file_names:
- test.fail_test(test.read(fn + '.out') != fn + '\n')
+ out_name = string.replace(fn, '$$', '$') + '.out'
+ test.fail_test(test.read(out_name) != fn + '\n')
test.pass_test()