Commits

Anonymous committed b5ff52f

Add argument passing to the Scanner class

Comments (0)

Files changed (2)

src/scons/Scanner/ScannerTests.py

 
 class ScannerTestBase:
     
-    def func(self, filename, env):
+    def func(self, filename, env, *args):
         self.filename = filename
         self.env = env
+
+        if len(args) > 0:
+            self.arg = args[0]
+        
         return self.deps
 
-    def error_func(self, filename, env):
-        self.fail("the wrong function was called")
 
-    def test(self, scanner, env, filename, deps):
+    def test(self, scanner, env, filename, deps, *args):
         self.deps = deps
         deps = scanner.scan(filename, env)
 
         self.failUnless(self.env == env, "the environment was passed incorrectly")
         self.failUnless(self.deps == deps, "the dependencies were returned incorrectly")
 
+        if len(args) > 0:
+            self.failUnless(self.arg == args[0], "the argument was passed incorrectly")
+        else:
+            self.failIf(hasattr(self, "arg"), "an argument was given when it shouldn't have been")
+
 class DummyEnvironment:
     pass
 
     def runTest(self):
         s = scons.Scanner.Scanner(self.func)
         env = DummyEnvironment()
-        env.ARGUMENT = "arg1"
-        self.test(s, env, 'f1.cpp', ['f1.h', 'f2.h'])
+        env.VARIABLE = "var1"
+        self.test(s, env, 'f1.cpp', ['f1.h', 'f1.hpp'])
 
 class ScannerKeywordTestCase(ScannerTestBase, unittest.TestCase):
     "Test the Scanner class using the keyword argument"
     def runTest(self):
         s = scons.Scanner.Scanner(function = self.func)
         env = DummyEnvironment()
-        env.ARGUMENT = "arg1"
-        self.test(s, env, 'f1.cpp', ['f1.h', 'f2.h'])
+        env.VARIABLE = "var2"
+        self.test(s, env, 'f2.cpp', ['f2.h', 'f2.hpp'])
+
+class ScannerPositionalArgumentTestCase(ScannerTestBase, unittest.TestCase):
+    "Test the Scanner class using the position argument and optional argument"
+    def runTest(self):
+        arg = "this is the argument"
+        s = scons.Scanner.Scanner(self.func, arg)
+        env = DummyEnvironment()
+        env.VARIABLE = "var3"
+        self.test(s, env, 'f3.cpp', ['f3.h', 'f3.hpp'], arg)
+
+class ScannerKeywordArgumentTestCase(ScannerTestBase, unittest.TestCase):
+    "Test the Scanner class using the keyword argument and optional argument"
+    def runTest(self):
+        arg = "this is another argument"
+        s = scons.Scanner.Scanner(function = self.func, argument = arg)
+        env = DummyEnvironment()
+        env.VARIABLE = "var4"
+        self.test(s, env, 'f4.cpp', ['f4.h', 'f4.hpp'], arg)
 
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(ScannerPositionalTestCase())
     suite.addTest(ScannerKeywordTestCase())
+    suite.addTest(ScannerPositionalArgumentTestCase())
+    suite.addTest(ScannerKeywordArgumentTestCase())
     return suite
 
 if __name__ == "__main__":

src/scons/Scanner/__init__.py

 
 __version__ = "__VERSION__"
 
+class _Null:
+    pass
+
+# This is used instead of None as a default argument value so None can be
+# used as an actual argument value.
+_null = _Null
+
 class Scanner:
 
-    def __init__(self, function):
+    def __init__(self, function, argument=_null):
         """
         Construct a new scanner object given a scanner function.
 
-        The only argument to this method is a function taking two arguments
-        and returning a list of strings. The functions first argument will
-        be the name of a file that should be scanned for dependencies, the
-        second argument will be an Environment object and
-        the returned list of should contain the file names of all the
-        direct dependencies of this file.
+        'function' - a scanner function taking two or three arguments and
+        returning a list of strings.
+
+        'argument' - an optional argument that will be passed to the
+        scanner function if it is given.
+
+        The scanner function's first argument will be the name of a file
+        that should be scanned for dependencies, the second argument will
+        be an Environment object, the third argument will be the value
+        passed into 'argument', and the returned list should contain the
+        file names of all the direct dependencies of the file.
 
         Examples:
 
         
         s = Scanner(function = my_scanner_function)
 
+        s = Scanner(function = my_scanner_function, argument = 'foo')
+
         """
 
         # Note: this class could easily work with scanner functions that take
         # would need to be changed is the documentation.
 
         self.function = function
+        self.argument = argument
 
     def scan(self, filename, env):
         """
         environment that will be passed to the scanner function. A list of
         dependencies will be returned.
         """
-        
-        return self.function(filename, env)
+
+        if not self.argument is _null:
+            return self.function(filename, env, self.argument)
+        else:
+            return self.function(filename, env)