summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Scanner
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-12-16 14:22:29 (GMT)
committerSteven Knight <knight@baldmt.com>2004-12-16 14:22:29 (GMT)
commit64c24fdd205f1d3fe584990aaf6ae050bb46c431 (patch)
tree56224b472ce45750199e13b89473109b50ea3f9a /src/engine/SCons/Scanner
parent3869e426c19bd3b2e9bbb611b596220df9b34814 (diff)
downloadSCons-64c24fdd205f1d3fe584990aaf6ae050bb46c431.zip
SCons-64c24fdd205f1d3fe584990aaf6ae050bb46c431.tar.gz
SCons-64c24fdd205f1d3fe584990aaf6ae050bb46c431.tar.bz2
Cache get_suffix() and get_build_env(). (Kevin Quick)
Diffstat (limited to 'src/engine/SCons/Scanner')
-rw-r--r--src/engine/SCons/Scanner/ScannerTests.py27
-rw-r--r--src/engine/SCons/Scanner/__init__.py24
2 files changed, 39 insertions, 12 deletions
diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py
index 6520788..00ad7fb 100644
--- a/src/engine/SCons/Scanner/ScannerTests.py
+++ b/src/engine/SCons/Scanner/ScannerTests.py
@@ -399,10 +399,18 @@ class ClassicTestCase(unittest.TestCase):
env = DummyEnvironment()
s = MyScanner("t", ['.suf'], 'MYPATH', '^my_inc (\S+)')
+ # This set of tests is intended to test the scanning operation
+ # of the Classic scanner.
+
+ # Note that caching has been added for not just the includes
+ # but the entire scan call. The caching is based on the
+ # arguments, so we will fiddle with the path parameter to
+ # defeat this caching for the purposes of these tests.
+
# If the node doesn't exist, scanning turns up nothing.
n1 = MyNode("n1")
n1._exists = None
- ret = s.scan(n1, env)
+ ret = s.function(n1, env)
assert ret == [], ret
# Verify that it finds includes from the contents.
@@ -410,22 +418,27 @@ class ClassicTestCase(unittest.TestCase):
n._exists = 1
n._dir = MyNode("n._dir")
n._contents = 'my_inc abc\n'
- ret = s.scan(n, env)
+ ret = s.function(n, env, ('foo',))
assert ret == ['abc'], ret
# Verify that it uses the cached include info.
n._contents = 'my_inc def\n'
- ret = s.scan(n, env)
+ ret = s.function(n, env, ('foo2',))
assert ret == ['abc'], ret
# Verify that if we wipe the cache, it uses the new contents.
n.includes = None
- ret = s.scan(n, env)
+ ret = s.function(n, env, ('foo3',))
assert ret == ['def'], ret
+ # Verify that overall scan results are cached even if individual
+ # results are de-cached
+ ret = s.function(n, env, ('foo2',))
+ assert ret == ['abc'], ret
+
# Verify that it sorts what it finds.
n.includes = ['xyz', 'uvw']
- ret = s.scan(n, env)
+ ret = s.function(n, env, ('foo4',))
assert ret == ['uvw', 'xyz'], ret
# Verify that we use the rfile() node.
@@ -434,9 +447,11 @@ class ClassicTestCase(unittest.TestCase):
nr._dir = MyNode("nr._dir")
nr.includes = ['jkl', 'mno']
n._rfile = nr
- ret = s.scan(n, env)
+ ret = s.function(n, env, ('foo5',))
assert ret == ['jkl', 'mno'], ret
+
+
class ClassicCPPTestCase(unittest.TestCase):
def test_find_include(self):
"""Test the Scanner.ClassicCPP find_include() method"""
diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py
index e5ac2c6..cbab50c 100644
--- a/src/engine/SCons/Scanner/__init__.py
+++ b/src/engine/SCons/Scanner/__init__.py
@@ -296,8 +296,24 @@ class Classic(Current):
self.cre = re.compile(regex, re.M)
self.fs = fs
+ self._cached = {}
- kw['function'] = self.scan
+ def _scan(node, env, path=(), self=self):
+ node = node.rfile()
+
+ if not node.exists():
+ return []
+
+ key = str(id(node)) + '|' + string.join(map(str, path), ':')
+ try:
+ return self._cached[key]
+ except KeyError:
+ pass
+
+ self._cached[key] = scan_result = self.scan(node, path)
+ return scan_result
+
+ kw['function'] = _scan
kw['path_function'] = FindPathDirs(path_variable, fs)
kw['recursive'] = 1
kw['skeys'] = suffixes
@@ -314,11 +330,7 @@ class Classic(Current):
def sort_key(self, include):
return SCons.Node.FS._my_normcase(include)
- def scan(self, node, env, path=()):
- node = node.rfile()
-
- if not node.exists():
- return []
+ def scan(self, node, path=()):
# cache the includes list in node so we only scan it once:
if node.includes != None: