Remove widespread reliance on SCons.Node.FS.default_fs so we can initialize it once...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 2 Apr 2005 19:50:33 +0000 (19:50 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 2 Apr 2005 19:50:33 +0000 (19:50 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1274 fdb21ef1-2011-0410-befe-b5e4ea1792b1

33 files changed:
src/engine/SCons/Builder.py
src/engine/SCons/BuilderTests.py
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Node/NodeTests.py
src/engine/SCons/Node/__init__.py
src/engine/SCons/SConf.py
src/engine/SCons/Scanner/C.py
src/engine/SCons/Scanner/CTests.py
src/engine/SCons/Scanner/D.py
src/engine/SCons/Scanner/Dir.py
src/engine/SCons/Scanner/DirTests.py
src/engine/SCons/Scanner/Fortran.py
src/engine/SCons/Scanner/FortranTests.py
src/engine/SCons/Scanner/IDL.py
src/engine/SCons/Scanner/IDLTests.py
src/engine/SCons/Scanner/Prog.py
src/engine/SCons/Scanner/ProgTests.py
src/engine/SCons/Scanner/ScannerTests.py
src/engine/SCons/Scanner/__init__.py
src/engine/SCons/Script/Main.py
src/engine/SCons/Script/SConscript.py
src/engine/SCons/Tool/Perforce.py
src/engine/SCons/Tool/jar.py
src/engine/SCons/Tool/javac.py
src/engine/SCons/Tool/javah.py
src/engine/SCons/Tool/msvs.py
src/engine/SCons/Tool/qt.py
src/engine/SCons/Tool/rmic.py
src/engine/SCons/Tool/tar.py
src/engine/SCons/Tool/zip.py

index 7069ef0b2627da6fb1878c8dc37ae143040315bd..ec78d895478c2b6e3a9406fe4db3d747543ae0ef 100644 (file)
@@ -342,7 +342,7 @@ def _init_nodes(builder, env, overrides, executor_kw, tlist, slist):
 
     # Now set up the relevant information in the target Nodes themselves.
     for t in tlist:
-        t.cwd = SCons.Node.FS.default_fs.getcwd()
+        t.cwd = env.fs.getcwd()
         t.builder_set(builder)
         t.env_set(env)
         t.add_source(slist)
@@ -390,8 +390,8 @@ class BuilderBase:
                         prefix = '',
                         suffix = '',
                         src_suffix = '',
-                        target_factory = SCons.Node.FS.default_fs.File,
-                        source_factory = SCons.Node.FS.default_fs.File,
+                        target_factory = None,
+                        source_factory = None,
                         target_scanner = None,
                         source_scanner = None,
                         emitter = None,
@@ -498,8 +498,11 @@ class BuilderBase:
 
         src_suf = self.get_src_suffix(env)
 
+        target_factory = env.get_factory(self.target_factory)
+        source_factory = env.get_factory(self.source_factory)
+
         source = _adjustixes(source, None, src_suf)
-        slist = env.arg2nodes(source, self.source_factory)
+        slist = env.arg2nodes(source, source_factory)
 
         pre = self.get_prefix(env, slist)
         suf = self.get_suffix(env, slist)
@@ -516,7 +519,7 @@ class BuilderBase:
                 tlist = [ t_from_s(pre, suf, splitext) ]
         else:
             target = _adjustixes(target, pre, suf)
-            tlist = env.arg2nodes(target, self.target_factory)
+            tlist = env.arg2nodes(target, target_factory)
 
         if self.emitter:
             # The emitter is going to do str(node), but because we're
@@ -543,8 +546,8 @@ class BuilderBase:
 
             # Have to call arg2nodes yet again, since it is legal for
             # emitters to spit out strings as well as Node instances.
-            slist = env.arg2nodes(source, self.source_factory)
-            tlist = env.arg2nodes(target, self.target_factory)
+            slist = env.arg2nodes(source, source_factory)
+            tlist = env.arg2nodes(target, target_factory)
 
         return tlist, slist
 
@@ -693,8 +696,8 @@ class MultiStepBuilder(BuilderBase):
                         prefix = '',
                         suffix = '',
                         src_suffix = '',
-                        target_factory = SCons.Node.FS.default_fs.File,
-                        source_factory = SCons.Node.FS.default_fs.File,
+                        target_factory = None,
+                        source_factory = None,
                         target_scanner = None,
                         source_scanner = None,
                         emitter=None,
@@ -723,7 +726,8 @@ class MultiStepBuilder(BuilderBase):
         
     def _execute(self, env, target, source, overwarn={}, executor_kw={}):
         # We now assume that target and source are lists or None.
-        slist = env.arg2nodes(source, self.source_factory)
+        source_factory = env.get_factory(self.source_factory)
+        slist = env.arg2nodes(source, source_factory)
         final_sources = []
 
         sdict = self._get_sdict(env)
index 09927f1c72d7ab74ac44f80b0a795a3034292320..fbf79f43b687c706deedfd170366cca94a637f2e 100644 (file)
@@ -55,6 +55,9 @@ test = TestCmd.TestCmd(workdir = '')
 outfile = test.workpath('outfile')
 outfile2 = test.workpath('outfile2')
 
+infile = test.workpath('infile')
+test.write(infile, "infile\n")
+
 show_string = None
 
 scons_env = SCons.Environment.Environment()
@@ -72,6 +75,7 @@ class Environment:
         global env_arg2nodes_called
         env_arg2nodes_called = None
         self.scanner = None
+        self.fs = SCons.Node.FS.FS()
     def subst(self, s):
         if not SCons.Util.is_String(s):
             return s
@@ -102,6 +106,8 @@ class Environment:
                 a = factory(a)
             list.append(a)
         return list
+    def get_factory(self, factory):
+        return factory or self.fs.File
     def get_scanner(self, ext):
         return self.scanner
     def Dictionary(self):
@@ -552,7 +558,7 @@ class BuilderTestCase(unittest.TestCase):
                                    suffix='.c')
         tgt = b8(env, target=None, source='foo_source.a')
         assert str(tgt[0]) == 'foo_obj.c', str(tgt[0])
-        src = SCons.Node.FS.default_fs.File('foo_source.a')
+        src = env.fs.File('foo_source.a')
         tgt = b8(env, target=None, source=src)
         assert str(tgt[0]) == 'foo_obj.c', str(tgt[0])
 
@@ -674,7 +680,7 @@ class BuilderTestCase(unittest.TestCase):
         tgts = builder(env, source=[])
         assert tgts == [], tgts
 
-        tgts = builder(env, target = [outfile, outfile2], source = 'foo')
+        tgts = builder(env, target = [outfile, outfile2], source = infile)
         for t in tgts:
             t.prepare()
         try:
@@ -698,7 +704,7 @@ class BuilderTestCase(unittest.TestCase):
             return 1
 
         builder = SCons.Builder.Builder(action = function3)
-        tgts = builder(env, target = [sub1_out, sub2_out], source = 'foo')
+        tgts = builder(env, target = [sub1_out, sub2_out], source = infile)
         for t in tgts:
             t.prepare()
         try:
index 77ce3c2915a46ebb711a0f7df6e918726d03e2ba..b813cf17eca16cdd8caaae5248f060e693fb7232 100644 (file)
@@ -94,7 +94,7 @@ def alias_builder(env, target, source):
 
 AliasBuilder = SCons.Builder.Builder(action = alias_builder,
                                      target_factory = SCons.Node.Alias.default_ans.Alias,
-                                     source_factory = SCons.Node.FS.default_fs.Entry,
+                                     source_factory = SCons.Node.FS.Entry,
                                      multi = 1,
                                      is_explicit = None,
                                      name='AliasBuilder')
@@ -250,7 +250,7 @@ class SubstitutionEnvironment:
         """Initialization of an underlying SubstitutionEnvironment class.
         """
         if __debug__: logInstanceCreation(self, 'Environment.SubstitutionEnvironment')
-        self.fs = SCons.Node.FS.default_fs
+        self.fs = SCons.Node.FS.default_fs or SCons.Node.FS.FS()
         self.ans = SCons.Node.Alias.default_ans
         self.lookup_list = SCons.Node.arg2nodes_lookups
         self._dict = kw.copy()
@@ -483,7 +483,7 @@ class Base(SubstitutionEnvironment):
         with the much simpler base class initialization.
         """
         if __debug__: logInstanceCreation(self, 'Environment.Base')
-        self.fs = SCons.Node.FS.default_fs
+        self.fs = SCons.Node.FS.default_fs or SCons.Node.FS.FS()
         self.ans = SCons.Node.Alias.default_ans
         self.lookup_list = SCons.Node.arg2nodes_lookups
         self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
@@ -529,6 +529,14 @@ class Base(SubstitutionEnvironment):
     # These begin with lower-case letters.
     #######################################################################
 
+    def get_builder(self, name):
+        """Fetch the builder with the specified name from the environment.
+        """
+        try:
+            return self._dict['BUILDERS'][name]
+        except KeyError:
+            return None
+
     def get_calculator(self):
         "__cacheable__"
         try:
@@ -541,13 +549,35 @@ class Base(SubstitutionEnvironment):
             c = SCons.Defaults.DefaultEnvironment().get_calculator()
         return c
 
-    def get_builder(self, name):
-        """Fetch the builder with the specified name from the environment.
+    def get_factory(self, factory, default='File'):
+        """Return a factory function for creating Nodes for this
+        construction environment.
+        __cacheable__
         """
+        name = default
         try:
-            return self._dict['BUILDERS'][name]
-        except KeyError:
-            return None
+            is_node = issubclass(factory, SCons.Node.Node)
+        except TypeError:
+            # The specified factory isn't a Node itself--it's
+            # most likely None, or possibly a callable.
+            pass
+        else:
+            if is_node:
+                # The specified factory is a Node (sub)class.  Try to
+                # return the FS method that corresponds to the Node's
+                # name--that is, we return self.fs.Dir if they want a Dir,
+                # self.fs.File for a File, etc.
+                try: name = factory.__name__
+                except AttributeError: pass
+                else: factory = None
+        if not factory:
+            # They passed us None, or we picked up a name from a specified
+            # class, so return the FS method.  (Note that we *don't*
+            # use our own self.{Dir,File} methods because that would
+            # cause env.subst() to be called twice on the file name,
+            # interfering with files that have $$ in them.)
+            factory = getattr(self.fs, name)
+        return factory
 
     def _gsm(self):
         "__cacheable__"
index a508529ab70cea1248ee4171a7c78fcc52682ece..6b4bc6001145002cd30f6daa41e86caaec7a408d 100644 (file)
@@ -794,128 +794,81 @@ class BaseTestCase(unittest.TestCase):
     def test_autogenerate(dict):
         """Test autogenerating variables in a dictionary."""
 
-        def RDirs(pathlist):
-            return SCons.Node.FS.default_fs.Rsearchall(pathlist,
-                                                       clazz=SCons.Node.FS.Dir,
-                                                       must_exist=0,
-                                                       cwd=SCons.Node.FS.default_fs.Dir('xx'))
-
         env = Environment(LIBS = [ 'foo', 'bar', 'baz' ],
                           LIBLINKPREFIX = 'foo',
-                          LIBLINKSUFFIX = 'bar',
-                          RDirs=RDirs)
+                          LIBLINKSUFFIX = 'bar')
+
+        def RDirs(pathlist, fs=env.fs):
+            return fs.Rsearchall(pathlist,
+                                 clazz=SCons.Node.FS.Dir,
+                                 must_exist=0,
+                                 cwd=fs.Dir('xx'))
+
+        env['RDirs'] = RDirs
         flags = env.subst_list('$_LIBFLAGS', 1)[0]
