From 6cb454693e780e6b991a584329973a38b200ae2b Mon Sep 17 00:00:00 2001 From: stevenknight Date: Sat, 20 Jul 2002 21:32:56 +0000 Subject: [PATCH] Add an Rsearchall() method, and refactor the repository manipulation of CPPPATH to use it. git-svn-id: http://scons.tigris.org/svn/scons/trunk@419 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/engine/SCons/Environment.py | 18 ++------ src/engine/SCons/EnvironmentTests.py | 3 +- src/engine/SCons/Node/FS.py | 62 +++++++++++++++++++++------ src/engine/SCons/Node/FSTests.py | 63 ++++++++++++++++++++++++---- 4 files changed, 107 insertions(+), 39 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index da7c15ab..fea60c3f 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -489,21 +489,9 @@ class DirVarInterp(VarInterpolator): def prepareSrc(self, dict): src = VarInterpolator.prepareSrc(self, dict) - - def prepare(x, self=self): - if isinstance(x, SCons.Node.Node): - return [x] - elif str(x): - if os.path.isabs(str(x)): - return [self.fs.Dir(str(x), directory=self.dir)] - else: - return map(lambda d, s=str(x), fs=self.fs: - fs.Dir(s, directory=d), - [self.dir] + self.fs.Repositories) - else: - return [] - - return reduce(lambda x, y: x+y, map(prepare, src), []) + def path_dirs(path, fs = self.fs, dir = self.dir): + return fs.Dir(path, directory = dir) + return self.fs.Rsearchall(src, path_dirs) def instance(self, dir, fs): try: diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 418d8916..eefb605b 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -453,7 +453,7 @@ class EnvironmentTestCase(unittest.TestCase): assert dict['_LIBFLAGS'][2] == 'foobazbar', \ dict['_LIBFLAGS'][2] - blat = SCons.Node.FS.default_fs.File('blat') + blat = SCons.Node.FS.default_fs.Dir('blat') env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat ], INCPREFIX = 'foo ', @@ -507,7 +507,6 @@ class EnvironmentTestCase(unittest.TestCase): assert len(dict['_F77INCFLAGS']) == 0, dict['_F77INCFLAGS'] assert len(dict['_LIBDIRFLAGS']) == 0, dict['_LIBDIRFLAGS'] - blat = SCons.Node.FS.default_fs.File('blat') SCons.Node.FS.default_fs.Repository('/rep1') SCons.Node.FS.default_fs.Repository('/rep2') env = Environment(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat], diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 2645cea0..9a75f34c 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -83,6 +83,15 @@ else: def _my_normcase(x): return string.upper(x) + +def exists_path(path): + """Return a path if it's already a Node or it exists in the + real filesystem.""" + if os.path.exists(path): + return path + return None + + class FS: def __init__(self, path = None): """Initialize the Node.FS subsystem. @@ -302,14 +311,40 @@ class FS: for d in dirs: self.Repositories.append(self.Dir(d)) - def Rsearch(self, path, func = os.path.exists): - """Search for something in a repository.""" - for dir in self.Repositories: - t = os.path.join(dir.path, path) - if func(t): - return t + def Rsearch(self, path, func = exists_path): + """Search for something in a repository. Returns the first + one found in the list, or None if there isn't one.""" + if isinstance(path, SCons.Node.Node): + return path + else: + n = func(path) + if n: + return n + for dir in self.Repositories: + n = func(os.path.join(dir.path, path)) + if n: + return n return None + def Rsearchall(self, pathlist, func = exists_path): + """Search for a list of somethings in the repository list.""" + ret = [] + if SCons.Util.is_String(pathlist): + pathlist = string.split(pathlist, os.pathsep) + for path in pathlist: + if isinstance(path, SCons.Node.Node): + ret.append(path) + else: + n = func(path) + if n: + ret.append(n) + if not os.path.isabs(path): + for dir in self.Repositories: + n = func(os.path.join(dir.path, path)) + if n: + ret.append(n) + return ret + class Entry(SCons.Node.Node): """A generic class for file system entries. This class if for @@ -350,7 +385,6 @@ class Entry(SCons.Node.Node): self.__doSrcpath(self.duplicate) self.srcpath_ = self.srcpath self.cwd = None # will hold the SConscript directory for target nodes - self._rfile = None def get_dir(self): return self.dir @@ -437,7 +471,6 @@ class Dir(Entry): def __init__(self, name, directory): Entry.__init__(self, name, directory) self._morph() - self._rfile = None def _morph(self): """Turn a file system node (either a freshly initialized @@ -557,7 +590,6 @@ class Dir(Entry): # XXX TODO? # rfile # precious -# no_rfile # rpath # rsrcpath # source_exists @@ -671,12 +703,16 @@ class File(Entry): self.__createDir() def rfile(self): - if not self._rfile: + if not hasattr(self, '_rfile'): self._rfile = self if not os.path.isabs(self.path) and not os.path.isfile(self.path): - t = self.fs.Rsearch(self.path, os.path.isfile) - if t: - self._rfile = self.fs.File(t) + def file_node(path, fs = self.fs): + if os.path.isfile(path): + return fs.File(path) + return None + n = self.fs.Rsearch(self.path, file_node) + if n: + self._rfile = n return self._rfile def rstr(self): diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 595396a6..42a6542e 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -544,7 +544,10 @@ class RepositoryTestCase(unittest.TestCase): assert len(fs.Repositories) == 4, fs.Repositories r = map(lambda x, np=os.path.normpath: np(str(x)), fs.Repositories) - assert r == ['foo', 'foo/bar', 'bar/foo', 'bar'], r + assert r == ['foo', + os.path.join('foo', 'bar'), + os.path.join('bar', 'foo'), + 'bar'], r test = TestCmd(workdir = '') test.subdir('rep1', 'rep2', 'rep3', 'work') @@ -558,26 +561,68 @@ class RepositoryTestCase(unittest.TestCase): fs = SCons.Node.FS.FS() fs.Repository(rep1, rep2, rep3) - wf = fs.File(os.path.join('f1')) - assert wf.rfile() is wf + f1 = fs.File(os.path.join('f1')) + assert f1.rfile() is f1 test.write([rep1, 'f2'], "") - wf = fs.File('f2') - assert not wf.rfile() is wf, wf.rfile() - assert str(wf.rfile()) == os.path.join(rep1, 'f2'), str(wf.rfile()) + f2 = fs.File('f2') + assert not f2.rfile() is f2, f2.rfile() + assert str(f2.rfile()) == os.path.join(rep1, 'f2'), str(f2.rfile()) test.subdir([rep2, 'f3']) test.write([rep3, 'f3'], "") - wf = fs.File('f3') - assert not wf.rfile() is wf, wf.rfile() - assert wf.rstr() == os.path.join(rep3, 'f3'), wf.rstr() + f3 = fs.File('f3') + assert not f3.rfile() is f3, f3.rfile() + assert f3.rstr() == os.path.join(rep3, 'f3'), f3.rstr() + + assert fs.Rsearch('f1') is None + assert fs.Rsearch('f2') + assert fs.Rsearch(f3) is f3 assert not fs.Rsearch('f1', os.path.exists) assert fs.Rsearch('f2', os.path.exists) assert fs.Rsearch('f3', os.path.exists) + list = fs.Rsearchall([fs.Dir('d1')]) + assert len(list) == 1, list + assert list[0].path == 'd1', list[0].path + + list = fs.Rsearchall('d2') + assert list == [], list + + test.subdir(['work', 'd2']) + list = fs.Rsearchall('d2') + assert list == ['d2'], list + + test.subdir(['rep2', 'd2']) + list = fs.Rsearchall('d2') + assert list == ['d2', test.workpath('rep2', 'd2')], list + + test.subdir(['rep1', 'd2']) + list = fs.Rsearchall('d2') + assert list == ['d2', + test.workpath('rep1', 'd2'), + test.workpath('rep2', 'd2')], list + + list = fs.Rsearchall(['d3', 'd4']) + assert list == [], list + + test.subdir(['work', 'd3']) + list = fs.Rsearchall(['d3', 'd4']) + assert list == ['d3'], list + + test.subdir(['rep3', 'd4']) + list = fs.Rsearchall(['d3', 'd4']) + assert list == ['d3', test.workpath('rep3', 'd4')], list + + list = fs.Rsearchall(string.join(['d3', 'd4'], os.pathsep)) + assert list == ['d3', test.workpath('rep3', 'd4')], list + + work_d4 = fs.File(os.path.join('work', 'd4')) + list = fs.Rsearchall(['d3', work_d4]) + assert list == ['d3', work_d4], list class find_fileTestCase(unittest.TestCase): def runTest(self): -- 2.26.2