Turn the Prog Scanner into a prototype pattern that looks up LIBPATH Nodes (the way...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 16 Mar 2002 10:18:24 +0000 (10:18 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 16 Mar 2002 10:18:24 +0000 (10:18 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@296 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Scanner/Prog.py
src/engine/SCons/Scanner/ProgTests.py

index d8fb22c06faf170d9f2b2150176f1474e116bda6..87b0ce8c72c95db1764b46ef0550612b51e02b45 100644 (file)
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import SCons.Scanner
+import copy
+import string
+
 import SCons.Node.FS
+import SCons.Scanner
 import SCons.Util
-import string
 
-def ProgScan():
+class NullProgScanner:
+    """A do-nothing ProgScanner for Environments that have no LIBS."""
+    def scan(node, env, args = []):
+        return []
+
+null_scanner = NullProgScanner()
+
+def ProgScan(fs = SCons.Node.FS.default_fs):
     """Return a prototype Scanner instance for scanning executable
     files for static-lib dependencies"""
-    return SCons.Scanner.Base(scan, "ProgScan", SCons.Node.FS.default_fs.File)
+    ps = ProgScanner(scan, "ProgScan")
+    ps.fs = fs
+    return ps
 
-def scan(node, env, node_factory):
-    """
-    This scanner scans program files for static-library
-    dependencies.  It will search the LIBPATH environment variable
-    for libraries specified in the LIBS variable, returning any
-    files it finds as dependencies.
-    """
-
-    fs = SCons.Node.FS.default_fs
-    try:
-        paths = SCons.Util.scons_str2nodes(env.Dictionary("LIBPATH"),
-                                           fs.Dir)
-    except KeyError:
-        paths = []
+class ProgScanner(SCons.Scanner.Base):
+    def __init__(self, *args, **kw):
+        apply(SCons.Scanner.Base.__init__, (self,) + args, kw)
+        self.hash = None
+        self.pathscanners = {}
 
-    try:
-        libs = env.Dictionary("LIBS")
+    def instance(self, env):
+        """
+        Return a unique instance of a Prog scanner object for a
+        given environment.
+        """
+        try:
+            libs = env.Dictionary('LIBS')
+        except KeyError:
+            # There are no LIBS in this environment, so just return the
+            # fake "scanner" instance that always returns a null list.
+            return null_scanner
         if SCons.Util.is_String(libs):
             libs = string.split(libs)
-    except KeyError:
-        libs = []
 
-    try:
-        prefix = env.Dictionary("LIBPREFIX")
-    except KeyError:
-        prefix=''
+        try:
+            dirs = tuple(SCons.Util.scons_str2nodes(env.Dictionary('LIBPATH'),
+                                                    self.fs.Dir))
+        except:
+            dirs = ()
+
+        try:
+            prefix = env.Dictionary('LIBPREFIX')
+        except KeyError:
+            prefix = ''
 
-    try:
-        suffix = env.Dictionary("LIBSUFFIX")
-    except KeyError:
-        suffix=''
+        try:
+            suffix = env.Dictionary('LIBSUFFIX')
+        except KeyError:
+            suffix = ''
 
+        key = (dirs, tuple(libs), prefix, suffix)
+        if not self.pathscanners.has_key(key):
+            clone = copy.copy(self)
+            clone.hash = key
+            clone.argument = [self.fs, dirs, libs, prefix, suffix]    # XXX reaching into object
+            self.pathscanners[key] = clone
+        return self.pathscanners[key]
+
+    def __hash__(self):
+        return hash(self.hash)
+
+def scan(node, env, args = [SCons.Node.FS.default_fs, (), [], '', '']):
+    """
+    This scanner scans program files for static-library
+    dependencies.  It will search the LIBPATH environment variable
+    for libraries specified in the LIBS variable, returning any
+    files it finds as dependencies.
+    """
+    fs, libpath, libs, prefix, suffix = args
     libs = map(lambda x, s=suffix, p=prefix: p + x + s, libs)
-    return SCons.Node.FS.find_files(libs, paths, node_factory)
+    return SCons.Node.FS.find_files(libs, libpath, fs.File)
index 3f7983869904dc8a8287ebc20969babd2b9c1b39..b59e554c0cc9011ba215d66715fdcebad077f7ef 100644 (file)
@@ -70,7 +70,7 @@ class ProgScanTestCase1(unittest.TestCase):
         env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
                                LIBS=[ 'l1', 'l2', 'l3' ])
         s = SCons.Scanner.Prog.ProgScan()
-        deps = s.scan('dummy', env)
+        deps = s.instance(env).scan('dummy', env)
         assert deps_match(deps, ['l1.lib']), map(str, deps)
 
 class ProgScanTestCase2(unittest.TestCase):
@@ -79,7 +79,7 @@ class ProgScanTestCase2(unittest.TestCase):
                                            ["", "d1", "d1/d2" ]),
                                LIBS=[ 'l1', 'l2', 'l3' ])
         s = SCons.Scanner.Prog.ProgScan()
-        deps = s.scan('dummy', env)
+        deps = s.instance(env).scan('dummy', env)
         assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), map(str, deps)
 
 class ProgScanTestCase3(unittest.TestCase):
@@ -88,7 +88,7 @@ class ProgScanTestCase3(unittest.TestCase):
                                test.workpath("d1"),
                                LIBS='l2 l3')
         s = SCons.Scanner.Prog.ProgScan()
-        deps = s.scan('dummy', env)
+        deps = s.instance(env).scan('dummy', env)
         assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
 
 def suite():
@@ -104,7 +104,7 @@ def suite():
                                            test.workpath("d1"),
                                            LIBS=u'l2 l3')
                     s = SCons.Scanner.Prog.ProgScan()
-                    deps = s.scan('dummy', env)
+                    deps = s.instance(env).scan('dummy', env)
                     assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
             suite.addTest(ProgScanTestCase4())
             \n"""