final_sources = []
src_suffix = env.subst(self.src_suffix)
for snode in slist:
- path, ext = os.path.splitext(snode.path)
+ path, ext = os.path.splitext(snode.abspath)
if not src_suffix or ext != src_suffix:
tgt = self.src_builder(env, target = [ path ],
source=snode)
scn = TestScanner()
builder=SCons.Builder.Builder(scanner=scn)
tgt = builder(env, target='foo', source='bar')
- assert tgt.scanner == scn, tgt.scanner
+ assert scn in tgt.scanners, tgt.scanners
assert instanced
instanced = None
src_builder = builder1,
scanner = scn)
tgt = builder2(env, target='baz', source='test.bar test2.foo test3.txt')
- assert tgt.scanner == scn, tgt.scanner
+ assert scn in tgt.scanners, tgt.scanners
assert instanced
def test_src_scanner(slf):
env_scanner = TestScanner()
builder = SCons.Builder.Builder(action='action')
tgt = builder(env, target='foo', source='bar')
- assert not tgt.scanner == env_scanner
- assert tgt.sources[0].scanner == env_scanner
+ assert not tgt.scanners == [ env_scanner ]
+ assert tgt.sources[0].scanners == [ env_scanner ]
if __name__ == "__main__":
suite = unittest.makeSuite(BuilderTestCase, 'test_')
import types
import SCons.Util
import SCons.Builder
+import SCons.Defaults
from SCons.Errors import UserError
from UserList import UserList
def InstallAs():
pass # XXX
-
-
-def _deepcopy_atomic(x, memo):
- return x
-copy._deepcopy_dispatch[types.ModuleType] = _deepcopy_atomic
-copy._deepcopy_dispatch[types.ClassType] = _deepcopy_atomic
-copy._deepcopy_dispatch[types.FunctionType] = _deepcopy_atomic
-copy._deepcopy_dispatch[types.MethodType] = _deepcopy_atomic
-copy._deepcopy_dispatch[types.TracebackType] = _deepcopy_atomic
-copy._deepcopy_dispatch[types.FrameType] = _deepcopy_atomic
-copy._deepcopy_dispatch[types.FileType] = _deepcopy_atomic
-
-
+def our_deepcopy(x):
+ """deepcopy lists and dictionaries, and just copy the reference
+ for everything else."""
+ if type(x) is type({}):
+ copy = {}
+ for key in x.keys():
+ copy[key] = our_deepcopy(x[key])
+ elif type(x) is type([]):
+ copy = map(our_deepcopy, x)
+ else:
+ copy = x
+ return copy
class Environment:
"""Base class for construction Environments. These are
def __init__(self, **kw):
import SCons.Defaults
- self._dict = copy.deepcopy(SCons.Defaults.ConstructionEnvironment)
+ self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
if kw.has_key('BUILDERS') and type(kw['BUILDERS']) != type([]):
kw['BUILDERS'] = [kw['BUILDERS']]
if kw.has_key('SCANNERS') and type(kw['SCANNERS']) != type([]):
kw['SCANNERS'] = [kw['SCANNERS']]
- self._dict.update(copy.deepcopy(kw))
+ self._dict.update(our_deepcopy(kw))
class BuilderWrapper:
"""Wrapper class that allows an environment to
(like a function). There are no references to any mutable
objects in the original Environment.
"""
- clone = copy.deepcopy(self)
+ clone = copy.copy(self)
+ clone._dict = our_deepcopy(self._dict)
apply(clone.Update, (), kw)
return clone
"""Update an existing construction Environment with new
construction variables and/or values.
"""
- self._dict.update(copy.deepcopy(kw))
+ self._dict.update(our_deepcopy(kw))
def Depends(self, target, dependency):
"""Explicity specify that 'target's depend on 'dependency'."""
assert env3.Dictionary('ZZZ') == 'z3'
assert env1 == env1copy
+ # Ensure that lists and dictionaries are
+ # deep copied, but not instances.
+ class TestA:
+ pass
+ env1 = Environment(XXX=TestA(), YYY = [ 1, 2, 3 ],
+ ZZZ = { 1:2, 3:4 })
+ env2=env1.Copy()
+ env2.Dictionary('YYY').append(4)
+ env2.Dictionary('ZZZ')[5] = 6
+ assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
+ assert 4 in env2.Dictionary('YYY')
+ assert not 4 in env1.Dictionary('YYY')
+ assert env2.Dictionary('ZZZ').has_key(5)
+ assert not env1.Dictionary('ZZZ').has_key(5)
+
def test_Dictionary(self):
"""Test retrieval of known construction variables
return self.dir.sconsign().get(self.name)
def scan(self):
- if not self.scanned.has_key(self.scanner) and self.env:
- if self.scanner:
- self.add_implicit(self.scanner.scan(self.path, self.env),
- self.scanner)
- self.scanned[self.scanner] = 1
+ if self.env:
+ for scn in self.scanners:
+ if not self.scanned.has_key(scn):
+ self.add_implicit(scn.scan(self.path, self.env),
+ scn)
+ self.scanned[scn] = 1
def __createDir(self):
# ensure that the directories for this node are
match(e13.path, "subdir/subdir/e13")
# Test scanning
- f1.scanner = Scanner()
+ scn = Scanner()
+ f1.scanners = [ scn ]
f1.scan()
- assert f1.implicit[f1.scanner][0].path_ == os.path.join("d1", "f1")
- del f1.implicit[f1.scanner]
+ assert f1.implicit[scn][0].path_ == os.path.join("d1", "f1")
+ del f1.implicit[scn]
f1.scan()
assert len(f1.implicit) == 0, f1.implicit
- del f1.scanned[f1.scanner]
+ del f1.scanned[scn]
f1.scan()
- assert f1.implicit[f1.scanner][0].path_ == os.path.join("d1", "f1")
+ assert f1.implicit[scn][0].path_ == os.path.join("d1", "f1")
# Test building a file whose directory is not there yet...
f1 = fs.File(test.workpath("foo/bar/baz/ack"))
assert node.implicit[3] == [two, three]
assert node.implicit[4] == [three, four, one]
+ def test_scan(self):
+ """Test Scanner functionality"""
+ class DummyScanner:
+ pass
+ ds=DummyScanner()
+ node = SCons.Node.Node()
+ assert node.scanners == [], node.scanners
+ node.scanner_set(ds)
+ assert node.scanners == [ ds ], node.scanners
+ node.scan()
+ assert node.scanned[ds] == 1, node.scanned
+
def test_children(self):
"""Test fetching the "children" of a Node.
"""
self.implicit = {} # implicit (scanned) dependencies
self.parents = []
self.builder = None
- self.scanner = None
+ self.scanners = []
self.scanned = {}
self.env = None
self.state = None
return Adapter(self)
def scanner_set(self, scanner):
- self.scanner = scanner
+ if not scanner in self.scanners:
+ self.scanners.append(scanner)
def scan(self):
- self.scanned[self.scanner] = 1
+ for scn in self.scanners:
+ self.scanned[scn] = 1
def env_set(self, env, safe=0):
if safe and self.env:
dir = os.path.dirname(filename)
if dir:
- source_dir = (fs.Dir(dir),)
+ source_dir = (fs.Dir(dir, fs.Top),)
else:
- source_dir = ()
-
+ source_dir = ( fs.Top, )
return (SCons.Util.find_files(angle_includes, cpppath + source_dir,
fs.File)
+ SCons.Util.find_files(quote_includes, source_dir + cpppath,
dict = {}
dict[s1] = 777
assert dict[s2] == 777
-
+
class CScannerTestCase8(unittest.TestCase):
def runTest(self):
fs = SCons.Node.FS.FS(test.workpath(''))
deps_match(self, deps1, headers1)
deps_match(self, deps2, headers2)
+class CScannerTestCase9(unittest.TestCase):
+ def runTest(self):
+ fs = SCons.Node.FS.FS(test.workpath(''))
+ s = SCons.Scanner.C.CScan(fs=fs)
+ env = DummyEnvironment([])
+ test.write('fa.h','\n')
+ deps = s.instance(env).scan('fa.cpp', None)
+ deps_match(self, deps, [ 'fa.h' ])
+ test.unlink('fa.h')
+
+class CScannerTestCase10(unittest.TestCase):
+ def runTest(self):
+ fs = SCons.Node.FS.FS(test.workpath(''))
+ fs.chdir(fs.Dir('include'))
+ s = SCons.Scanner.C.CScan(fs=fs)
+ env = DummyEnvironment([])
+ test.write('include/fa.cpp', test.read('fa.cpp'))
+ deps = s.instance(env).scan('include/fa.cpp', None)
+ deps_match(self, deps, [ 'include/fa.h', 'include/fb.h' ])
+ test.unlink('include/fa.cpp')
+
def suite():
suite = unittest.TestSuite()
suite.addTest(CScannerTestCase1())
suite.addTest(CScannerTestCase6())
suite.addTest(CScannerTestCase7())
suite.addTest(CScannerTestCase8())
+ suite.addTest(CScannerTestCase9())
+ suite.addTest(CScannerTestCase10())
return suite
if __name__ == "__main__":