-        assert len(flags) == 3, flags
-        assert flags[0] == 'foobar', \
-               flags[0]
-        assert flags[1] == 'foobar', \
-               flags[1]
-        assert flags[2] == 'foobazbar', \
-               flags[2]
-
-        blat = SCons.Node.FS.default_fs.Dir('blat')
-
-        env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat ],
-                          INCPREFIX = 'foo ',
-                          INCSUFFIX = 'bar',
-                          FOO = 'baz',
-                          RDirs=RDirs)
+        assert flags == ['foobar', 'foobar', 'foobazbar'], flags
+
+        blat = env.fs.Dir('blat')
+
+        env.Replace(CPPPATH = [ 'foo', '$FOO/bar', blat ],
+                    INCPREFIX = 'foo ',
+                    INCSUFFIX = 'bar',
+                    FOO = 'baz')
         flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
-        assert len(flags) == 8, flags
-        assert flags[0] == '$(', \
-               flags[0]
-        assert flags[1] == os.path.normpath('foo'), \
-               flags[1]
-        assert flags[2] == os.path.normpath('xx/foobar'), \
-               flags[2]
-        assert flags[3] == os.path.normpath('foo'), \
-               flags[3]
-        assert flags[4] == os.path.normpath('xx/baz/bar'), \
-               flags[4]
-        assert flags[5] == os.path.normpath('foo'), \
-               flags[5]
-        assert flags[6] == os.path.normpath('blatbar'), \
-               flags[6]
-        assert flags[7] == '$)', \
-               flags[7]
-
-        env = Environment(F77PATH = [ 'foo', '$FOO/bar', blat ],
-                          INCPREFIX = 'foo ',
-                          INCSUFFIX = 'bar',
-                          FOO = 'baz',
-                          RDirs=RDirs)
+        expect = [ '$(',
+                   os.path.normpath('foo'),
+                   os.path.normpath('xx/foobar'),
+                   os.path.normpath('foo'),
+                   os.path.normpath('xx/baz/bar'),
+                   os.path.normpath('foo'),
+                   os.path.normpath('blatbar'),
+                   '$)',
+        ]
+        assert flags == expect, flags
+
+        env.Replace(F77PATH = [ 'foo', '$FOO/bar', blat ],
+                    INCPREFIX = 'foo ',
+                    INCSUFFIX = 'bar',
+                    FOO = 'baz')
         flags = env.subst_list('$_F77INCFLAGS', 1)[0]
-        assert len(flags) == 8, flags
-        assert flags[0] == '$(', \
-               flags[0]
-        assert flags[1] == os.path.normpath('foo'), \
-               flags[1]
-        assert flags[2] == os.path.normpath('xx/foobar'), \
-               flags[2]
-        assert flags[3] == os.path.normpath('foo'), \
-               flags[3]
-        assert flags[4] == os.path.normpath('xx/baz/bar'), \
-               flags[4]
-        assert flags[5] == os.path.normpath('foo'), \
-               flags[5]
-        assert flags[6] == os.path.normpath('blatbar'), \
-               flags[6]
-        assert flags[7] == '$)', \
-               flags[7]
-
-        env = Environment(CPPPATH = '', F77PATH = '', LIBPATH = '',
-                          RDirs=RDirs)
+        expect = [ '$(',
+                   os.path.normpath('foo'),
+                   os.path.normpath('xx/foobar'),
+                   os.path.normpath('foo'),
+                   os.path.normpath('xx/baz/bar'),
+                   os.path.normpath('foo'),
+                   os.path.normpath('blatbar'),
+                   '$)',
+        ]
+        assert flags == expect, flags
+
+        env.Replace(CPPPATH = '', F77PATH = '', LIBPATH = '')
         l = env.subst_list('$_CPPINCFLAGS')
-        assert len(l[0]) == 0, l[0]
+        assert l == [[]], l
         l = env.subst_list('$_F77INCFLAGS')
-        assert len(l[0]) == 0, l[0]
+        assert l == [[]], l
         l = env.subst_list('$_LIBDIRFLAGS')
-        assert len(l[0]) == 0, l[0]
-
-        SCons.Node.FS.default_fs.Repository('/rep1')
-        SCons.Node.FS.default_fs.Repository('/rep2')
-        env = Environment(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
-                          INCPREFIX = '-I ',
-                          INCSUFFIX = 'XXX',
-                          FOO = 'baz',
-                          RDirs=RDirs)
+        assert l == [[]], l
+
+        env.fs.Repository('/rep1')
+        env.fs.Repository('/rep2')
+        env.Replace(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
+                    INCPREFIX = '-I ',
+                    INCSUFFIX = 'XXX',
+                    FOO = 'baz')
         flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
-        assert flags[0] == '$(', \
-               flags[0]
-        assert flags[1] == '-I', \
-               flags[1]
-        assert flags[2] == os.path.normpath('xx/fooXXX'), \
-               flags[2]
-        assert flags[3] == '-I', \
-               flags[3]
-        assert flags[4] == os.path.normpath('/rep1/xx/fooXXX'), \
-               flags[4]
-        assert flags[5] == '-I', \
-               flags[5]
-        assert flags[6] == os.path.normpath('/rep2/xx/fooXXX'), \
-               flags[6]
-        assert flags[7] == '-I', \
-               flags[7]
-        assert flags[8] == os.path.normpath('/a/bXXX'), \
-               flags[8]
-        assert flags[9] == '-I', \
-               flags[9]
-        assert flags[10] == os.path.normpath('xx/baz/barXXX'), \
-               flags[10]
-        assert flags[11] == '-I', \
-               flags[11]
-        assert flags[12] == os.path.normpath('/rep1/xx/baz/barXXX'), \
-               flags[12]
-        assert flags[13] == '-I', \
-               flags[13]
-        assert flags[14] == os.path.normpath('/rep2/xx/baz/barXXX'), \
-               flags[14]
-        assert flags[15] == '-I', \
-               flags[15]
-        assert flags[16] == os.path.normpath('blatXXX'), \
-               flags[16]
-        assert flags[17] == '$)', \
-               flags[17]
+        expect = [ '$(',
+                   '-I', os.path.normpath('xx/fooXXX'),
+                   '-I', os.path.normpath('/rep1/xx/fooXXX'),
+                   '-I', os.path.normpath('/rep2/xx/fooXXX'),
+                   '-I', os.path.normpath('/a/bXXX'),
+                   '-I', os.path.normpath('xx/baz/barXXX'),
+                   '-I', os.path.normpath('/rep1/xx/baz/barXXX'),
+                   '-I', os.path.normpath('/rep2/xx/baz/barXXX'),
+                   '-I', os.path.normpath('blatXXX'),
+                   '$)'
+        ]
+        assert flags == expect, flags
 
     def test_platform(self):
         """Test specifying a platform callable when instantiating."""
@@ -2189,7 +2142,7 @@ def generate(env):
         assert 'foo1.in' in map(lambda x: x.path, t.sources)
         assert 'foo2.in' in map(lambda x: x.path, t.sources)
 
-        sub = SCons.Node.FS.default_fs.Dir('sub')
+        sub = env.fs.Dir('sub')
         t = env.Command(target='bar.out', source='sub',
                         action='buildbar $target $source')[0]
         assert 'sub' in map(lambda x: x.path, t.sources)
index fe014f82a7fc3d7ad7805ff0a72bc515a39728a7..90bc70ad2a7057c3ee8599200ac5ed6d99eaa807 100644 (file)
@@ -5,9 +5,8 @@ File system nodes.
 These Nodes represent the canonical external objects that people think
 of when they think of building software: files and directories.
 
-This initializes a "default_fs" Node with an FS at the current directory
-for its own purposes, and for use by scripts or modules looking for the
-canonical default.
+This holds a "default_fs" variable that should be initialized with an FS
+that can be used by scripts or modules looking for the canonical default.
 
 """
 
@@ -759,20 +758,20 @@ class FS(LocalFS):
         The path argument must be a valid absolute path.
         """
         if __debug__: logInstanceCreation(self, 'Node.FS')
-        self.Top = None
-        if path == None:
-            self.pathTop = os.getcwd()
-        else:
-            self.pathTop = path
         self.Root = {}
         self.SConstruct_dir = None
         self.CachePath = None
         self.cache_force = None
         self.cache_show = None
 
-    def set_toplevel_dir(self, path):
-        assert not self.Top, "You can only set the top-level path on an FS object that has not had its File, Dir, or Entry methods called yet."
-        self.pathTop = path
+        if path is None:
+            self.pathTop = os.getcwd()
+        else:
+            self.pathTop = path
+
+        self.Top = self._doLookup(Dir, os.path.normpath(self.pathTop))
+        self.Top.path = '.'
+        self._cwd = self.Top
 
     def clear_cache(self):
         "__cache_reset__"
@@ -780,15 +779,8 @@ class FS(LocalFS):
     
     def set_SConstruct_dir(self, dir):
         self.SConstruct_dir = dir
-        
-    def __setTopLevelDir(self):
-        if not self.Top:
-            self.Top = self._doLookup(Dir, os.path.normpath(self.pathTop))
-            self.Top.path = '.'
-            self._cwd = self.Top
-        
+
     def getcwd(self):
-        self.__setTopLevelDir()
         return self._cwd
 
     def __checkClass(self, node, klass):
@@ -912,7 +904,6 @@ class FS(LocalFS):
         If directory is None, and name is a relative path,
         then the same applies.
         """
-        self.__setTopLevelDir()
         if name and name[0] == '#':
             directory = self.Top
             name = name[1:]
@@ -930,7 +921,6 @@ class FS(LocalFS):
         If change_os_dir is true, we will also change the "real" cwd
         to match.
         """
-        self.__setTopLevelDir()
         curr=self._cwd
         try:
             if not dir is None:
@@ -990,7 +980,6 @@ class FS(LocalFS):
         """Link the supplied build directory to the source directory
         for purposes of building files."""
         
-        self.__setTopLevelDir()
         if not isinstance(src_dir, SCons.Node.Node):
             src_dir = self.Dir(src_dir)
         if not isinstance(build_dir, SCons.Node.Node):
@@ -1010,7 +999,6 @@ class FS(LocalFS):
         for d in dirs:
             if not isinstance(d, SCons.Node.Node):
                 d = self.Dir(d)
-            self.__setTopLevelDir()
             self.Top.addRepository(d)
 
     def do_Rsearch(self, path, dir, func, clazz=_classEntry):
@@ -1150,7 +1138,6 @@ class FS(LocalFS):
             message = fmt % string.join(map(str, targets))
         return targets, message
 
-
 class Dir(Base):
     """A class for directories in a file system.
     """
