Allow SConsignFile() to take a dbm module argument; portability fixes. (Ralf W....
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 18 Oct 2003 19:22:25 +0000 (19:22 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 18 Oct 2003 19:22:25 +0000 (19:22 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@821 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Executor.py
src/engine/SCons/ExecutorTests.py
src/engine/SCons/Job.py
src/engine/SCons/JobTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Sig/SigTests.py
src/engine/SCons/Sig/__init__.py

index 1ab7499c6c4fb66c298c19cc7a3c6d91fbc7b6c5..6e81a3e330793b022a030277f6dc14b9abeb2e5a 100644 (file)
@@ -56,6 +56,9 @@ RELEASE X.XX - XXX
 
   - Accomodate anydbm modules that don't have a sync() method.
 
+  - Allow SConsignFile() to take an argument specifying the DBM
+    module to be used.
+
   From Stephen Kennedy:
 
   - Add support for a configurable global .sconsign.dbm file which
@@ -118,6 +121,11 @@ RELEASE X.XX - XXX
 
   - Remove the long-obsolete {Get,Set}CommandHandler() functions.
 
+  - Enhance env.Append() to suppress null values when appropriate.
+
+  - Fix ParseConfig() so it works regardless of initial construction
+    variable values.
+
   From Clark McGrew:
 
   - Generalize the action for .tex files so that it will decide whether
index f8ff6c35f49b1a2a7c4be978e27a356f31796bbe..e320f0580397d8a88311fb4c232acb0f6b8dad05 100644 (file)
@@ -427,10 +427,14 @@ class Base:
                 self._dict[key] = kw[key]
             elif SCons.Util.is_List(self._dict[key]) and not \
                  SCons.Util.is_List(kw[key]):
-                self._dict[key] = self._dict[key] + [ kw[key] ]
+                if not kw[key] is None and kw[key] != '':
+                    self._dict[key] = self._dict[key] + [ kw[key] ]
             elif SCons.Util.is_List(kw[key]) and not \
                  SCons.Util.is_List(self._dict[key]):
-                self._dict[key] = [ self._dict[key] ] + kw[key]
+                if self._dict[key] is None or self._dict[key] == '':
+                    self._dict[key] = kw[key]
+                else:
+                    self._dict[key] = [ self._dict[key] ] + kw[key]
             elif SCons.Util.is_Dict(self._dict[key]) and \
                  SCons.Util.is_Dict(kw[key]):
                 self._dict[key].update(kw[key])
@@ -549,34 +553,30 @@ class Base:
 
         # the default parse function
         def parse_conf(env, output):
-            env_dict = env.Dictionary()
+            dict = {
+                'CPPPATH' : [],
+                'LIBPATH' : [],
+                'LIBS'    : [],
+                'CCFLAGS' : [],
+            }
             static_libs = []
     
-            # setup all the dictionary options
-            if not env_dict.has_key('CPPPATH'):
-                env_dict['CPPPATH'] = []
-            if not env_dict.has_key('LIBPATH'):
-                env_dict['LIBPATH'] = []
-            if not env_dict.has_key('LIBS'):
-                env_dict['LIBS'] = []
-            if not env_dict.has_key('CCFLAGS') or env_dict['CCFLAGS'] == "":
-                env_dict['CCFLAGS'] = []
-    
             params = string.split(output)
             for arg in params:
                 switch = arg[0:1]
                 opt = arg[1:2]
                 if switch == '-':
                     if opt == 'L':
-                        env_dict['LIBPATH'].append(arg[2:])
+                        dict['LIBPATH'].append(arg[2:])
                     elif opt == 'l':
-                        env_dict['LIBS'].append(arg[2:])
+                        dict['LIBS'].append(arg[2:])
                     elif opt == 'I':
-                        env_dict['CPPPATH'].append(arg[2:])
+                        dict['CPPPATH'].append(arg[2:])
                     else:
-                        env_dict['CCFLAGS'].append(arg)
+                        dict['CCFLAGS'].append(arg)
                 else:
                     static_libs.append(arg)
+            apply(env.Append, (), dict)
             return static_libs
     
         if function is None:
@@ -940,11 +940,11 @@ class Base:
         nkw = self.subst_kw(kw)
         return apply(SCons.Scanner.Base, nargs, nkw)
 
-    def SConsignFile(self, name=".sconsign.dbm"):
+    def SConsignFile(self, name=".sconsign.dbm", dbm_module=None):
         name = self.subst(name)
         if not os.path.isabs(name):
             name = os.path.join(str(self.fs.SConstruct_dir), name)
-        SCons.Sig.SConsignFile(name)
+        SCons.Sig.SConsignFile(name, dbm_module)
 
     def SideEffect(self, side_effect, target):
         """Tell scons that side_effects are built as side 
index 49d6ac72017d9d435b2459a0999e51f1ae0c25bb..2ad0a329a6eafc04fdce141b5aa766b1e7e3363a 100644 (file)
@@ -724,20 +724,58 @@ class EnvironmentTestCase(unittest.TestCase):
         
         import UserList
         UL = UserList.UserList
-        env1 = Environment(AAA = 'a', BBB = 'b', CCC = 'c', DDD = 'd',
-                           EEE = ['e'], FFF = ['f'], GGG = ['g'], HHH = ['h'],
-                           III = UL(['i']), JJJ = UL(['j']),
-                           KKK = UL(['k']), LLL = UL(['l']))
-        env1.Append(BBB = 'B', CCC = ['C'], DDD = UL(['D']),
-                    FFF = 'F', GGG = ['G'], HHH = UL(['H']),
-                    JJJ = 'J', KKK = ['K'], LLL = UL(['L']))
-        env2 = Environment(AAA = 'a', BBB = 'bB',
-                           CCC = ['c', 'C'], DDD = UL(['d', 'D']),
-                           EEE = ['e'], FFF = ['f', 'F'],
-                           GGG = ['g', 'G'], HHH = UL(['h', 'H']),
-                           III = UL(['i']), JJJ = UL(['j', 'J']),
-                           KKK = UL(['k', 'K']), LLL = UL(['l', 'L']))
-        assert env1 == env2, diff_env(env1, env2)
+        env1 = Environment(AAA = 'a',
+                           AAA1 = 'a1', AAA2 = 'a2', AAA3 = 'a3',
+                           EEE = ['e'],
+                           EEE1 = ['e1'], EEE2 = ['e2'], EEE3 = ['e3'],
+                           III = UL(['i']),
+                           III1 = UL(['i1']), III2 = UL(['i2']), III3 = UL(['i3']),
+                           MMM = '',
+                           MMM1 = '', MMM2 = '', MMM3 = '',
+                           NNN = [],
+                           NNN1 = [], NNN2 = [], NNN3 = [],
+                           OOO = UL([]),
+                           OOO1 = UL([]), OOO2 = UL([]), OOO3 = UL([]),
+                           PPP = [''],
+                           PPP1 = [''], PPP2 = [''], PPP3 = [''],
+                           QQQ = UL(['']),
+                           QQQ1 = UL(['']), QQQ2 = UL(['']), QQQ3 = UL(['']))
+        env1.Append(AAA1 = 'A1', AAA2 = ['A2'], AAA3 = UL(['A3']),
+                    EEE1 = 'E1', EEE2 = ['E2'], EEE3 = UL(['E3']),
+                    III1 = 'I1', III2 = ['I2'], III3 = UL(['I3']),
+                    MMM1 = 'M1', MMM2 = ['M2'], MMM3 = UL(['M3']),
+                    NNN1 = 'N1', NNN2 = ['N2'], NNN3 = UL(['N3']),
+                    OOO1 = 'O1', OOO2 = ['O2'], OOO3 = UL(['O3']),
+                    PPP1 = 'P1', PPP2 = ['P2'], PPP3 = UL(['P3']),
+                    QQQ1 = 'Q1', QQQ2 = ['Q2'], QQQ3 = UL(['Q3']))
+        assert env1['AAA'] == 'a', env1['AAA']
+        assert env1['AAA1'] == 'a1A1', env1['AAA1']
+        assert env1['AAA2'] == ['a2', 'A2'], env1['AAA2']
+        assert env1['AAA3'] == UL(['a3', 'A3']), env1['AAA3']
+        assert env1['EEE'] == ['e'], env1['EEE']
+        assert env1['EEE1'] == ['e1', 'E1'], env1['EEE1']
+        assert env1['EEE2'] == ['e2', 'E2'], env1['EEE2']
+        assert env1['EEE3'] == UL(['e3', 'E3']), env1['EEE3']
+        assert env1['III'] == UL(['i']), env1['III']
+        assert env1['III1'] == UL(['i1', 'I1']), env1['III1']
+        assert env1['III2'] == UL(['i2', 'I2']), env1['III2']
+        assert env1['III3'] == UL(['i3', 'I3']), env1['III3']
+        assert env1['MMM'] == '', env1['MMM']
+        assert env1['MMM1'] == 'M1', env1['MMM1']
+        assert env1['MMM2'] == ['M2'], env1['MMM2']
+        assert env1['MMM3'] == UL(['M3']), env1['MMM3']
+        assert env1['NNN1'] == ['N1'], env1['NNN1']
+        assert env1['NNN2'] == ['N2'], env1['NNN2']
+        assert env1['NNN3'] == UL(['N3']), env1['NNN3']
+        assert env1['OOO1'] == ['O1'], env1['OOO1']
+        assert env1['OOO2'] == ['O2'], env1['OOO2']
+        assert env1['OOO3'] == UL(['O3']), env1['OOO3']
+        assert env1['PPP1'] == ['', 'P1'], env1['PPP1']
+        assert env1['PPP2'] == ['', 'P2'], env1['PPP2']
+        assert env1['PPP3'] == UL(['', 'P3']), env1['PPP3']
+        assert env1['QQQ1'] == UL(['', 'Q1']), env1['QQQ1']
+        assert env1['QQQ2'] == UL(['', 'Q2']), env1['QQQ2']
+        assert env1['QQQ3'] == UL(['', 'Q3']), env1['QQQ3']
 
         env3 = Environment(X = {'x1' : 7})
         env3.Append(X = {'x1' : 8, 'x2' : 9}, Y = {'y1' : 10})
@@ -946,7 +984,11 @@ class EnvironmentTestCase(unittest.TestCase):
 
     def test_ParseConfig(self):
         """Test the ParseConfig() method"""
-        env = Environment(COMMAND='command')
+        env = Environment(COMMAND='command',
+                          CPPPATH='string',
+                          LIBPATH=['list'],
+                          LIBS='',
+                          CCFLAGS=[''])
         save_command = []
         orig_popen = os.popen
         def my_popen(command, save_command=save_command):
@@ -961,10 +1003,10 @@ class EnvironmentTestCase(unittest.TestCase):
             libs = env.ParseConfig("fake $COMMAND")
             assert save_command == ['fake command'], save_command
             assert libs == ['abc'], libs
-            assert env['CPPPATH'] == ['/usr/include/fum', 'bar'], env['CPPPATH']
-            assert env['LIBPATH'] == ['/usr/fax', 'foo'], env['LIBPATH']
+            assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH']
+            assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH']
             assert env['LIBS'] == ['xxx'], env['LIBS']
-            assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
+            assert env['CCFLAGS'] == ['', '-X'], env['CCFLAGS']
         finally:
             os.popen = orig_popen
 
@@ -1723,27 +1765,34 @@ class EnvironmentTestCase(unittest.TestCase):
         env.fs = MyFS()
 
         try:
-            save = []
-            def capture(name, save=save):
-                save.append(name)
+            fnames = []
+            dbms = []
+            def capture(name, dbm_module, fnames=fnames, dbms=dbms):
+                fnames.append(name)
+                dbms.append(dbm_module)
 
             save_Sig_SConsignFile = SCons.Sig.SConsignFile
             SCons.Sig.SConsignFile = capture
 
             env.SConsignFile('foo')
-            assert save[0] == os.path.join(os.sep, 'dir', 'foo'), save
+            assert fnames[0] == os.path.join(os.sep, 'dir', 'foo'), fnames
+            assert dbms[0] == None, dbms
 
             env.SConsignFile('$FOO')
-            assert save[1] == os.path.join(os.sep, 'dir', 'SConsign'), save
+            assert fnames[1] == os.path.join(os.sep, 'dir', 'SConsign'), fnames
+            assert dbms[1] == None, dbms
 
             env.SConsignFile('/$FOO')
-            assert save[2] == '/SConsign', save
+            assert fnames[2] == '/SConsign', fnames
+            assert dbms[2] == None, dbms
 
-            env.SConsignFile('$BAR')
-            assert save[3] == os.path.join(os.sep, 'File'), save
+            env.SConsignFile('$BAR', 'x')
+            assert fnames[3] == os.path.join(os.sep, 'File'), fnames
+            assert dbms[3] == 'x', dbms
 
-            env.SConsignFile('__$BAR')
-            assert save[4] == os.path.join(os.sep, 'dir', '__', 'File'), save
+            env.SConsignFile('__$BAR', 7)
+            assert fnames[4] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
+            assert dbms[4] == 7, dbms
         finally:
             SCons.Sig.SConsignFile = save_Sig_SConsignFile
 
index 2b4e634fb06a1a1c470905c0732b009518b8c045..12dfcc7e918c70d7637076c6953dd56b2a3720c9 100644 (file)
@@ -138,4 +138,4 @@ class Executor:
         course (only files do), but this is the interface used by the
         timestamp module.
         """
-        return None
+        return 0
index 6af5794f089e8fd1064f3bfb1c31ff8575852070..6ead30687a7cd37a5766e995bfa893991810dccd 100644 (file)
@@ -160,7 +160,7 @@ class ExecutorTestCase(unittest.TestCase):
         """Test fetching the "timestamp" """
         x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2'])
         ts = x.get_timestamp()
-        assert ts is None, ts
+        assert ts == 0, ts
 
 
 if __name__ == "__main__":
index 0c01b852bacd1e7075379f86bb9fe3ca60852ac1..b5296dc824ca0ec2978b6cd343fcd6fa0f6475d8 100644 (file)
@@ -136,9 +136,9 @@ class Worker(threading.Thread):
             try:
                 task.execute()
             except:
-                ok = False
+                ok = 0
             else:
-                ok = True
+                ok = 1
 
             self.resultsQueue.put((task, ok))
 
@@ -147,8 +147,8 @@ class ThreadPool:
 
     def __init__(self, num):
         """Create the request and reply queues, and 'num' worker threads."""
-        self.requestQueue = Queue.Queue()
-        self.resultsQueue = Queue.Queue()
+        self.requestQueue = Queue.Queue(0)
+        self.resultsQueue = Queue.Queue(0)
 
         # Create worker threads
         for i in range(num):
@@ -165,7 +165,7 @@ class ThreadPool:
     def get_nowait(self):
         """Remove and result a result tuple from the results queue 
         without blocking."""
-        return self.get(False)
+        return self.get(0)
 
 class Parallel:
     """This class is used to execute tasks in parallel, and is somewhat 
index 2c8402852429a2717766fe938732fe5241734071..1b09fd646419ec70b31c0f6b76587f7fa8d9659b 100644 (file)
@@ -172,9 +172,9 @@ class Taskmaster:
 
     def is_blocked(self):
         if self.stop or self.all_tasks_are_executed():
-            return False
+            return 0
         if self.all_tasks_are_iterated():
-            return True
+            return 1
         # simulate blocking tasks
         return self.num_iterated - self.num_executed >= max(num_jobs/2, 2)
 
index d93a6a49c43c319922a3527cd5e059baf9fa5cdd..b183a8812a8e8dd48fece894994fe0a72d0a1e3c 100644 (file)
@@ -912,7 +912,7 @@ class DummyExecutor:
     def get_contents(self):
         return ''
     def get_timestamp(self):
-        return None
+        return 0
 
 class Dir(Base):
     """A class for directories in a file system.
@@ -1148,7 +1148,7 @@ class Dir(Base):
 
     def get_timestamp(self):
         """Return the latest timestamp from among our children"""
-        stamp = None
+        stamp = 0
         for kid in self.children(None):
             if kid.get_timestamp() > stamp:
                 stamp = kid.get_timestamp()
index 53e2013b2f8443c0e3f1658a011be230debd292f..2237959e326d027d6e950751d20e5906b73b4112 100644 (file)
@@ -985,6 +985,27 @@ class FSTestCase(unittest.TestCase):
         finally:
             test.unlink("tstamp")
 
+        test.subdir('tdir1')
+        d = fs.Dir('tdir1')
+        t = d.get_timestamp()
+        assert t == 0, "expected 0, got %s" % str(t)
+
+        test.subdir('tdir2')
+        d = fs.Dir('tdir2')
+        f1 = test.workpath('tdir2', 'file1')
+        f2 = test.workpath('tdir2', 'file2')
+        test.write(f1, 'file1\n')
+        test.write(f2, 'file2\n')
+        fs.File(f1)
+        fs.File(f2)
+        current_time = float(int(time.time() / 2) * 2)
+        t1 = current_time - 4.0
+        t2 = current_time - 2.0
+        os.utime(f1, (t1 - 2.0, t1))
+        os.utime(f2, (t2 - 2.0, t2))
+        t = d.get_timestamp()
+        assert t == t2, "expected %f, got %f" % (t2, t)
+
         #XXX test get_prevsiginfo()
 
         skey = fs.Entry('eee.x').scanner_key()
index c82d2c5fe59dad087c8871c8701fb6c4eee06e44..f297464d876d55a74deb44e71b2f252ebeb62054 100644 (file)
@@ -490,6 +490,41 @@ class SConsignDirFileTestCase(unittest.TestCase):
         assert f.get('foo') == (3, 1, 2)
         assert f.get_implicit('foo') == ['bar']
 
+class SConsignFileTestCase(unittest.TestCase):
+
+    def runTest(self):
+        test = TestCmd.TestCmd(workdir = '')
+        file = test.workpath('sconsign_file')
+
+        assert SCons.Sig.SConsign_db is None, SCons.Sig.SConsign_db
+
+        SCons.Sig.SConsignFile(file)
+
+        assert not SCons.Sig.SConsign_db is None, SCons.Sig.SConsign_db
+
+        class Fake_DBM:
+            def open(self, name, mode):
+                self.name = name
+                self.mode = mode
+                return self
+
+        fake_dbm = Fake_DBM()
+
+        SCons.Sig.SConsignFile(file, fake_dbm)
+
+        assert not SCons.Sig.SConsign_db is None, SCons.Sig.SConsign_db
+        assert not hasattr(fake_dbm, 'name'), fake_dbm
+        assert not hasattr(fake_dbm, 'mode'), fake_dbm
+
+        SCons.Sig.SConsign_db = None
+
+        SCons.Sig.SConsignFile(file, fake_dbm)
+
+        assert not SCons.Sig.SConsign_db is None, SCons.Sig.SConsign_db
+        assert fake_dbm.name == file, fake_dbm.name
+        assert fake_dbm.mode == "c", fake_dbm.mode
+
+
 
 def suite():
     suite = unittest.TestSuite()
@@ -500,6 +535,7 @@ def suite():
     suite.addTest(_SConsignTestCase())
     suite.addTest(SConsignDBTestCase())
     suite.addTest(SConsignDirFileTestCase())
+    suite.addTest(SConsignFileTestCase())
     return suite
 
 if __name__ == "__main__":
index 4898f29ed8ab40bbbf00a8238cd2a2e0bce45434..dfddf34114eda1f62dd607663239ec1d9d6e6194 100644 (file)
@@ -301,15 +301,17 @@ class SConsignDirFile(SConsignDir):
 
 SConsignForDirectory = SConsignDirFile
 
-def SConsignFile(name):
+def SConsignFile(name, dbm_module=None):
     """
     Arrange for all signatures to be stored in a global .sconsign.dbm
     file.
     """
     global SConsign_db
     if SConsign_db is None:
-        import anydbm
-        SConsign_db = anydbm.open(name, "c")
+        if dbm_module is None:
+            import anydbm
+            dbm_module = anydbm
+        SConsign_db = dbm_module.open(name, "c")
 
     global SConsignForDirectory
     SConsignForDirectory = SConsignDB