Add an Rsearchall() method, and refactor the repository manipulation of CPPPATH to...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 20 Jul 2002 21:32:56 +0000 (21:32 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 20 Jul 2002 21:32:56 +0000 (21:32 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@419 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py

index da7c15ab22aa3de5567c7cc6964f60f051409864..fea60c3fdca0bb1f1e8bc97825f2d6efbc1cd62b 100644 (file)
@@ -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:
index 418d89166f6ac7f2b2a92f7bba7c2a4d996bebf5..eefb605b3f7a8d4581349122624fca6b25de5272 100644 (file)
@@ -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],
index 2645cea0725b1a3bb2b4eceabfe297a0f5d25dec..9a75f34c01f187a934b7fbb728ef1e1e6958e788 100644 (file)
@@ -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):
index 595396a6199d58cca3b354d966afa809621e035f..42a6542e1a4516b51b79a4737430bde1e85a3bfd 100644 (file)
@@ -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):