@@ -1914,7 +1901,7 @@ class File(Base):
         File, this is a TypeError..."""
         raise TypeError, "Tried to lookup File '%s' as a Dir." % self.path
 
-default_fs = FS()
+default_fs = None
 
 def find_file(filename, paths, verbose=None):
     """
index 94e9790f22c4e845845f87f3774fa6ee79e4bd62..e2c787ec8c2db0d497ea89ed22f3df8bd3bd53e2 100644 (file)
@@ -972,7 +972,7 @@ class FSTestCase(_tempdirTestCase):
         # the reading of files in text mode.  This tests that
         # get_contents() returns the binary contents.
         test.write("binary_file", "Foo\x1aBar")
-        f1 = SCons.Node.FS.default_fs.File(test.workpath("binary_file"))
+        f1 = fs.File(test.workpath("binary_file"))
         assert f1.get_contents() == "Foo\x1aBar", f1.get_contents()
 
         def nonexistent(method, s):
index 5f03377ea9ad2e207cc4f252e11800f4bcbc2c2d..67ac05f673afef218b0543053eef1a02b98b5cc5 100644 (file)
@@ -141,6 +141,8 @@ class Environment:
         self._dict.update(dict)
     def get_calculator(self):
         return SCons.Sig.default_calc
+    def get_factory(self, factory):
+        return factory or MyNode
     def get_scanner(self, scanner_key):
         return self._dict['SCANNERS'][0]
 
index db80985d5ed921f1cb77a3ac61a7491960ec0493..bc10e21744a5667d9d83491a662bb2093371f1d2 100644 (file)
@@ -424,7 +424,8 @@ class Node:
         here is a significant performance boost.
         __cacheable__
         """
-        return self.builder.source_factory(path)
+        env = self.get_build_env()
+        return env.get_factory(self.builder.source_factory)(path)
 
     def get_scanner(self, env, kw={}):
         return env.get_scanner(self.scanner_key())
index 7bd9c1a40a5783ba811482e67994a9de1e2febba..b89ca4aed6f73766c5f975b1f79486df6896ffaf 100644 (file)
@@ -76,7 +76,7 @@ def SetProgressDisplay(display):
     global progress_display
     progress_display = display
 
-SConfFS=SCons.Node.FS.default_fs
+SConfFS = None
 
 _ac_build_counter = 0 # incremented, whenever TryBuild is called
 _ac_config_logs = {}  # all config.log files created in this build
@@ -338,7 +338,8 @@ class SConf:
         """
         global SConfFS
         if not SConfFS:
-            SConfFS = SCons.Node.FS.FS(SCons.Node.FS.default_fs.pathTop)
+            SConfFS = SCons.Node.FS.default_fs or \
+                      SCons.Node.FS.FS(env.fs.pathTop)
         if not sconf_global is None:
             raise (SCons.Errors.UserError,
                    "Only one SConf object may be active at one time")
index 62a6842e710f4120ad57f1cf25b5f7fb6e546e8c..276570e010e69e5c726a697d7c167d183a4970c6 100644 (file)
@@ -32,12 +32,11 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import SCons.Node.FS
 import SCons.Scanner
 
-def CScanner(fs = SCons.Node.FS.default_fs):
+def CScanner():
     """Return a prototype Scanner instance for scanning source files
     that use the C pre-processor"""
     cs = SCons.Scanner.ClassicCPP("CScanner",
                                   "$CPPSUFFIXES",
                                   "CPPPATH",
-                                  '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")',
-                                  fs = fs)
+                                  '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
     return cs
index fd17ee1e755c8604ebcc0de7e75c1d7a18629371..138b78838ee0ddc4ea91a6af37c3ab266961aaf7 100644 (file)
@@ -174,6 +174,7 @@ class DummyEnvironment(UserDict.UserDict):
     def __init__(self, **kw):
         UserDict.UserDict.__init__(self)
         self.data.update(kw)
+        self.fs = SCons.Node.FS.FS(test.workpath(''))
 
     def Dictionary(self, *args):
         return self.data
@@ -196,6 +197,15 @@ class DummyEnvironment(UserDict.UserDict):
     def get_calculator(self):
         return None
 
+    def get_factory(self, factory):
+        return factory or self.fs.File
+
+    def Dir(self, filename):
+        return self.fs.Dir(test.workpath(filename))
+
+    def File(self, filename):
+        return self.fs.File(test.workpath(filename))
+
 if os.path.normcase('foo') == os.path.normcase('FOO'):
     my_normpath = os.path.normcase
 else:
@@ -207,9 +217,6 @@ def deps_match(self, deps, headers):
     expect = map(my_normpath, headers)
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
-def make_node(filename, fs=SCons.Node.FS.default_fs):
-    return fs.File(test.workpath(filename))
-
 # define some tests:
 
 class CScannerTestCase1(unittest.TestCase):
