Create a specific CScanner subclass.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 11 Dec 2001 05:28:54 +0000 (05:28 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 11 Dec 2001 05:28:54 +0000 (05:28 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@140 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Scanner/C.py
src/engine/SCons/Scanner/CTests.py

index 953d737a0aa106c6262d0b8aaea27e84f71526cf..5dbdf6f63acecb8ef49f34db308ddf41299ca6c4 100644 (file)
@@ -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 []
index 5f4e0b69c6227fd16fc9fba4df5a5c30a28dc426..c16da610bd7994c1f709b84c663f598041f4b762 100644 (file)
@@ -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__":