From c6a5a383c8771988bc829ef90111afc4db03cc5f Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Wed, 3 Mar 2004 14:45:54 +0000 Subject: Refactor Scanner internals as a prelude to fixing use of '${TARGET.dir}' in *PATH variables. --- src/engine/SCons/Scanner/Prog.py | 12 ++-------- src/engine/SCons/Scanner/ScannerTests.py | 27 ++++++++++++++++++++--- src/engine/SCons/Scanner/__init__.py | 36 +++++++++++++++++++++--------- src/engine/SCons/Util.py | 38 -------------------------------- src/engine/SCons/UtilTests.py | 25 --------------------- 5 files changed, 52 insertions(+), 86 deletions(-) diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 5b3c935..0100b3d 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -33,18 +33,10 @@ import SCons.Util def ProgScan(fs = SCons.Node.FS.default_fs): """Return a prototype Scanner instance for scanning executable files for static-lib dependencies""" - ps = SCons.Scanner.Base(scan, "ProgScan", fs, path_function = path) + pf = SCons.Scanner.FindPathDirs('LIBPATH', fs) + ps = SCons.Scanner.Base(scan, "ProgScan", path_function = pf) return ps -def path(env, dir, fs = SCons.Node.FS.default_fs): - try: - libpath = env['LIBPATH'] - except KeyError: - return () - return tuple(fs.Rsearchall(SCons.Util.mapPaths(libpath, dir, env), - clazz = SCons.Node.FS.Dir, - must_exist = 0)) - def scan(node, env, libpath = (), fs = SCons.Node.FS.default_fs): """ This scanner scans program files for static-library diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py index 8c8744d..3d72bd2 100644 --- a/src/engine/SCons/Scanner/ScannerTests.py +++ b/src/engine/SCons/Scanner/ScannerTests.py @@ -23,12 +23,32 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import sys import unittest +import UserDict + import SCons.Scanner -import sys -class DummyEnvironment: - pass +class DummyEnvironment(UserDict.UserDict): + def __init__(self, dict=None, **kw): + UserDict.UserDict.__init__(self, dict) + self.data.update(kw) + def subst(self, strSubst): + return strSubst + +class FindPathDirsTestCase(unittest.TestCase): + def test_FindPathDirs(self): + """Test the FindPathDirs callable class""" + + class FS: + def Rsearchall(self, nodes, must_exist=0, clazz=None, cwd=dir): + return ['xxx'] + nodes + + env = DummyEnvironment(LIBPATH = [ 'foo' ]) + + fpd = SCons.Scanner.FindPathDirs('LIBPATH', FS()) + result = fpd(env, dir) + assert result == ('xxx', 'foo'), result class ScannerTestCase(unittest.TestCase): @@ -297,6 +317,7 @@ class ClassicCPPTestCase(unittest.TestCase): def suite(): suite = unittest.TestSuite() tclasses = [ + FindPathDirsTestCase, ScannerTestCase, CurrentTestCase, ClassicTestCase, diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py index 2146ebe..4bf8b6c 100644 --- a/src/engine/SCons/Scanner/__init__.py +++ b/src/engine/SCons/Scanner/__init__.py @@ -43,6 +43,31 @@ class _Null: # used as an actual argument value. _null = _Null +class FindPathDirs: + """A class to bind a specific *PATH variable name and the fs object + to a function that will return all of the *path directories.""" + def __init__(self, variable, fs): + self.variable = variable + self.fs = fs + def __call__(self, env, dir, argument=None): + try: + path = env[self.variable] + except KeyError: + return () + + if not SCons.Util.is_List(path): + path = [path] + r = [] + for p in path: + if SCons.Util.is_String(p): + p = env.subst(p) + r.append(p) + + return tuple(self.fs.Rsearchall(r, + must_exist = 0, + clazz = SCons.Node.FS.Dir, + cwd = dir)) + class Base: """ The base class for dependency scanners. This implements @@ -200,20 +225,11 @@ class Classic(Current): self.cre = re.compile(regex, re.M) self.fs = fs - def _path(env, dir, pv=path_variable, fs=fs): - try: - path = env[pv] - except KeyError: - return () - return tuple(fs.Rsearchall(SCons.Util.mapPaths(path, dir, env), - clazz = SCons.Node.FS.Dir, - must_exist = 0)) - def _scan(node, env, path, self=self, fs=fs): return self.scan(node, env, path) kw['function'] = _scan - kw['path_function'] = _path + kw['path_function'] = FindPathDirs(path_variable, fs) kw['recursive'] = 1 kw['skeys'] = suffixes diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index d189ecf..97ba8b5 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -879,44 +879,6 @@ def is_Dict(e): def is_List(e): return type(e) is types.ListType or isinstance(e, UserList.UserList) -def mapPaths(paths, dir, env=None): - """Takes a single node or string, or a list of nodes and/or - strings. We leave the nodes untouched, but we put the strings - under the supplied directory node dir, if they are not an absolute - path. - - For instance, the following: - - n = SCons.Node.FS.default_fs.File('foo') - mapPaths([ n, 'foo', '/bar' ], - SCons.Node.FS.default_fs.Dir('baz'), env) - - ...would return: - - [ n, 'baz/foo', '/bar' ] - - The env argument, if given, is used to perform variable - substitution on the source string(s). - """ - - def mapPathFunc(path, dir=dir, env=env): - if is_String(path): - if env: - path = env.subst(path) - if dir: - if not path: - return str(dir) - if os.path.isabs(path) or path[0] == '#': - return path - return str(dir) + os.sep + path - return path - - if not is_List(paths): - paths = [ paths ] - ret = map(mapPathFunc, paths) - return ret - - if hasattr(types, 'UnicodeType'): def is_String(e): return type(e) is types.StringType \ diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 8591119..c96f124 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -1132,31 +1132,6 @@ class UtilTestCase(unittest.TestCase): cmd_list = SCons.Util.escape_list(cmd_list[0], escape_func) assert cmd_list == ['BAZ', '**BLEH**'], cmd_list - def test_mapPaths(self): - """Test the mapPaths function""" - class MyFileNode: - def __init__(self, path): - self.path = path - def __str__(self): - return self.path - - dir=MyFileNode('foo') - file=MyFileNode('bar/file') - - class DummyEnv: - def subst(self, arg): - return 'bar' - - res = mapPaths([ file, 'baz', 'blat/boo', '#test' ], dir) - assert res[0] == file, res[0] - assert res[1] == os.path.join('foo', 'baz'), res[1] - assert res[2] == os.path.join('foo', 'blat/boo'), res[2] - assert res[3] == '#test', res[3] - - env=DummyEnv() - res=mapPaths('bleh', dir, env) - assert res[0] == os.path.normpath('foo/bar'), res[1] - def test_display(self): old_stdout = sys.stdout sys.stdout = OutBuffer() -- cgit v0.12