@@ -217,36 +224,36 @@ class CScannerTestCase1(unittest.TestCase):
         env = DummyEnvironment(CPPPATH=[])
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps = s(make_node('f1.cpp'), env, path)
+        deps = s(env.File('f1.cpp'), env, path)
         headers = ['f1.h', 'f2.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class CScannerTestCase2(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment(CPPPATH=[test.workpath("d1")])
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps = s(make_node('f1.cpp'), env, path)
+        deps = s(env.File('f1.cpp'), env, path)
         headers = ['f1.h', 'd1/f2.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class CScannerTestCase3(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment(CPPPATH=[test.workpath("d1")])
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps = s(make_node('f2.cpp'), env, path)
+        deps = s(env.File('f2.cpp'), env, path)
         headers = ['d1/f1.h', 'f1.h', 'd1/d2/f1.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class CScannerTestCase4(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")])
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps = s(make_node('f2.cpp'), env, path)
+        deps = s(env.File('f2.cpp'), env, path)
         headers =  ['d1/f1.h', 'f1.h', 'd1/d2/f1.h', 'd1/d2/f4.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         
 class CScannerTestCase5(unittest.TestCase):
     def runTest(self):
@@ -254,7 +261,7 @@ class CScannerTestCase5(unittest.TestCase):
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
 
-        n = make_node('f3.cpp')
+        n = env.File('f3.cpp')
         def my_rexists(s=n):
             s.rexists_called = 1
             return s.old_rexists()
@@ -269,7 +276,7 @@ class CScannerTestCase5(unittest.TestCase):
         
         headers =  ['f1.h', 'f2.h', 'f3-test.h',
                     'd1/f1.h', 'd1/f2.h', 'd1/f3-test.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class CScannerTestCase6(unittest.TestCase):
     def runTest(self):
@@ -278,25 +285,24 @@ class CScannerTestCase6(unittest.TestCase):
         s = SCons.Scanner.C.CScanner()
         path1 = s.path(env1)
         path2 = s.path(env2)
-        deps1 = s(make_node('f1.cpp'), env1, path1)
-        deps2 = s(make_node('f1.cpp'), env2, path2)
+        deps1 = s(env1.File('f1.cpp'), env1, path1)
+        deps2 = s(env2.File('f1.cpp'), env2, path2)
         headers1 =  ['f1.h', 'd1/f2.h']
         headers2 =  ['f1.h', 'd1/d2/f2.h']
-        deps_match(self, deps1, map(test.workpath, headers1))
-        deps_match(self, deps2, map(test.workpath, headers2))
+        deps_match(self, deps1, headers1)
+        deps_match(self, deps2, headers2)
 
 class CScannerTestCase8(unittest.TestCase):
     def runTest(self):
-        fs = SCons.Node.FS.FS(test.workpath(''))
         env = DummyEnvironment(CPPPATH=["include"])
-        s = SCons.Scanner.C.CScanner(fs = fs)
+        s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps1 = s(fs.File('fa.cpp'), env, path)
-        fs.chdir(fs.Dir('subdir'))
-        dir = fs.getcwd()
-        fs.chdir(fs.Dir('..'))
+        deps1 = s(env.File('fa.cpp'), env, path)
+        env.fs.chdir(env.Dir('subdir'))
+        dir = env.fs.getcwd()
+        env.fs.chdir(env.Dir(''))
         path = s.path(env, dir)
-        deps2 = s(fs.File('#fa.cpp'), env, path)
+        deps2 = s(env.File('#fa.cpp'), env, path)
         headers1 =  ['include/fa.h', 'include/fb.h']
         headers2 =  ['subdir/include/fa.h', 'subdir/include/fb.h']
         deps_match(self, deps1, headers1)
@@ -315,7 +321,8 @@ class CScannerTestCase9(unittest.TestCase):
         test.write('fa.h','\n')
         fs = SCons.Node.FS.FS(test.workpath(''))
         env = DummyEnvironment(CPPPATH=[])
-        s = SCons.Scanner.C.CScanner(fs=fs)
+        env.fs = fs
+        s = SCons.Scanner.C.CScanner()
         path = s.path(env)
         deps = s(fs.File('fa.cpp'), env, path)
 
@@ -330,7 +337,8 @@ class CScannerTestCase10(unittest.TestCase):
         fs = SCons.Node.FS.FS(test.workpath(''))
         fs.chdir(fs.Dir('include'))
         env = DummyEnvironment(CPPPATH=[])
-        s = SCons.Scanner.C.CScanner(fs=fs)
+        env.fs = fs
+        s = SCons.Scanner.C.CScanner()
         path = s.path(env)
         test.write('include/fa.cpp', test.read('fa.cpp'))
         fs.chdir(fs.Dir('..'))
@@ -349,10 +357,12 @@ class CScannerTestCase11(unittest.TestCase):
         f1=fs.File('include2/jjj.h')
         f1.builder=1
         env = DummyEnvironment(CPPPATH=['include', 'include2'])
-        s = SCons.Scanner.C.CScanner(fs=fs)
+        env.fs = fs
+        s = SCons.Scanner.C.CScanner()
         path = s.path(env)
         deps = s(fs.File('src/fff.c'), env, path)
-        deps_match(self, deps, [ test.workpath('repository/include/iii.h'), 'include2/jjj.h' ])
+        deps_match(self, deps, [ test.workpath('repository/include/iii.h'),
+                                 'include2/jjj.h' ])
         os.chdir(test.workpath(''))
 
 class CScannerTestCase12(unittest.TestCase):
@@ -363,7 +373,8 @@ class CScannerTestCase12(unittest.TestCase):
         fs.BuildDir('build2', 'src', 0)
         fs.Repository(test.workpath('repository'))
         env = DummyEnvironment(CPPPATH=[])
-        s = SCons.Scanner.C.CScanner(fs = fs)
+        env.fs = fs
+        s = SCons.Scanner.C.CScanner()
         path = s.path(env)
         deps1 = s(fs.File('build1/aaa.c'), env, path)
         deps_match(self, deps1, [ 'build1/bbb.h' ])
@@ -383,18 +394,18 @@ class CScannerTestCase13(unittest.TestCase):
         env = SubstEnvironment(CPPPATH=["blah"])
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps = s(make_node('f1.cpp'), env, path)
+        deps = s(env.File('f1.cpp'), env, path)
         headers = ['f1.h', 'd1/f2.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class CScannerTestCase14(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment(CPPPATH=[])
         s = SCons.Scanner.C.CScanner()
         path = s.path(env)
-        deps = s(make_node('f5.c'), env, path)
+        deps = s(env.File('f5.c'), env, path)
         headers = ['f5a.h', 'f5b.h']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class CScannerTestCase15(unittest.TestCase):
     def runTest(self):
index cd93a6908086dad26cdb9136e561a13c4c1a5f66..2ea261449d03e78b18ee403016a26e345090ba6e 100644 (file)
@@ -36,13 +36,12 @@ import string
 
 import SCons.Scanner
 
-def DScanner(fs = SCons.Node.FS.default_fs):
+def DScanner():
     """Return a prototype Scanner instance for scanning D source files"""
     ds = D(name = "DScanner",
            suffixes = '$DSUFFIXES',
            path_variable = 'DPATH',
-           regex = 'import\s+([^\;]*)\;',
-           fs = fs)
+           regex = 'import\s+([^\;]*)\;')
     return ds
 
 class D(SCons.Scanner.Classic):
index 616105952ab4a495edce31b0cf369e5722ffb022..ae207495b213a86fa388e241ef7434f925919a39 100644 (file)
@@ -28,14 +28,16 @@ import string
 import SCons.Node.FS
 import SCons.Scanner
 
-def DirScanner(fs = SCons.Node.FS.default_fs, **kw):
+def DirScanner(**kw):
     """Return a prototype Scanner instance for scanning
     directories for on-disk files"""
-    def only_dirs(nodes, fs=fs):
-        return filter(lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir), nodes)
-    kw['node_factory'] = fs.Entry
+    def only_dirs(nodes):
+        return filter(lambda n: isinstance(n.disambiguate(),
+                                SCons.Node.FS.Dir),
+                      nodes)
+    kw['node_factory'] = SCons.Node.FS.Entry
     kw['recursive'] = only_dirs
-    ds = apply(SCons.Scanner.Base, [scan, "DirScanner"], kw)
+    ds = apply(SCons.Scanner.Base, (scan, "DirScanner"), kw)
     return ds
 
 skip_entry = {
index e735ca2bcfc4ef24179a63d48bfd2ea821497cef..257e76b8f12aa3611130c6f43cd0a840fbba4fef 100644 (file)
@@ -47,24 +47,35 @@ test.write(['dir', 'sub', '.sconsign'], "dir/.sconsign\n")
 test.write(['dir', 'sub', '.sconsign.dblite'], "dir/.sconsign.dblite\n")
 
 class DummyNode:
-    def __init__(self, name):
+    def __init__(self, name, fs):
         self.name = name
         self.abspath = test.workpath(name)
-        self.fs = SCons.Node.FS.default_fs
+        self.fs = fs
     def __str__(self):
         return self.name
     def Entry(self, name):
         return self.fs.Entry(name)
 
+class DummyEnvironment:
+    def __init__(self):
+        self.fs = SCons.Node.FS.FS()
+    def Entry(self, name):
+        node = DummyNode(name, self.fs)
+        return node
+    def get_factory(self, factory):
+        return factory or self.fs.Entry
+
 class DirScannerTestCase1(unittest.TestCase):
     def runTest(self):
+        env = DummyEnvironment()
+
         s = SCons.Scanner.Dir.DirScanner()
 
-        deps = s(DummyNode('dir'), {}, ())
+        deps = s(env.Entry('dir'), env, ())
         sss = map(str, deps)
         assert sss == ['f1', 'f2', 'sub'], sss
 
-        deps = s(DummyNode('dir/sub'), {}, ())
+        deps = s(env.Entry('dir/sub'), env, ())
         sss = map(str, deps)
         assert sss == ['f3', 'f4'], sss
 
index 4da0914d3d3943e756599164e23a741dd241a747..66bec0c835a03c9ce413371234277539afbd3737 100644 (file)
@@ -55,13 +55,12 @@ class F90Scanner(SCons.Scanner.Classic):
     """
 
     def __init__(self, name, suffixes, path_variable, use_regex,
-                 incl_regex, fs=SCons.Node.FS.default_fs, *args, **kw):
+                 incl_regex, *args, **kw):
 
         self.cre_use = re.compile(use_regex, re.M)
         self.cre_incl = re.compile(incl_regex, re.M)
-        self.fs = fs
 
-        def _scan(node, env, path, self=self, fs=fs):
+        def _scan(node, env, path, self=self):
             node = node.rfile()
 
             if not node.exists():
@@ -70,7 +69,7 @@ class F90Scanner(SCons.Scanner.Classic):
             return self.scan(node, env, path)
 
         kw['function'] = _scan
-        kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable, fs)
+        kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable)
         kw['recursive'] = 1
         kw['skeys'] = suffixes
         kw['name'] = name
@@ -117,7 +116,7 @@ class F90Scanner(SCons.Scanner.Classic):
         nodes = map(lambda pair: pair[1], nodes)
         return nodes
 
-def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
+def FortranScan(path_variable="FORTRANPATH"):
     """Return a prototype Scanner instance for scanning source files
     for Fortran USE & INCLUDE statements"""
 
@@ -275,6 +274,5 @@ def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
                          "$FORTRANSUFFIXES",
                          path_variable,
                          use_regex,
-                         include_regex,
-                         fs = fs)
+                         include_regex)
     return scanner
index 4c825221b82d601387b0e5c085075413fd1f18b7..141f375c7852a3759600d9da25cd02ec24f2b92b 100644 (file)
@@ -210,6 +210,7 @@ test.write(['modules', 'use.mod'], "\n")
 class DummyEnvironment:
     def __init__(self, listCppPath):
         self.path = listCppPath
+        self.fs = SCons.Node.FS.FS(test.workpath(''))
 
     def Dictionary(self, *args):
         if not args:
@@ -244,14 +245,20 @@ class DummyEnvironment:
     def get_calculator(self):
         return None
 
+    def get_factory(self, factory):
+        return factory or self.fs.File
+
+    def Dir(self, filename):
+        return self.fs.Dir(test.workpath(filename))
+
+    def File(self, filename):
+        return self.fs.File(test.workpath(filename))
+
 def deps_match(self, deps, headers):
     scanned = map(os.path.normpath, map(str, deps))
     expect = map(os.path.normpath, headers)
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
-def make_node(filename, fs=SCons.Node.FS.default_fs):
-    return fs.File(test.workpath(filename))
-
 # define some tests:
 
 class FortranScannerTestCase1(unittest.TestCase):
@@ -261,10 +268,9 @@ class FortranScannerTestCase1(unittest.TestCase):
         env = DummyEnvironment([])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff1.f', fs), env, path)
+        deps = s(env.File('fff1.f'), env, path)
         headers = ['f1.f', 'f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.unlink('f1.f')
         test.unlink('f2.f')
 
@@ -275,10 +281,9 @@ class FortranScannerTestCase2(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff1.f', fs), env, path)
+        deps = s(env.File('fff1.f'), env, path)
         headers = ['f1.f', 'f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.unlink('f1.f')
         test.unlink('f2.f')
 
@@ -287,10 +292,9 @@ class FortranScannerTestCase3(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff1.f', fs), env, path)
+        deps = s(env.File('fff1.f'), env, path)
         headers = ['d1/f1.f', 'd1/f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class FortranScannerTestCase4(unittest.TestCase):
     def runTest(self):
@@ -298,10 +302,9 @@ class FortranScannerTestCase4(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff1.f', fs), env, path)
+        deps = s(env.File('fff1.f'), env, path)
         headers = ['d1/f1.f', 'd1/f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.write(['d1', 'f2.f'], "\n")
 
 class FortranScannerTestCase5(unittest.TestCase):
@@ -309,10 +312,9 @@ class FortranScannerTestCase5(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff2.f', fs), env, path)
+        deps = s(env.File('fff2.f'), env, path)
         headers = ['d1/f2.f', 'd1/d2/f2.f', 'd1/f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class FortranScannerTestCase6(unittest.TestCase):
     def runTest(self):
@@ -320,10 +322,9 @@ class FortranScannerTestCase6(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff2.f', fs), env, path)
+        deps = s(env.File('fff2.f'), env, path)
         headers =  ['d1/f2.f', 'd1/d2/f2.f', 'f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.unlink('f2.f')
 
 class FortranScannerTestCase7(unittest.TestCase):
@@ -331,10 +332,9 @@ class FortranScannerTestCase7(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff2.f', fs), env, path)
+        deps = s(env.File('fff2.f'), env, path)
         headers =  ['d1/f2.f', 'd1/d2/f2.f', 'd1/d2/f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class FortranScannerTestCase8(unittest.TestCase):
     def runTest(self):
@@ -342,10 +342,9 @@ class FortranScannerTestCase8(unittest.TestCase):
         env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff2.f', fs), env, path)
+        deps = s(env.File('fff2.f'), env, path)
         headers =  ['d1/f2.f', 'd1/d2/f2.f', 'f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.unlink('f2.f')
 
 class FortranScannerTestCase9(unittest.TestCase):
@@ -355,7 +354,7 @@ class FortranScannerTestCase9(unittest.TestCase):
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
 
-        n = make_node('fff3.f')
+        n = env.File('fff3.f')
         def my_rexists(s=n):
             s.rexists_called = 1
             return s.old_rexists()
@@ -369,21 +368,20 @@ class FortranScannerTestCase9(unittest.TestCase):
         assert n.rexists_called
 
         headers =  ['d1/f3.f', 'f3.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.unlink('f3.f')
 
 class FortranScannerTestCase10(unittest.TestCase):
     def runTest(self):
-        fs = SCons.Node.FS.FS(test.workpath(''))
         env = DummyEnvironment(["include"])
-        s = SCons.Scanner.Fortran.FortranScan(fs = fs)
+        s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        deps1 = s(fs.File('fff4.f'), env, path)
-        fs.chdir(fs.Dir('subdir'))
-        dir = fs.getcwd()
-        fs.chdir(fs.Dir('..'))
+        deps1 = s(env.File('fff4.f'), env, path)
+        env.fs.chdir(env.Dir('subdir'))
+        dir = env.fs.getcwd()
+        env.fs.chdir(env.Dir(''))
         path = s.path(env, dir)
-        deps2 = s(fs.File('#fff4.f'), env, path)
+        deps2 = s(env.File('#fff4.f'), env, path)
         headers1 =  ['include/f4.f']
         headers2 =  ['subdir/include/f4.f']
         deps_match(self, deps1, headers1)
@@ -399,11 +397,10 @@ class FortranScannerTestCase11(unittest.TestCase):
         to = TestOut()
         to.out = None
         SCons.Warnings._warningOut = to
-        fs = SCons.Node.FS.FS(test.workpath(''))
         env = DummyEnvironment([])
-        s = SCons.Scanner.Fortran.FortranScan(fs=fs)
+        s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        deps = s(fs.File('fff5.f'), env, path)
+        deps = s(env.File('fff5.f'), env, path)
 
         # Did we catch the warning from not finding not_there.f?
         assert to.out
@@ -412,14 +409,13 @@ class FortranScannerTestCase11(unittest.TestCase):
 
 class FortranScannerTestCase12(unittest.TestCase):
     def runTest(self):
-        fs = SCons.Node.FS.FS(test.workpath(''))
-        fs.chdir(fs.Dir('include'))
         env = DummyEnvironment([])
-        s = SCons.Scanner.Fortran.FortranScan(fs=fs)
+        env.fs.chdir(env.Dir('include'))
+        s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
         test.write('include/fff4.f', test.read('fff4.f'))
-        deps = s(fs.File('#include/fff4.f'), env, path)
-        fs.chdir(fs.Dir('..'))
+        deps = s(env.File('#include/fff4.f'), env, path)
+        env.fs.chdir(env.Dir(''))
         deps_match(self, deps, ['include/f4.f'])
         test.unlink('include/fff4.f')
 
@@ -434,7 +430,8 @@ class FortranScannerTestCase13(unittest.TestCase):
         f1=fs.File('include2/jjj.f')
         f1.builder=1
         env = DummyEnvironment(['include','include2'])
-        s = SCons.Scanner.Fortran.FortranScan(fs=fs)
+        env.fs = fs
+        s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
         deps = s(fs.File('src/fff.f'), env, path)
         deps_match(self, deps, [test.workpath('repository/include/iii.f'), 'include2/jjj.f'])
@@ -448,7 +445,8 @@ class FortranScannerTestCase14(unittest.TestCase):
         fs.BuildDir('build2', 'src', 0)
         fs.Repository(test.workpath('repository'))
         env = DummyEnvironment([])
-        s = SCons.Scanner.Fortran.FortranScan(fs = fs)
+        env.fs = fs
+        s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
         deps1 = s(fs.File('build1/aaa.f'), env, path)
         deps_match(self, deps1, [ 'build1/bbb.f' ])
@@ -469,10 +467,9 @@ class FortranScannerTestCase15(unittest.TestCase):
         env = SubstEnvironment(["junk"])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff1.f', fs), env, path)
+        deps = s(env.File('fff1.f'), env, path)
         headers = ['d1/f1.f', 'd1/f2.f']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         test.write(['d1', 'f2.f'], "\n")
 
 class FortranScannerTestCase16(unittest.TestCase):
@@ -490,8 +487,7 @@ class FortranScannerTestCase16(unittest.TestCase):
         env = DummyEnvironment([test.workpath('modules')])
         s = SCons.Scanner.Fortran.FortranScan()
         path = s.path(env)
-        fs = SCons.Node.FS.FS(original)
-        deps = s(make_node('fff90a.f90', fs), env, path)
+        deps = s(env.File('fff90a.f90'), env, path)
         headers = ['f1.f', 'f2.f', 'f3.f', 'f4.f', 'f5.f', 'f6.f', 'f7.f', 'f8.f', 'f9.f']
         modules = ['mod01.mod', 'mod02.mod', 'mod03.mod', 'mod04.mod', 'mod05.mod',
                    'mod06.mod', 'mod07.mod', 'mod08.mod', 'mod09.mod', 'mod10.mod',
@@ -499,7 +495,7 @@ class FortranScannerTestCase16(unittest.TestCase):
                    'mod16.mod', 'mod17.mod', 'mod18.mod', 'mod19.mod', 'mod20.mod',
                    'mod21.mod', 'mod22.mod', 'mod23.mod', 'mod24.mod', 'mod25.mod', 'modules/use.mod']
         deps_expected = headers + modules
-        deps_match(self, deps, map(test.workpath, deps_expected))
+        deps_match(self, deps, deps_expected)
         test.unlink('f1.f')
         test.unlink('f2.f')
         test.unlink('f3.f')
index 8c4f68d597d6bd4dbf3b6fbd47ed6cac9db2099d..b0fd8ed5de2c559fd583839cad20bc247ae32a36 100644 (file)
@@ -33,11 +33,10 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import SCons.Node.FS
 import SCons.Scanner
 
-def IDLScan(fs = SCons.Node.FS.default_fs):
+def IDLScan():
     """Return a prototype Scanner instance for scanning IDL source files"""
     cs = SCons.Scanner.ClassicCPP("IDLScan",
                                   "$IDLSUFFIXES",
                                   "CPPPATH",
-                                  '^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")',
-                                  fs = fs)
+                                  '^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")')
     return cs
index db842c340df556567325e4ef70ebe0baacb0ac2a..d1a094166076d777007628ae6a48964dd9478902 100644 (file)
@@ -189,6 +189,7 @@ test.write([ 'repository', 'src', 'ddd.idl'], "\n")
 class DummyEnvironment:
     def __init__(self, listCppPath):
         self.path = listCppPath
+        self.fs = SCons.Node.FS.FS(test.workpath(''))
         
     def Dictionary(self, *args):
         if not args:
@@ -221,6 +222,15 @@ class DummyEnvironment:
     def get_calculator(self):
         return None
 
+    def get_factory(self, factory):
+        return factory or self.fs.File
+
+    def Dir(self, filename):
+        return self.fs.Dir(test.workpath(filename))
+
+    def File(self, filename):
+        return self.fs.File(test.workpath(filename))
+
 global my_normpath
 my_normpath = os.path.normpath
 
@@ -232,9 +242,6 @@ def deps_match(self, deps, headers):
     expect = map(my_normpath, headers)
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
-def make_node(filename, fs=SCons.Node.FS.default_fs):
-    return fs.File(test.workpath(filename))
-
 # define some tests:
 
 class IDLScannerTestCase1(unittest.TestCase):
@@ -242,36 +249,36 @@ class IDLScannerTestCase1(unittest.TestCase):
         env = DummyEnvironment([])
         s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps = s(make_node('t1.idl'), env, path)
+        deps = s(env.File('t1.idl'), env, path)
         headers = ['f1.idl', 'f3.idl', 'f2.idl']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class IDLScannerTestCase2(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps = s(make_node('t1.idl'), env, path)
+        deps = s(env.File('t1.idl'), env, path)
         headers = ['f1.idl', 'f3.idl', 'd1/f2.idl']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class IDLScannerTestCase3(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment([test.workpath("d1")])
         s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps = s(make_node('t2.idl'), env, path)
+        deps = s(env.File('t2.idl'), env, path)
         headers = ['d1/f1.idl', 'f1.idl', 'd1/d2/f1.idl', 'f3.idl']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class IDLScannerTestCase4(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment([test.workpath("d1"), test.workpath("d1/d2")])
         s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps = s(make_node('t2.idl'), env, path)
+        deps = s(env.File('t2.idl'), env, path)
         headers =  ['d1/f1.idl', 'f1.idl', 'd1/d2/f1.idl', 'f3.idl']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         
 class IDLScannerTestCase5(unittest.TestCase):
     def runTest(self):
@@ -279,7 +286,7 @@ class IDLScannerTestCase5(unittest.TestCase):
         s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
 
-        n = make_node('t3.idl')
+        n = env.File('t3.idl')
         def my_rexists(s=n):
             s.rexists_called = 1
             return s.old_rexists()
@@ -295,7 +302,7 @@ class IDLScannerTestCase5(unittest.TestCase):
         headers =  ['d1/f1.idl', 'd1/f2.idl',
                     'f1.idl', 'f2.idl', 'f3-test.idl',
                     'd1/f1.idl', 'd1/f2.idl', 'd1/f3-test.idl']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
 
 class IDLScannerTestCase6(unittest.TestCase):
     def runTest(self):
@@ -304,25 +311,24 @@ class IDLScannerTestCase6(unittest.TestCase):
         s = SCons.Scanner.IDL.IDLScan()
         path1 = s.path(env1)
         path2 = s.path(env2)
-        deps1 = s(make_node('t1.idl'), env1, path1)
-        deps2 = s(make_node('t1.idl'), env2, path2)
+        deps1 = s(env1.File('t1.idl'), env1, path1)
+        deps2 = s(env2.File('t1.idl'), env2, path2)
         headers1 = ['f1.idl', 'f3.idl', 'd1/f2.idl']
         headers2 = ['f1.idl', 'f3.idl', 'd1/d2/f2.idl']
-        deps_match(self, deps1, map(test.workpath, headers1))
-        deps_match(self, deps2, map(test.workpath, headers2))
+        deps_match(self, deps1, headers1)
+        deps_match(self, deps2, headers2)
 
 class IDLScannerTestCase7(unittest.TestCase):
     def runTest(self):
-        fs = SCons.Node.FS.FS(test.workpath(''))
         env = DummyEnvironment(["include"])
-        s = SCons.Scanner.IDL.IDLScan(fs = fs)
+        s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps1 = s(fs.File('t4.idl'), env, path)
-        fs.chdir(fs.Dir('subdir'))
-        dir = fs.getcwd()
-        fs.chdir(fs.Dir('..'))
+        deps1 = s(env.File('t4.idl'), env, path)
+        env.fs.chdir(env.Dir('subdir'))
+        dir = env.fs.getcwd()
+        env.fs.chdir(env.Dir(''))
         path = s.path(env, dir)
-        deps2 = s(fs.File('#t4.idl'), env, path)
+        deps2 = s(env.File('#t4.idl'), env, path)
         headers1 =  ['include/fa.idl', 'include/fb.idl']
         headers2 =  ['subdir/include/fa.idl', 'subdir/include/fb.idl']
         deps_match(self, deps1, headers1)
@@ -339,11 +345,10 @@ class IDLScannerTestCase8(unittest.TestCase):
         to.out = None
         SCons.Warnings._warningOut = to
         test.write('fa.idl','\n')
-        fs = SCons.Node.FS.FS(test.workpath(''))
         env = DummyEnvironment([])
-        s = SCons.Scanner.IDL.IDLScan(fs=fs)
+        s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps = s(fs.File('t4.idl'), env, path)
+        deps = s(env.File('t4.idl'), env, path)
 
         # Did we catch the warning associated with not finding fb.idl?
         assert to.out
@@ -353,14 +358,13 @@ class IDLScannerTestCase8(unittest.TestCase):
 
 class IDLScannerTestCase9(unittest.TestCase):
     def runTest(self):
-        fs = SCons.Node.FS.FS(test.workpath(''))
-        fs.chdir(fs.Dir('include'))
         env = DummyEnvironment([])
-        s = SCons.Scanner.IDL.IDLScan(fs=fs)
+        env.fs.chdir(env.Dir('include'))
+        s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
         test.write('include/t4.idl', test.read('t4.idl'))
-        deps = s(fs.File('#include/t4.idl'), env, path)
-        fs.chdir(fs.Dir('..'))
+        deps = s(env.File('#include/t4.idl'), env, path)
+        env.fs.chdir(env.Dir(''))
         deps_match(self, deps, [ 'include/fa.idl', 'include/fb.idl' ])
         test.unlink('include/t4.idl')
 
@@ -372,13 +376,15 @@ class IDLScannerTestCase10(unittest.TestCase):
 
         # Create a derived file in a directory that does not exist yet.
         # This was a bug at one time.
-        f1=fs.File('include2/jjj.idl')
-        f1.builder=1
         env = DummyEnvironment(['include', 'include2'])
-        s = SCons.Scanner.IDL.IDLScan(fs=fs)
+        env.fs = fs
+        f1 = fs.File('include2/jjj.idl')
+        f1.builder = 1
+        s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
         deps = s(fs.File('src/fff.c'), env, path)
-        deps_match(self, deps, [ test.workpath('repository/include/iii.idl'), 'include2/jjj.idl' ])
+        deps_match(self, deps, [ test.workpath('repository/include/iii.idl'),
+                                 'include2/jjj.idl' ])
         os.chdir(test.workpath(''))
 
 class IDLScannerTestCase11(unittest.TestCase):
@@ -389,7 +395,8 @@ class IDLScannerTestCase11(unittest.TestCase):
         fs.BuildDir('build2', 'src', 0)
         fs.Repository(test.workpath('repository'))
         env = DummyEnvironment([])
-        s = SCons.Scanner.IDL.IDLScan(fs = fs)
+        env.fs = fs
+        s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
         deps1 = s(fs.File('build1/aaa.c'), env, path)
         deps_match(self, deps1, [ 'build1/bbb.idl' ])
@@ -409,9 +416,9 @@ class IDLScannerTestCase12(unittest.TestCase):
         env = SubstEnvironment(["blah"])
         s = SCons.Scanner.IDL.IDLScan()
         path = s.path(env)
-        deps = s(make_node('t1.idl'), env, path)
+        deps = s(env.File('t1.idl'), env, path)
         headers = ['f1.idl', 'f3.idl', 'd1/f2.idl']
-        deps_match(self, deps, map(test.workpath, headers))
+        deps_match(self, deps, headers)
         
 
 def suite():
index 206c6de9dd635a78b0a531da7c2a226bc9b3f04b..54db9a8b6a7782bddda483f15b1f9f4a443d8da4 100644 (file)
@@ -33,14 +33,14 @@ import SCons.Util
 # global, set by --debug=findlibs
 print_find_libs = None
 
-def ProgramScanner(fs = SCons.Node.FS.default_fs, **kw):
+def ProgramScanner(**kw):
     """Return a prototype Scanner instance for scanning executable
     files for static-lib dependencies"""
-    kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH', fs)
+    kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH')
     ps = apply(SCons.Scanner.Base, [scan, "ProgramScanner"], kw)
     return ps
 
-def scan(node, env, libpath = (), fs = SCons.Node.FS.default_fs):
+def scan(node, env, libpath = ()):
     """
     This scanner scans program files for static-library
     dependencies.  It will search the LIBPATH environment variable
index ec25f244f5e9c90ea1bd61ea2c5912ce23f7f065..bac10b732106962997e5b9bbc37fe98797c24760 100644 (file)
@@ -49,6 +49,7 @@ class DummyEnvironment:
     def __init__(self, **kw):
         self._dict = {'LIBSUFFIXES' : '.lib'}
         self._dict.update(kw)
+        self.fs = SCons.Node.FS.FS(test.workpath(''))
 
     def Dictionary(self, *args):
         if not args:
@@ -83,6 +84,15 @@ class DummyEnvironment:
             path = [path]
         return map(self.subst, path)
 
+    def get_factory(self, factory):
+        return factory or self.fs.File
+
+    def Dir(self, filename):
+        return self.fs.Dir(test.workpath(filename))
+
+    def File(self, filename):
+        return self.fs.File(test.workpath(filename))
+
 class DummyNode:
     def __init__(self, name):
         self.name = name
@@ -95,9 +105,7 @@ def deps_match(deps, libs):
     deps=map(str, deps)
     deps.sort()
     libs.sort()
-    return map(os.path.normpath, deps) == \
-           map(os.path.normpath,
-               map(test.workpath, libs))
+    return map(os.path.normpath, deps) == map(os.path.normpath, libs)
 
 # define some tests:
 
@@ -117,7 +125,7 @@ class ProgramScannerTestCase1(unittest.TestCase):
         deps = s(DummyNode('dummy'), env, path)
         assert deps_match(deps, ['l1.lib']), map(str, deps)
 
-        f1 = SCons.Node.FS.default_fs.File(test.workpath('f1'))
+        f1 = env.fs.File(test.workpath('f1'))
         env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
                                LIBS=[f1])
         s = SCons.Scanner.Prog.ProgramScanner()
@@ -125,7 +133,7 @@ class ProgramScannerTestCase1(unittest.TestCase):
         deps = s(DummyNode('dummy'), env, path)
         assert deps[0] is f1, deps
 
-        f2 = SCons.Node.FS.default_fs.File(test.workpath('f1'))
+        f2 = env.fs.File(test.workpath('f1'))
         env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
                                LIBS=f2)
         s = SCons.Scanner.Prog.ProgramScanner()
index ef836bca6475ea5dc085703e08fcc8b51e26eb02..0d0cceced7ffebaa10e46c26038118681644f60c 100644 (file)
@@ -30,10 +30,19 @@ import SCons.Sig
 
 import SCons.Scanner
 
+class DummyFS:
+    def __init__(self, search_result=[]):
+        self.search_result = search_result
+    def File(self, name):
+        return DummyNode(name)
+    def Rsearchall(self, nodes, must_exist=0, clazz=None, cwd=dir):
+        return self.search_result + nodes
+
 class DummyEnvironment(UserDict.UserDict):
     def __init__(self, dict=None, **kw):
         UserDict.UserDict.__init__(self, dict)
         self.data.update(kw)
+        self.fs = DummyFS()
     def subst(self, strSubst):
         if strSubst[0] == '$':
             return self.data[strSubst[1:]]
@@ -48,6 +57,8 @@ class DummyEnvironment(UserDict.UserDict):
         return map(self.subst, path)
     def get_calculator(self):
         return SCons.Sig.default_calc
+    def get_factory(self, factory):
+        return factory or self.fs.File
 
 class DummyNode:
     def __init__(self, name):
@@ -56,18 +67,15 @@ class DummyNode:
         return 1
     def __str__(self):
         return self.name
-    
+
 class FindPathDirsTestCase(unittest.TestCase):
     def test_FindPathDirs(self):
         """Test the FindPathDirs callable class"""
 
-        class FS:
-            def Rsearchall(self, nodes, must_exist=0, clazz=None, cwd=dir):
-                return ['xxx'] + nodes
-
         env = DummyEnvironment(LIBPATH = [ 'foo' ])
+        env.fs = DummyFS(['xxx'])
 
-        fpd = SCons.Scanner.FindPathDirs('LIBPATH', FS())
+        fpd = SCons.Scanner.FindPathDirs('LIBPATH')
         result = fpd(env, dir)
         assert str(result) == "('xxx', 'foo')", result
 
@@ -308,11 +316,12 @@ class SelectorTestCase(unittest.TestCase):
         s2 = SCons.Scanner.Base(s2func)
         selector = SCons.Scanner.Selector({'.x' : s1, '.y' : s2})
         nx = self.skey_node('.x')
-        selector(nx, None, [])
+        env = DummyEnvironment()
+        selector(nx, env, [])
         assert called == ['s1func', nx], called
         del called[:]
         ny = self.skey_node('.y')
-        selector(ny, None, [])
+        selector(ny, env, [])
         assert called == ['s2func', ny], called
 
     def test_select(self):
index 247eafb75bf344f618309ece4b62ebf8c675d961..504b6df96d9177eeb9b326c97b0b549d8ee6668d 100644 (file)
@@ -75,11 +75,10 @@ def Binder(path):
 
 
 class FindPathDirs:
-    """A class to bind a specific *PATH variable name and the fs object
-    to a function that will return all of the *path directories."""
-    def __init__(self, variable, fs):
+    """A class to bind a specific *PATH variable name to a function that
+    will return all of the *path directories."""
+    def __init__(self, variable):
         self.variable = variable
-        self.fs = fs
     def __call__(self, env, dir, target=None, source=None, argument=None):
         # The goal is that we've made caching this unnecessary
         # because the caching takes place at higher layers.
@@ -89,10 +88,10 @@ class FindPathDirs:
             return ()
 
         path = env.subst_path(path, target=target, source=source)
-        path_tuple = tuple(self.fs.Rsearchall(path,
-                                              must_exist = 0, #kwq!
-                                              clazz = SCons.Node.FS.Dir,
-                                              cwd = dir))
+        path_tuple = tuple(env.fs.Rsearchall(path,
+                                             must_exist = 0, #kwq!
+                                             clazz = SCons.Node.FS.Dir,
+                                             cwd = dir))
         return Binder(path_tuple)
 
 class Base:
@@ -110,7 +109,7 @@ class Base:
                  skeys = [],
                  path_function = None,
                  node_class = SCons.Node.FS.Entry,
-                 node_factory = SCons.Node.FS.default_fs.File,
+                 node_factory = None,
                  scan_check = None,
                  recursive = None):
         """
@@ -155,13 +154,12 @@ class Base:
         (the canonical example being only recursively scanning
         subdirectories within a directory).
 
-        The scanner function's first argument will be the a Node that
-        should be scanned for dependencies, the second argument will
-        be an Environment object, the third argument will be the tuple
-        of paths returned by the path_function, and the fourth
-        argument will be the value passed into 'argument', and the
-        returned list should contain the Nodes for all the direct
-        dependencies of the file.
+        The scanner function's first argument will be a Node that should
+        be scanned for dependencies, the second argument will be an
+        Environment object, the third argument will be the tuple of paths
+        returned by the path_function, and the fourth argument will be
+        the value passed into 'argument', and the returned list should
+        contain the Nodes for all the direct dependencies of the file.
 
         Examples:
 
@@ -218,10 +216,11 @@ class Base:
         kw = {}
         if hasattr(node, 'dir'):
             kw['directory'] = node.dir
+        node_factory = env.get_factory(self.node_factory)
         nodes = []
         for l in list:
             if self.node_class and not isinstance(l, self.node_class):
-                l = apply(self.node_factory, (l,), kw)
+                l = apply(node_factory, (l,), kw)
             nodes.append(l)
         return nodes
 
@@ -315,11 +314,9 @@ class Classic(Current):
     include file in group 0.
     """
 
-    def __init__(self, name, suffixes, path_variable, regex,
-                 fs=SCons.Node.FS.default_fs, *args, **kw):
+    def __init__(self, name, suffixes, path_variable, regex, *args, **kw):
 
         self.cre = re.compile(regex, re.M)
-        self.fs = fs
 
         def _scan(node, env, path=(), self=self):
             node = node.rfile()
@@ -328,7 +325,7 @@ class Classic(Current):
             return self.scan(node, path)
 
         kw['function'] = _scan
-        kw['path_function'] = FindPathDirs(path_variable, fs)
+        kw['path_function'] = FindPathDirs(path_variable)
         kw['recursive'] = 1
         kw['skeys'] = suffixes
         kw['name'] = name
index d018d150ea3b196ab78f5aa39739a7f5231a8e15..fd2a9143c4fdf0caa84e8acba46a45c869c9444e 100644 (file)
@@ -241,7 +241,6 @@ class QuestionTask(SCons.Taskmaster.Task):
 # Global variables
 
 keep_going_on_error = 0
-count_stats = None
 print_dtree = 0
 print_explanations = 0
 print_includes = 0
@@ -251,7 +250,6 @@ print_stacktrace = 0
 print_stree = 0
 print_time = 0
 print_tree = 0
-memory_stats = None
 ignore_errors = 0
 sconscript_time = 0
 command_time = 0
@@ -260,6 +258,62 @@ profiling = 0
 repositories = []
 num_jobs = 1 # this is modifed by SConscript.SetJobs()
 
+#
+class Stats:
+    def __init__(self):
+        self.stats = []
+        self.labels = []
+        self.append = self.do_nothing
+        self.print_stats = self.do_nothing
+    def enable(self, outfp):
+        self.outfp = outfp
+        self.append = self.do_append
+        self.print_stats = self.do_print
+    def do_nothing(self, *args, **kw):
+        pass
+
+class CountStats(Stats):
+    def do_append(self, label):
+        self.labels.append(label)
+        self.stats.append(SCons.Debug.fetchLoggedInstances())
+    def do_print(self):
+        stats_table = {}
+        for s in self.stats:
+            for n in map(lambda t: t[0], s):
+                stats_table[n] = [0, 0, 0, 0]
+        i = 0
+        for s in self.stats:
+            for n, c in s:
+                stats_table[n][i] = c
+            i = i + 1
+        keys = stats_table.keys()
+        keys.sort()
+        self.outfp.write("Object counts:\n")
+        pre = ["   "]
+        post = ["   %s\n"]
+        l = len(self.stats)
+        fmt1 = string.join(pre + [' %7s']*l + post, '')
+        fmt2 = string.join(pre + [' %7d']*l + post, '')
+        self.labels.append(("", "Class"))
+        self.outfp.write(fmt1 % tuple(map(lambda x: x[0], self.labels)))
+        self.outfp.write(fmt1 % tuple(map(lambda x: x[1], self.labels)))
+        for k in keys:
+            r = stats_table[k]
+            self.outfp.write(fmt2 % (r[0], r[1], r[2], r[3], k))
+
+count_stats = CountStats()
+
+class MemStats(Stats):
+    def do_append(self, label):
+        self.labels.append(label)
+        self.stats.append(SCons.Debug.memory())
+    def do_print(self):
+        fmt = 'Memory %-32s %12d\n'
+        for label, stats in map(None, self.labels, self.stats):
+            self.outfp.write(fmt % (label, stats))
+
+memory_stats = MemStats()
+
 # utility functions
 
 def get_all_children(node): return node.all_children()
@@ -406,15 +460,13 @@ def _SConstruct_exists(dirname=''):
     return None
 
 def _set_globals(options):
-    global repositories, keep_going_on_error, ignore_errors
+    global keep_going_on_error, ignore_errors
     global count_stats, print_dtree
     global print_explanations, print_includes, print_memoizer
     global print_objects, print_stacktrace, print_stree
     global print_time, print_tree
-    global memory_outf, memory_stats
+    global memory_stats
 
-    if options.repository:
-        repositories.extend(options.repository)
     keep_going_on_error = options.keep_going
     try:
         debug_values = options.debug
@@ -424,7 +476,7 @@ def _set_globals(options):
         pass
     else:
         if "count" in debug_values:
-            count_stats = []
+            count_stats.enable(sys.stdout)
         if "dtree" in debug_values:
             print_dtree = 1
         if "explain" in debug_values:
@@ -436,8 +488,7 @@ def _set_globals(options):
         if "memoizer" in debug_values:
             print_memoizer = 1
         if "memory" in debug_values:
-            memory_stats = []
-            memory_outf = sys.stdout
+            memory_stats.enable(sys.stdout)
         if "objects" in debug_values:
             print_objects = 1
         if "presub" in debug_values:
@@ -795,50 +846,28 @@ class SConscriptSettableOptions:
     
 
 def _main(args, parser):
-    targets = []
-    fs = SCons.Node.FS.default_fs
-
-    # Enable deprecated warnings by default.
+    # Here's where everything really happens.
+
+    # First order of business:  set up default warnings and and then
+    # handle the user's warning options, so we can warn about anything
+    # that happens appropriately.
+    default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
+                         SCons.Warnings.DeprecatedWarning,
+                         SCons.Warnings.DuplicateEnvironmentWarning,
+                         SCons.Warnings.MissingSConscriptWarning,
+                         SCons.Warnings.NoParallelSupportWarning,
+                         SCons.Warnings.MisleadingKeywordsWarning, ]
+    for warning in default_warnings:
+        SCons.Warnings.enableWarningClass(warning)
     SCons.Warnings._warningOut = _scons_internal_warning
-    SCons.Warnings.enableWarningClass(SCons.Warnings.CorruptSConsignWarning)
-    SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning)
-    SCons.Warnings.enableWarningClass(SCons.Warnings.DuplicateEnvironmentWarning)
-    SCons.Warnings.enableWarningClass(SCons.Warnings.MissingSConscriptWarning)
-    SCons.Warnings.enableWarningClass(SCons.Warnings.NoParallelSupportWarning)
-    # This is good for newbies, and hopefully most everyone else too.
-    SCons.Warnings.enableWarningClass(SCons.Warnings.MisleadingKeywordsWarning)
-
-    global ssoptions
-    ssoptions = SConscriptSettableOptions(options)
-
-    _set_globals(options)
-    SCons.Node.implicit_cache = options.implicit_cache
-    SCons.Node.implicit_deps_changed = options.implicit_deps_changed
-    SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
     if options.warn:
         _setup_warn(options.warn)
