summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2001-12-11 05:28:54 (GMT)
committerSteven Knight <knight@baldmt.com>2001-12-11 05:28:54 (GMT)
commitd28daaf13a9b527df8a9f5ce2b04e077b776ef25 (patch)
treed7a12e4a69be2477e011e3644cceb5ed420a0969 /src/engine
parentae0bbc2d9e90c35913e217e1c0ceb3fb86b2b1ee (diff)
downloadSCons-d28daaf13a9b527df8a9f5ce2b04e077b776ef25.zip
SCons-d28daaf13a9b527df8a9f5ce2b04e077b776ef25.tar.gz
SCons-d28daaf13a9b527df8a9f5ce2b04e077b776ef25.tar.bz2
Create a specific CScanner subclass.
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/SCons/Scanner/C.py60
-rw-r--r--src/engine/SCons/Scanner/CTests.py31
2 files changed, 65 insertions, 26 deletions
diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py
index 953d737..5dbdf6f 100644
--- a/src/engine/SCons/Scanner/C.py
+++ b/src/engine/SCons/Scanner/C.py
@@ -30,22 +30,45 @@ This module implements the depenency scanner for C/C++ code.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import SCons.Scanner
-import re
+import copy
import os.path
+import re
+import SCons.Scanner
import SCons.Util
angle_re = re.compile('^[ \t]*#[ \t]*include[ \t]+<([\\w./\\\\]+)>', re.M)
quote_re = re.compile('^[ \t]*#[ \t]*include[ \t]+"([\\w./\\\\]+)"', re.M)
-def CScan():
+def CScan(fs = SCons.Node.FS.default_fs):
"Return a prototype Scanner instance for scanning C/C++ source files"
- return SCons.Scanner.Recursive(scan, "CScan",
- SCons.Node.FS.default_fs.File,
- [".c", ".C", ".cxx", ".cpp", ".c++",
- ".h", ".H", ".hxx", ".hpp"])
-
-def scan(filename, env, node_factory):
+ cs = CScanner(scan, "CScan", [fs, ()],
+ [".c", ".C", ".cxx", ".cpp", ".c++",
+ ".h", ".H", ".hxx", ".hpp"])
+ cs.fs = fs
+ return cs
+
+class CScanner(SCons.Scanner.Recursive):
+ def __init__(self, *args, **kw):
+ apply(SCons.Scanner.Recursive.__init__, (self,) + args, kw)
+ self.pathscanners = {}
+
+ def instance(self, env):
+ """
+ Return a unique instance of a C scanner object for a
+ given environment.
+ """
+ try:
+ dirs = tuple(SCons.Util.scons_str2nodes(env.Dictionary('CPPPATH'),
+ self.fs.Dir))
+ except:
+ dirs = ()
+ if not self.pathscanners.has_key(dirs):
+ clone = copy.copy(self)
+ clone.argument = [self.fs, dirs] # XXX reaching into object
+ self.pathscanners[dirs] = clone
+ return self.pathscanners[dirs]
+
+def scan(filename, env, args = [SCons.Node.FS.default_fs, ()]):
"""
scan(str, Environment) -> [str]
@@ -66,12 +89,7 @@ def scan(filename, env, node_factory):
dependencies.
"""
- fs = SCons.Node.FS.default_fs
- try:
- paths = map(lambda x, dir=fs.Dir: dir(x),
- env.Dictionary("CPPPATH"))
- except KeyError:
- paths = []
+ fs, cpppath = args
try:
file = open(filename)
@@ -83,13 +101,13 @@ def scan(filename, env, node_factory):
dir = os.path.dirname(filename)
if dir:
- source_dir = [fs.Dir(dir)]
+ source_dir = (fs.Dir(dir),)
else:
- source_dir = []
+ source_dir = ()
- return (SCons.Util.find_files(angle_includes, paths + source_dir,
- node_factory)
- + SCons.Util.find_files(quote_includes, source_dir + paths,
- node_factory))
+ return (SCons.Util.find_files(angle_includes, cpppath + source_dir,
+ fs.File)
+ + SCons.Util.find_files(quote_includes, source_dir + cpppath,
+ fs.File))
except (IOError, OSError):
return []
diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py
index 5f4e0b6..c16da61 100644
--- a/src/engine/SCons/Scanner/CTests.py
+++ b/src/engine/SCons/Scanner/CTests.py
@@ -27,10 +27,13 @@ import TestCmd
import SCons.Scanner.C
import unittest
import sys
+import os
import os.path
test = TestCmd.TestCmd(workdir = '')
+os.chdir(test.workpath(''))
+
# create some source files and headers:
test.write('f1.cpp',"""
@@ -122,7 +125,7 @@ class CScannerTestCase1(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([])
s = SCons.Scanner.C.CScan()
- deps = s.scan(test.workpath('f1.cpp'), env)
+ deps = s.instance(env).scan(test.workpath('f1.cpp'), env)
headers = ['f1.h', 'f2.h', 'fi.h']
deps_match(self, deps, headers)
@@ -130,7 +133,7 @@ class CScannerTestCase2(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.C.CScan()
- deps = s.scan(test.workpath('f1.cpp'), env)
+ deps = s.instance(env).scan(test.workpath('f1.cpp'), env)
headers = ['f1.h', 'd1/f2.h']
deps_match(self, deps, headers)
@@ -138,7 +141,7 @@ class CScannerTestCase3(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.C.CScan()
- deps = s.scan(test.workpath('f2.cpp'), env)
+ deps = s.instance(env).scan(test.workpath('f2.cpp'), env)
headers = ['f1.h', 'd1/f1.h', 'd1/d2/f1.h']
deps_match(self, deps, headers)
@@ -146,7 +149,7 @@ class CScannerTestCase4(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([test.workpath("d1"), test.workpath("d1/d2")])
s = SCons.Scanner.C.CScan()
- deps = s.scan(test.workpath('f2.cpp'), env)
+ deps = s.instance(env).scan(test.workpath('f2.cpp'), env)
headers = ['f1.h', 'd1/f1.h', 'd1/d2/f1.h', 'd1/d2/f4.h']
deps_match(self, deps, headers)
@@ -154,11 +157,28 @@ class CScannerTestCase5(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([])
s = SCons.Scanner.C.CScan()
- deps = s.scan(test.workpath('f3.cpp'), env)
+ deps = s.instance(env).scan(test.workpath('f3.cpp'), env)
headers = ['f1.h', 'f2.h', 'f3.h', 'fi.h', 'fj.h',
'd1/f1.h', 'd1/f2.h', 'd1/f3.h']
deps_match(self, deps, headers)
+class CScannerTestCase6(unittest.TestCase):
+ def runTest(self):
+ env1 = DummyEnvironment([test.workpath("d1")])
+ env2 = DummyEnvironment([test.workpath("d1/d2")])
+ s = SCons.Scanner.C.CScan()
+ s1 = s.instance(env1)
+ s2 = s.instance(env2)
+ s3 = s.instance(env1)
+ assert not s1 is s2
+ assert s1 is s3
+ deps1 = s1.scan(test.workpath('f1.cpp'), None)
+ deps2 = s2.scan(test.workpath('f1.cpp'), None)
+ headers1 = ['f1.h', 'd1/f2.h']
+ headers2 = ['f1.h', 'd1/d2/f2.h']
+ deps_match(self, deps1, headers1)
+ deps_match(self, deps2, headers2)
+
def suite():
suite = unittest.TestSuite()
suite.addTest(CScannerTestCase1())
@@ -166,6 +186,7 @@ def suite():
suite.addTest(CScannerTestCase3())
suite.addTest(CScannerTestCase4())
suite.addTest(CScannerTestCase5())
+ suite.addTest(CScannerTestCase6())
return suite
if __name__ == "__main__":