From 7e9ab4162cf3da6f95e5ed650dd27b081eeb4860 Mon Sep 17 00:00:00 2001 From: stevenknight Date: Tue, 11 Dec 2001 05:28:54 +0000 Subject: [PATCH] Create a specific CScanner subclass. git-svn-id: http://scons.tigris.org/svn/scons/trunk@140 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/engine/SCons/Scanner/C.py | 60 +++++++++++++++++++----------- src/engine/SCons/Scanner/CTests.py | 31 ++++++++++++--- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index 953d737a..5dbdf6f6 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 5f4e0b69..c16da610 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__": -- 2.26.2