-    if options.noexec:
-        SCons.SConf.dryrun = 1
-        SCons.Action.execute_actions = None
-        CleanTask.execute = CleanTask.show
-    if options.question:
-        SCons.SConf.dryrun = 1
-    SCons.SConf.SetCacheMode(options.config)
-    SCons.SConf.SetProgressDisplay(progress_display)
 
-    if options.no_progress or options.silent:
-        progress_display.set_mode(0)
-    if options.silent:
-        display.set_mode(0)
-    if options.silent:
-        SCons.Action.print_actions = None
-    if options.cache_disable:
-        def disable(self): pass
-        fs.CacheDir = disable
-    if options.cache_force:
-        fs.cache_force = 1
-    if options.cache_show:
-        fs.cache_show = 1
+    # Next, we want to create the FS object that represents the outside
+    # world's file system, as that's central to a lot of initialization.
+    # To do this, however, we need to be in the directory from which we
+    # want to start everything, which means first handling any relevant
+    # options that might cause us to chdir somewhere (-C, -D, -U, -u).
     if options.directory:
         cdir = _create_path(options.directory)
         try:
@@ -846,14 +875,11 @@ def _main(args, parser):
         except OSError:
             sys.stderr.write("Could not change directory to %s\n" % cdir)
 
-    xmit_args = []
-    for a in args:
-        if '=' in a:
-            xmit_args.append(a)
-        else:
-            targets.append(a)
-    SCons.Script._Add_Arguments(xmit_args)
-    SCons.Script._Add_Targets(targets)
+    # The SConstruct file may be in a repository, so initialize those
+    # before we start the search up our path for one.
+    global repositories
+    if options.repository:
+        repositories.extend(options.repository)
 
     target_top = None
     if options.climb_up:
