summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-04-25 19:47:31 (GMT)
committerSteven Knight <knight@baldmt.com>2004-04-25 19:47:31 (GMT)
commitae9f03ddef2d4a346bd49e10e8b033ddbf7b852a (patch)
tree8d8a4602fe35bf6d30f890c083280157cd8487da /src/engine
parentbd74d2939db1d55119af3faf56a89f07722d487a (diff)
downloadSCons-ae9f03ddef2d4a346bd49e10e8b033ddbf7b852a.zip
SCons-ae9f03ddef2d4a346bd49e10e8b033ddbf7b852a.tar.gz
SCons-ae9f03ddef2d4a346bd49e10e8b033ddbf7b852a.tar.bz2
Have SConsignFile() use a dblite.py module by default, so we can control the behavior. (Ralf W. Grosse-Kunstleve)
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/MANIFEST.in1
-rw-r--r--src/engine/SCons/Environment.py2
-rw-r--r--src/engine/SCons/EnvironmentTests.py4
-rw-r--r--src/engine/SCons/Sig/SigTests.py2
-rw-r--r--src/engine/SCons/Sig/__init__.py4
-rw-r--r--src/engine/SCons/dblite.py149
6 files changed, 158 insertions, 4 deletions
diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in
index a8bac0a..4942be8 100644
--- a/src/engine/MANIFEST.in
+++ b/src/engine/MANIFEST.in
@@ -2,6 +2,7 @@ SCons/__init__.py
SCons/Action.py
SCons/Builder.py
SCons/Conftest.py
+SCons/dblite.py
SCons/Debug.py
SCons/Defaults.py
SCons/Environment.py
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index c312f31..d214e9b 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -1153,7 +1153,7 @@ class Base:
nkw = self.subst_kw(kw)
return apply(SCons.Scanner.Base, nargs, nkw)
- def SConsignFile(self, name=".sconsign.dbm", dbm_module=None):
+ def SConsignFile(self, name=".sconsign", dbm_module=None):
name = self.subst(name)
if not os.path.isabs(name):
name = os.path.join(str(self.fs.SConstruct_dir), name)
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index 0995a05..d141d49 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -2245,6 +2245,10 @@ class EnvironmentTestCase(unittest.TestCase):
env.SConsignFile('__$BAR', 7)
assert fnames[4] == os.path.join(os.sep, 'dir', '__', 'File'), fnames
assert dbms[4] == 7, dbms
+
+ env.SConsignFile()
+ assert fnames[5] == os.path.join(os.sep, 'dir', '.sconsign'), fnames
+ assert dbms[5] == None, dbms
finally:
SCons.Sig.SConsignFile = save_Sig_SConsignFile
diff --git a/src/engine/SCons/Sig/SigTests.py b/src/engine/SCons/Sig/SigTests.py
index 98465ff..76cd931 100644
--- a/src/engine/SCons/Sig/SigTests.py
+++ b/src/engine/SCons/Sig/SigTests.py
@@ -502,7 +502,7 @@ class SConsignFileTestCase(unittest.TestCase):
SCons.Sig.SConsignFile(file)
- assert not SCons.Sig.SConsign_db is None, SCons.Sig.SConsign_db
+ assert not SCons.Sig.SConsign_db is SCons.dblite, SCons.Sig.SConsign_db
class Fake_DBM:
def open(self, name, mode):
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index d703194..6bdfe09 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -326,8 +326,8 @@ def SConsignFile(name, dbm_module=None):
global SConsign_db
if SConsign_db is None:
if dbm_module is None:
- import anydbm
- dbm_module = anydbm
+ import SCons.dblite
+ dbm_module = SCons.dblite
SConsign_db = dbm_module.open(name, "c")
global SConsignForDirectory
diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py
new file mode 100644
index 0000000..df04d80
--- /dev/null
+++ b/src/engine/SCons/dblite.py
@@ -0,0 +1,149 @@
+# dblite.py module contributed by Ralf W. Grosse-Kunstleve.
+
+import cPickle
+import time
+import shutil
+import os
+import __builtin__
+
+_open = __builtin__.open # avoid name clash
+
+keep_all_files = 00000
+ignore_corrupt_dbfiles = 0
+
+class dblite:
+
+ def __init__(self, file_base_name, flag, mode):
+ assert flag in (None, "r", "w", "c", "n")
+ if (flag is None): flag = "r"
+ if file_base_name[-7:] != '.dblite':
+ file_base_name = file_base_name + '.dblite'
+ self._file_name = file_base_name
+ self._flag = flag
+ self._mode = mode
+ self._dict = {}
+ self._needs_sync = 00000
+ if (self._flag == "n"):
+ _open(self._file_name, "wb", self._mode)
+ else:
+ try:
+ f = _open(self._file_name, "rb")
+ except IOError, e:
+ if (self._flag != "c"):
+ raise e
+ _open(self._file_name, "wb", self._mode)
+ else:
+ p = f.read()
+ if (len(p) > 0):
+ try:
+ self._dict = cPickle.loads(p)
+ except:
+ if (ignore_corrupt_dbfiles == 0): raise
+ if (ignore_corrupt_dbfiles == 1):
+ print "Warning: Discarding corrupt database:", self._file_name
+
+ def __del__(self):
+ if (self._needs_sync):
+ self.sync()
+
+ def sync(self):
+ self._check_writable()
+ f = _open(self._file_name, "wb", self._mode)
+ cPickle.dump(self._dict, f, 1)
+ f.close()
+ self._needs_sync = 00000
+ if (keep_all_files):
+ shutil.copyfile(
+ self._file_name,
+ self._file_name + "_" + str(int(time.time())))
+
+ def _check_writable(self):
+ if (self._flag == "r"):
+ raise IOError("Read-only database: %s" % self._file_name)
+
+ def __getitem__(self, key):
+ return self._dict[key]
+
+ def __setitem__(self, key, value):
+ self._check_writable()
+ if (type(key) != type("")):
+ raise TypeError, "key must be a string"
+ if (type(value) != type("")):
+ raise TypeError, "value must be a string"
+ self._dict[key] = value
+ self._needs_sync = 0001
+
+ def keys(self):
+ return self._dict.keys()
+
+ def has_key(self, key):
+ return key in self._dict
+
+ def __contains__(self, key):
+ return key in self._dict
+
+ def iterkeys(self):
+ return self._dict.iterkeys()
+
+ __iter__ = iterkeys
+
+ def __len__(self):
+ return len(self._dict)
+
+def open(file, flag=None, mode=0666):
+ return dblite(file, flag, mode)
+
+def _exercise():
+ db = open("tmp", "n")
+ assert len(db) == 0
+ db["foo"] = "bar"
+ assert db["foo"] == "bar"
+ db.sync()
+ db = open("tmp", "c")
+ assert len(db) == 1
+ assert db["foo"] == "bar"
+ db["bar"] = "foo"
+ assert db["bar"] == "foo"
+ db.sync()
+ db = open("tmp", "r")
+ assert len(db) == 2
+ assert db["foo"] == "bar"
+ assert db["bar"] == "foo"
+ try:
+ db.sync()
+ except IOError, e:
+ assert str(e) == "Read-only database: tmp.dblite"
+ else:
+ raise RuntimeError, "IOError expected."
+ db = open("tmp", "w")
+ assert len(db) == 2
+ db["ping"] = "pong"
+ db.sync()
+ db = open("tmp", "r")
+ assert len(db) == 3
+ db = open("tmp", "n")
+ assert len(db) == 0
+ _open("tmp.dblite", "w")
+ db = open("tmp", "r")
+ _open("tmp.dblite", "w").write("x")
+ try:
+ db = open("tmp", "r")
+ except cPickle.UnpicklingError:
+ pass
+ else:
+ raise RuntimeError, "cPickle exception expected."
+ global ignore_corrupt_dbfiles
+ ignore_corrupt_dbfiles = 2
+ db = open("tmp", "r")
+ assert len(db) == 0
+ os.unlink("tmp.dblite")
+ try:
+ db = open("tmp", "w")
+ except IOError, e:
+ assert str(e) == "Database does not exist: tmp.dblite"
+ else:
+ raise RuntimeError, "IOError expected."
+ print "OK"
+
+if (__name__ == "__main__"):
+ _exercise()