Support variable substitution on scanner directories. (Charles Crain)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 3 Dec 2002 14:42:35 +0000 (14:42 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 3 Dec 2002 14:42:35 +0000 (14:42 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@512 fdb21ef1-2011-0410-befe-b5e4ea1792b1

13 files changed:
src/CHANGES.txt
src/engine/SCons/Node/FS.py
src/engine/SCons/Scanner/C.py
src/engine/SCons/Scanner/CTests.py
src/engine/SCons/Scanner/Fortran.py
src/engine/SCons/Scanner/FortranTests.py
src/engine/SCons/Scanner/Prog.py
src/engine/SCons/Scanner/ProgTests.py
src/engine/SCons/Util.py
src/engine/SCons/UtilTests.py
test/CPPPATH.py
test/F77PATH.py
test/LIBPATH.py

index 586f81a2372209005bc64703548534f3f2bc8c2f..a2c6d36c06f79cd12d033876606c3acef3e69a2f 100644 (file)
@@ -15,6 +15,9 @@ RELEASE 0.09 -
   - Add a Prepend() method to Environments, to append values to
     the beginning of construction variables.
 
+  - Add support for construction variable substition on scanner
+    directories (in CPPPATH, F77PATH, LIBPATH, etc.).
+
  From Charles Crain and Steven Knight:
 
   - Add Repository() functionality, including the -Y option.
index b805d4a54a62dbc2de74e426d926dd785c7437a7..9976ef2533dfeb6403f2ceb6e01c1cea5e37a411 100644 (file)
@@ -362,7 +362,7 @@ class FS:
         then the same applies.
         """
         self.__setTopLevelDir()
-        if name[0] == '#':
+        if name and name[0] == '#':
             directory = self.Top
             name = name[1:]
             if name and (name[0] == os.sep or name[0] == '/'):
index 6eb03f4b56ff2e93f31de58a18a10542b934e7c8..6e7db584497a7dde6c30673f3c21dfbda3cd3abd 100644 (file)
@@ -80,7 +80,7 @@ def scan(node, env, target, fs = SCons.Node.FS.default_fs):
 
     if not hasattr(target, 'cpppath'):
         try:
-            target.cpppath = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['CPPPATH'], target.cwd), clazz=SCons.Node.FS.Dir, must_exist=0))
+            target.cpppath = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['CPPPATH'], target.cwd, env), clazz=SCons.Node.FS.Dir, must_exist=0))
         except KeyError:
             target.cpppath = ()
 
index be911d9e970f64bb33c56b1e32fb44914616fe0d..28a5f520fd0b9db4fd5e42d30ccb9f009fc23c21 100644 (file)
@@ -175,6 +175,9 @@ class DummyEnvironment:
         else:
             raise KeyError, "Dummy environment only has CPPPATH attribute."
 
+    def subst(self, arg):
+        return arg
+
     def __getitem__(self,key):
         return self.Dictionary()[key]
 
@@ -349,6 +352,17 @@ class CScannerTestCase12(unittest.TestCase):
         deps4 = s.scan(fs.File('build2/ccc.c'), env, DummyTarget())
         deps_match(self, deps4, [ test.workpath('repository/src/ddd.h') ])
         os.chdir(test.workpath(''))
+
+class CScannerTestCase13(unittest.TestCase):
+    def runTest(self):
+        class SubstEnvironment(DummyEnvironment):
+            def subst(self, arg, test=test):
+                return test.workpath("d1")
+        env = SubstEnvironment(["blah"])
+        s = SCons.Scanner.C.CScan()
+        deps = s.scan(make_node('f1.cpp'), env, DummyTarget())
+        headers = ['d1/f2.h', 'f1.h']
+        deps_match(self, deps, map(test.workpath, headers))
         
 
 def suite():
@@ -364,6 +378,7 @@ def suite():
     suite.addTest(CScannerTestCase10())
     suite.addTest(CScannerTestCase11())
     suite.addTest(CScannerTestCase12())
+    suite.addTest(CScannerTestCase13())
     return suite
 
 if __name__ == "__main__":
index afe46d09858060699239cd12883fc2a69f1bb793..5d908f71e5bbbfc892ce061e645d81206533acfe 100644 (file)
@@ -78,7 +78,7 @@ def scan(node, env, target, fs = SCons.Node.FS.default_fs):
 
     if not hasattr(target, 'f77path'):
         try:
-            target.f77path = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['F77PATH'], target.cwd), clazz=SCons.Node.FS.Dir, must_exist=0))
+            target.f77path = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['F77PATH'], target.cwd, env), clazz=SCons.Node.FS.Dir, must_exist=0))
         except KeyError:
             target.f77path = ()
 
index 3e3f7da66abad0e146ad6a595e1567dadfe1c78c..e2cfcd6da7854ed1f346129bedb0ee74e59bea37 100644 (file)
@@ -152,6 +152,9 @@ class DummyEnvironment:
     def __delitem__(self,key):
         del self.Dictionary()[key]
 
+    def subst(self, arg):
+        return arg
+
 def deps_match(self, deps, headers):
     scanned = map(os.path.normpath, map(str, deps))
     expect = map(os.path.normpath, headers)
@@ -354,6 +357,20 @@ class FortranScannerTestCase14(unittest.TestCase):
         deps_match(self, deps4, [ test.workpath('repository/src/ddd.f') ])
         os.chdir(test.workpath(''))
 
+class FortranScannerTestCase15(unittest.TestCase):
+    def runTest(self):
+        class SubstEnvironment(DummyEnvironment):
+            def subst(self, arg, test=test):
+                return test.workpath("d1")
+        test.write(['d1', 'f2.f'], "      INCLUDE 'fi.f'\n")
+        env = SubstEnvironment(["junk"])
+        s = SCons.Scanner.Fortran.FortranScan()
+       fs = SCons.Node.FS.FS(original)
+        deps = s.scan(make_node('fff1.f', fs), env, DummyTarget())
+        headers = ['d1/f1.f', 'd1/f2.f']
+        deps_match(self, deps, map(test.workpath, headers))
+        test.write(['d1', 'f2.f'], "\n")
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(FortranScannerTestCase1())
@@ -370,6 +387,7 @@ def suite():
     suite.addTest(FortranScannerTestCase12())
     suite.addTest(FortranScannerTestCase13())
     suite.addTest(FortranScannerTestCase14())
+    suite.addTest(FortranScannerTestCase15())
     return suite
 
 if __name__ == "__main__":
index 818aa865fac306bf498332be004534ab794de7ae..7cfd9f41ca605caf6b79e5e65a824597705f8527 100644 (file)
@@ -49,9 +49,8 @@ def scan(node, env, target, fs):
     # target.libpath - env['LIBPATH'] converted to nodes
 
     if not hasattr(target, 'libpath'):
-        def Dir(x, dir=target.cwd, fs=fs): return fs.Dir(x,dir)
         try:
-            target.libpath = tuple(SCons.Node.arg2nodes(env['LIBPATH'],Dir))
+            target.libpath = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['LIBPATH'], target.cwd, env), clazz=SCons.Node.FS.Dir, must_exist=0))
         except KeyError:
             target.libpath = ()
  
index 4e60ccfaa21ce9f7003569f4423c64c90b749882..1302e467e09fb8a40aa55e467851fab7a9ba02b9 100644 (file)
@@ -107,11 +107,26 @@ class ProgScanTestCase3(unittest.TestCase):
         deps = s.scan('dummy', env, DummyTarget())
         assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
 
+class ProgScanTestCase5(unittest.TestCase):
+    def runTest(self):
+        class SubstEnvironment(DummyEnvironment):
+            def subst(self, arg, path=test.workpath("d1")):
+                if arg == "blah":
+                    return test.workpath("d1")
+                else:
+                    return arg
+        env = SubstEnvironment(LIBPATH=[ "blah" ],
+                               LIBS=string.split('l2 l3'))
+        s = SCons.Scanner.Prog.ProgScan()
+        deps = s.scan('dummy', env, DummyTarget())
+        assert deps_match(deps, [ 'd1/l2.lib' ]), map(str, deps)
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(ProgScanTestCase1())
     suite.addTest(ProgScanTestCase2())
     suite.addTest(ProgScanTestCase3())
+    suite.addTest(ProgScanTestCase5())
     if hasattr(types, 'UnicodeType'):
         code = """if 1:
             class ProgScanTestCase4(unittest.TestCase):
index 62772ae150f8295ca2a57aaa8baf7015ee2966bc..17b288271ac732f620b9d22e23199e1770a2a535 100644 (file)
@@ -518,7 +518,7 @@ def Split(arg):
     else:
         return [arg]
 
-def mapPaths(paths, dir):
+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
@@ -528,27 +528,31 @@ def mapPaths(paths, dir):
 
     n = SCons.Node.FS.default_fs.File('foo')
     mapPaths([ n, 'foo', '/bar' ],
-             SCons.Node.FS.default_fs.Dir('baz'))
+             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):
-        if dir and is_String(path):
-            if not path:
-                return str(dir)
-            if os.path.isabs(path) or path[0] == '#':
-                return path
-            return dir.path_ + path
+    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 dir.path_ + path
         return path
 
     if not is_List(paths):
         paths = [ paths ]
     ret = map(mapPathFunc, paths)
-    if len(ret) == 1:
-        ret = ret[0]
     return ret
     
 
index e9662537a96f982c11a81cc1ab7cd88a2a6e9499..4b93d0f1150c7e394f964ebbc185e2f29c371dc2 100644 (file)
@@ -477,6 +477,27 @@ class UtilTestCase(unittest.TestCase):
         assert cmd_list[0] == 'BAZ', cmd_list[0]
         assert cmd_list[1] == '**$BAR**', cmd_list[1]
 
+    def test_mapPaths(self):
+        """Test the mapPaths function"""
+        fs = SCons.Node.FS.FS()
+        dir=fs.Dir('foo')
+        file=fs.File('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.normpath('foo/baz'), res[1]
+        assert res[2] == os.path.normpath('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]
+        
+
 if __name__ == "__main__":
     suite = unittest.makeSuite(UtilTestCase, 'test_')
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
index a2cae10bec747b8766723a6329e8f39ba5e5be58..4a50c67f496ef1ffd997fb43cbe531f110183369 100644 (file)
@@ -44,7 +44,8 @@ test = TestSCons.TestSCons()
 test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2')
 
 test.write('SConstruct', """
-env = Environment(CPPPATH = ['include'])
+env = Environment(CPPPATH = ['$FOO'],
+                  FOO='include')
 obj = env.Object(target='foobar/prog', source='subdir/prog.c')
 env.Program(target='prog', source=obj)
 SConscript('subdir/SConscript', "env")
index 3dcc2804b93ddaa458b521e14f9a24f02deddfe5..49aeb9a04c6bced637acd34f1912729642ff91df 100644 (file)
@@ -47,7 +47,7 @@ if not test.where_is('g77'):
 test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2')
 
 test.write('SConstruct', """
-env = Environment(F77PATH = ['include'], LIBS = 'g2c')
+env = Environment(F77PATH = ['$FOO'], LIBS = 'g2c', FOO='include')
 obj = env.Object(target='foobar/prog', source='subdir/prog.f')
 env.Program(target='prog', source=obj)
 SConscript('subdir/SConscript', "env")
index 51b29989b984df5f960d28a512c02b5698e2ff78..f122519b08ec44fc5767338db615293ca9aa956e 100644 (file)
@@ -47,7 +47,8 @@ prog2 = test.workpath(lib_ + 'shlib') + _dll
 
 test.write('SConstruct', """
 env1 = Environment(LIBS = [ 'foo1' ],
-                  LIBPATH = [ './lib1' ])
+                   LIBPATH = [ '$FOO' ],
+                   FOO='./lib1')
 
 f1 = env1.Object('f1', 'f1.c')