@@ -869,8 +895,17 @@ def _main(args, parser):
             display("scons: Entering directory `%s'" % script_dir)
             os.chdir(script_dir)
 
-    fs.set_toplevel_dir(os.getcwd())
+    # Now that we're in the top-level SConstruct directory, go ahead
+    # and initialize the FS object that represents the file system,
+    # and make it the build engine default.
+    fs = SCons.Node.FS.default_fs = SCons.Node.FS.FS()
+
+    for rep in repositories:
+        fs.Repository(rep)
 
+    # Now that we have the FS object, the next order of business is to
+    # check for an SConstruct file (or other specified config file).
+    # If there isn't one, we can bail before doing any more work.
     scripts = []
     if options.file:
         scripts.extend(options.file)
@@ -879,15 +914,13 @@ def _main(args, parser):
         if sfile:
             scripts.append(sfile)
 
-    if options.help_msg:
-        if not scripts:
+    if not scripts:
+        if options.help_msg:
             # There's no SConstruct, but they specified -h.
             # Give them the options usage now, before we fail
             # trying to read a non-existent SConstruct file.
             parser.print_help()
             sys.exit(0)
-
-    if not scripts:
         raise SCons.Errors.UserError, "No SConstruct file found."
 
     if scripts[0] == "-":
@@ -896,6 +929,54 @@ def _main(args, parser):
         d = fs.File(scripts[0]).dir
     fs.set_SConstruct_dir(d)
 
+    # Now that we have the FS object and it's intialized, set up (most
+    # of) the rest of the options.
+    global ssoptions
+    ssoptions = SConscriptSettableOptions(options)
+
+    _set_globals(options)
+    SCons.Node.implicit_cache = options.implicit_cache
+    SCons.Node.implicit_deps_changed = options.implicit_deps_changed
+    SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
+    if options.noexec:
+        SCons.SConf.dryrun = 1
+        SCons.Action.execute_actions = None
+        CleanTask.execute = CleanTask.show
+    if options.question:
+        SCons.SConf.dryrun = 1
+    SCons.SConf.SetCacheMode(options.config)
+    SCons.SConf.SetProgressDisplay(progress_display)
+
+    if options.no_progress or options.silent:
+        progress_display.set_mode(0)
+    if options.silent:
+        display.set_mode(0)
+    if options.silent:
+        SCons.Action.print_actions = None
+    if options.cache_disable:
+        def disable(self): pass
+        fs.CacheDir = disable
+    if options.cache_force:
+        fs.cache_force = 1
+    if options.cache_show:
+        fs.cache_show = 1
+
+    if options.include_dir:
+        sys.path = options.include_dir + sys.path
+
+    # That should cover (most of) the options.  Next, set up the variables
+    # that hold command-line arguments, so the SConscript files that we
+    # read and execute have access to them.
+    targets = []
+    xmit_args = []
+    for a in args:
+        if '=' in a:
+            xmit_args.append(a)
+        else:
+            targets.append(a)
+    SCons.Script._Add_Targets(targets)
+    SCons.Script._Add_Arguments(xmit_args)
+
     class Unbuffered:
         def __init__(self, file):
             self.file = file
@@ -907,15 +988,8 @@ def _main(args, parser):
 
     sys.stdout = Unbuffered(sys.stdout)
 
-    if options.include_dir:
-        sys.path = options.include_dir + sys.path
-
-    global repositories
-    for rep in repositories:
-        fs.Repository(rep)
-
-    if not memory_stats is None: memory_stats.append(SCons.Debug.memory())
-    if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances())
+    memory_stats.append('before reading SConscript files:')
+    count_stats.append(('pre-', 'read'))
 
     progress_display("scons: Reading SConscript files ...")
 
@@ -944,8 +1018,8 @@ def _main(args, parser):
     # file system nodes.
     SCons.Node.FS.save_strings(1)
 
-    if not memory_stats is None: memory_stats.append(SCons.Debug.memory())
-    if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances())
+    memory_stats.append('after reading SConscript files:')
+    count_stats.append(('post-', 'read'))
 
     fs.chdir(fs.Top)
 
@@ -1084,8 +1158,8 @@ def _main(args, parser):
               "\tignoring -j or num_jobs option.\n"
         SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
 
-    if not memory_stats is None: memory_stats.append(SCons.Debug.memory())
-    if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances())
+    memory_stats.append('before building targets:')
+    count_stats.append(('pre-', 'build'))
 
     try:
         jobs.run()
@@ -1097,37 +1171,11 @@ def _main(args, parser):
         if not options.noexec:
             SCons.SConsign.write()
 
-    if not memory_stats is None:
-        memory_stats.append(SCons.Debug.memory())
-        when = [
-            'before reading SConscript files',
-            'after reading SConscript files',
-            'before building targets',
-            'after building targets',
-        ]
-        for i in xrange(len(when)):
-            memory_outf.write('Memory %-32s %12d\n' % (when[i]+':', memory_stats[i]))
-
-    if not count_stats is None:
-        count_stats.append(SCons.Debug.fetchLoggedInstances())
-        stats_table = {}
-        for cs in count_stats:
-            for n in map(lambda t: t[0], cs):
-                stats_table[n] = [0, 0, 0, 0]
-        i = 0
-        for cs in count_stats:
-            for n, c in cs:
-                stats_table[n][i] = c
-            i = i + 1
-        keys = stats_table.keys()
-        keys.sort()
-        print "Object counts:"
-        fmt = "    %7s %7s %7s %7s   %s"
-        print fmt % ("pre-", "post-", "pre-", "post-", "")
-        print fmt % ("read", "read", "build", "build", "Class")
-        for k in keys:
-            r = stats_table[k]
-            print "    %7d %7d %7d %7d   %s" % (r[0], r[1], r[2], r[3], k)
+    memory_stats.append('after building targets:')
+    memory_stats.print_stats()
+
+    count_stats.append(('post-', 'build'))
+    count_stats.print_stats()
 
     if print_objects:
         SCons.Debug.listLoggedInstances('*')
@@ -1139,8 +1187,8 @@ def _main(args, parser):
 
     # Dump any development debug info that may have been enabled.
     # These are purely for internal debugging during development, so
-    # there's no need to control the with --debug= options, they're
-    # controlled by changing the source code.)
+    # there's no need to control them with --debug= options; they're
+    # controlled by changing the source code.
     SCons.Debug.dump_caller_counts()
     SCons.Taskmaster.dump_stats()
 
index 07dfd5599776f8e0fd2ac5254aaca00c53b760e2..7ca99939a41b063a5748032876f4394489a7bc48 100644 (file)
@@ -117,16 +117,16 @@ def compute_exports(exports):
 
 class Frame:
     """A frame on the SConstruct/SConscript call stack"""
-    def __init__(self, exports, sconscript):
+    def __init__(self, fs, exports, sconscript):
         self.globals = BuildDefaultGlobals()
         self.retval = None
-        self.prev_dir = SCons.Node.FS.default_fs.getcwd()
+        self.prev_dir = fs.getcwd()
         self.exports = compute_exports(exports)  # exports from the calling SConscript
         # make sure the sconscript attr is a Node.
         if isinstance(sconscript, SCons.Node.Node):
             self.sconscript = sconscript
         else:
-            self.sconscript = SCons.Node.FS.default_fs.File(str(sconscript))
+            self.sconscript = fs.File(str(sconscript))
 
 # the SConstruct/SConscript call stack:
 call_stack = []
@@ -158,7 +158,7 @@ def _SConscript(fs, *files, **kw):
     # evaluate each SConscript file
     results = []
     for fn in files:
-        call_stack.append(Frame(exports,fn))
+        call_stack.append(Frame(fs, exports, fn))
         old_sys_path = sys.path
         try:
             SCons.Script.sconscript_reading = 1
index 22c75e94608542d8630eeb85a9cd901ca2235941..37115e9a1913ec43c5246e87ccf685801262adc5 100644 (file)
@@ -75,7 +75,7 @@ def generate(env):
     # calling getcwd() for itself, which is odd.  If no PWD variable
     # is present, p4 WILL call getcwd, but this seems to cause problems
     # with good ol' Win32's tilde-mangling for long file names.
-    environ['PWD'] = SCons.Node.FS.default_fs.Dir('#').get_abspath()
+    environ['PWD'] = env.Dir('#').get_abspath()
 
     for var in _import_env:
         v = os.environ.get(var)
index a721d96daa4b9b70d326df7ea2b52a3cc82e4492..b0699903a8c7663f81f311a6976ac358321b152a 100644 (file)
@@ -82,7 +82,7 @@ def jarChdir(target, source, env, for_signature):
 JarAction = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
 
 JarBuilder = SCons.Builder.Builder(action = JarAction,
-                                   source_factory = SCons.Node.FS.default_fs.Entry,
+                                   source_factory = SCons.Node.FS.Entry,
                                    suffix = '$JARSUFFIX')
 
 def generate(env):
index 8741c23a7167ae02ee96cb2decb5427f6b88fde4..44a4bd04a6f67266635845147107fab337f694f3 100644 (file)
@@ -99,8 +99,8 @@ JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
 
 JavaBuilder = SCons.Builder.Builder(action = JavaAction,
                     emitter = emit_java_classes,
-                    target_factory = SCons.Node.FS.default_fs.Dir,
-                    source_factory = SCons.Node.FS.default_fs.Dir)
+                    target_factory = SCons.Node.FS.Dir,
+                    source_factory = SCons.Node.FS.Dir)
 
 def generate(env):
     """Add Builders and construction variables for javac to an Environment."""
index 4d5749a181c119181a6734cf6900543c611e4e18..26fcc532168321c55108ec67bd8b34cc44c473b9 100644 (file)
@@ -59,7 +59,7 @@ def emit_java_headers(target, source, env):
                 classdir = s.attributes.java_classdir
             except AttributeError:
                 classdir = '.'
-    classdir = SCons.Node.FS.default_fs.Dir(classdir).rdir()
+    classdir = env.Dir(classdir).rdir()
     if str(classdir) == '.':
         c_ = None
     else:
@@ -111,8 +111,8 @@ JavaHAction = SCons.Action.Action('$JAVAHCOM', '$JAVAHCOMSTR')
 JavaHBuilder = SCons.Builder.Builder(action = JavaHAction,
                      emitter = emit_java_headers,
                      src_suffix = '$JAVACLASSSUFFIX',
-                     target_factory = SCons.Node.FS.default_fs.Entry,
-                     source_factory = SCons.Node.FS.default_fs.File)
+                     target_factory = SCons.Node.FS.Entry,
+                     source_factory = SCons.Node.FS.File)
 
 def generate(env):
     """Add Builders and construction variables for javah to an Environment."""
index 04e09f5ad3321ade98b4e53d6033da85ae0dc0f9..e03eb8d4bf2f551b9435a24bb26aef64b7402c34 100644 (file)
@@ -1049,8 +1049,8 @@ def projectEmitter(target, source, env):
     suff = env.subst('$MSVSPROJECTSUFFIX')
     target[0] = base + suff
 
-    dspfile = SCons.Node.FS.default_fs.File(target[0]).srcnode()
-    dswfile = SCons.Node.FS.default_fs.File(SCons.Util.splitext(str(dspfile))[0] + env.subst('$MSVSSOLUTIONSUFFIX'))
+    dspfile = env.File(target[0]).srcnode()
+    dswfile = env.File(SCons.Util.splitext(str(dspfile))[0] + env.subst('$MSVSSOLUTIONSUFFIX'))
 
     # XXX Need to find a way to abstract this; the build engine
     # shouldn't depend on anything in SCons.Script.
@@ -1060,7 +1060,7 @@ def projectEmitter(target, source, env):
     source[0].attributes.sconstruct = stack[0].sconscript
 
     bdswpath = SCons.Util.splitext(str(target[0]))[0] + env.subst('$MSVSSOLUTIONSUFFIX')
-    bdswfile = SCons.Node.FS.default_fs.File(bdswpath)
+    bdswfile = env.File(bdswpath)
 
     # only make these side effects if they're
     # not the same file.
index bc2d41b11e0871a7d21843416a45fb3073433879..04b6215020d335555cb073533fd716da7c7eb568 100644 (file)
@@ -107,7 +107,6 @@ class _Automoc:
             debug = 0
         
         # some shortcuts used in the scanner
-        FS = SCons.Node.FS.default_fs
         splitext = SCons.Util.splitext
         objBuilder = getattr(env, self.objBuilderName)
   
@@ -147,9 +146,7 @@ class _Automoc:
                 # try to find the header file in the corresponding source
                 # directory
                 hname = splitext(cpp.name)[0] + h_ext
-                h = find_file(hname,
-                              (cpp.get_dir(),),
-                              FS.File)
+                h = find_file(hname, (cpp.get_dir(),), env.File)
                 if h:
                     if debug:
                         print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))
index c5c4854ab50157e3ef9a08e05dd2815449fc9ecd..4b48e0b909c5947fad4a5b8f91147dd512e1da4c 100644 (file)
@@ -58,7 +58,7 @@ def emit_rmic_classes(target, source, env):
                 classdir = s.attributes.java_classdir
             except AttributeError:
                 classdir = '.'
-    classdir = SCons.Node.FS.default_fs.Dir(classdir).rdir()
+    classdir = env.Dir(classdir).rdir()
     if str(classdir) == '.':
         c_ = None
     else:
@@ -95,8 +95,8 @@ RMICAction = SCons.Action.Action('$RMICCOM', '$RMICCOMSTR')
 RMICBuilder = SCons.Builder.Builder(action = RMICAction,
                      emitter = emit_rmic_classes,
                      src_suffix = '$JAVACLASSSUFFIX',
-                     target_factory = SCons.Node.FS.default_fs.Dir,
-                     source_factory = SCons.Node.FS.default_fs.File)
+                     target_factory = SCons.Node.FS.Dir,
+                     source_factory = SCons.Node.FS.File)
 
 def generate(env):
     """Add Builders and construction variables for rmic to an Environment."""
index 079865ee36dce4627b469b9e7fad90d46a529ad0..58b755476439893fc260d710eb4edf5a5b66a947 100644 (file)
@@ -44,7 +44,7 @@ tars = ['tar', 'gtar']
 TarAction = SCons.Action.Action('$TARCOM', '$TARCOMSTR')
 
 TarBuilder = SCons.Builder.Builder(action = TarAction,
-                                   source_factory = SCons.Node.FS.default_fs.Entry,
+                                   source_factory = SCons.Node.FS.Entry,
                                    source_scanner = SCons.Defaults.DirScanner,
                                    suffix = '$TARSUFFIX',
                                    multi = 1)
index b67528bd876ae5c8e79b3cc9b4fe34467e5dbca1..fe9ce32bf32fbc5f1c0e3710d309b936961b9e74 100644 (file)
@@ -69,7 +69,7 @@ else:
 zipAction = SCons.Action.Action(zip, varlist=['ZIPCOMPRESSION'])
 
 ZipBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'),
-                                   source_factory = SCons.Node.FS.default_fs.Entry,
+                                   source_factory = SCons.Node.FS.Entry,
                                    source_scanner = SCons.Defaults.DirScanner,
                                    suffix = '$ZIPSUFFIX',
                                    multi = 1)