diff options
Diffstat (limited to 'src/engine/SCons')
-rw-r--r-- | src/engine/SCons/Node/FS.py | 65 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 84 | ||||
-rw-r--r-- | src/engine/SCons/Sig/MD5.py | 6 |
3 files changed, 114 insertions, 41 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index ff4dfb5..c226504 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -378,9 +378,11 @@ class Entry(SCons.Node.Node): return self._exists def rexists(self): - if not hasattr(self, '_rexists'): + try: + return self._rexists + except AttributeError: self._rexists = self.rfile().exists() - return self._rexists + return self._rexists def get_parents(self): parents = SCons.Node.Node.get_parents(self) @@ -1112,25 +1114,28 @@ class File(Entry): else: return 0 - def calc_signature(self, calc, cache=None): + def calc_signature(self, calc): """ Select and calculate the appropriate build signature for a File. self - the File node calc - the signature calculation module - cache - alternate node to use for the signature cache returns - the signature """ - - if self.is_derived(): - if SCons.Sig.build_signature: - return calc.bsig(self.rfile(), self) + try: + return self._calculated_sig + except AttributeError: + if self.is_derived(): + if SCons.Sig.build_signature: + sig = self.rfile().calc_bsig(calc, self) + else: + sig = self.rfile().calc_csig(calc, self) + elif not self.rexists(): + sig = None else: - return calc.csig(self.rfile(), self) - elif not self.rexists(): - return None - else: - return calc.csig(self.rfile(), self) + sig = self.rfile().calc_csig(calc, self) + self._calculated_sig = sig + return sig def store_csig(self): self.dir.sconsign().set_csig(self.name, self.get_csig()) @@ -1208,10 +1213,14 @@ class File(Entry): # created the directory, depending on whether the -n # option was used or not. Delete the _exists and # _rexists attributes so they can be reevaluated. - if hasattr(dirnode, '_exists'): + try: delattr(dirnode, '_exists') - if hasattr(dirnode, '_rexists'): + except AttributeError: + pass + try: delattr(dirnode, '_rexists') + except AttributeError: + pass except OSError: pass @@ -1253,10 +1262,14 @@ class File(Entry): CachePush(self, None, None) SCons.Node.Node.built(self) self.found_includes = {} - if hasattr(self, '_exists'): + try: delattr(self, '_exists') - if hasattr(self, '_rexists'): + except AttributeError: + pass + try: delattr(self, '_rexists') + except AttributeError: + pass def visited(self): if self.fs.CachePath and self.fs.cache_force and os.path.exists(self.path): @@ -1321,8 +1334,10 @@ class File(Entry): except OSError, e: raise SCons.Errors.BuildError(node = self, errstr = e.strerror) - if hasattr(self, '_exists'): + try: delattr(self, '_exists') + except AttributeError: + pass else: try: self._createDir() @@ -1357,10 +1372,14 @@ class File(Entry): # created the file, depending on whether the -n # option was used or not. Delete the _exists and # _rexists attributes so they can be reevaluated. - if hasattr(self, '_exists'): + try: delattr(self, '_exists') - if hasattr(self, '_rexists'): + except AttributeError: + pass + try: delattr(self, '_rexists') + except AttributeError: + pass return Entry.exists(self) def current(self, calc): @@ -1384,14 +1403,16 @@ class File(Entry): return calc.current(self, bsig) def rfile(self): - if not hasattr(self, '_rfile'): + try: + return self._rfile + except: self._rfile = self if not self.exists(): n = self.fs.Rsearch(self.path, clazz=File, cwd=self.fs.Top) if n: self._rfile = n - return self._rfile + return self._rfile def rstr(self): return str(self.rfile()) diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index f2d77ce..43ae7c5 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -209,6 +209,14 @@ class Node: self.set_state(None) self.del_bsig() self.del_csig() + try: + delattr(self, '_calculated_sig') + except AttributeError: + pass + try: + delattr(self, '_tempbsig') + except AttributeError: + pass self.includes = None self.found_includes = {} self.implicit = None @@ -383,37 +391,63 @@ class Node: return self.env = env - def calc_signature(self, calc, cache=None): + def calc_signature(self, calc): """ Select and calculate the appropriate build signature for a node. self - the node calc - the signature calculation module - cache - alternate node to use for the signature cache returns - the signature """ - - if self.has_builder(): - if SCons.Sig.build_signature: - return calc.bsig(self, cache) + try: + return self._calculated_sig + except AttributeError: + if self.has_builder(): + if SCons.Sig.build_signature: + sig = self.calc_bsig(calc) + else: + sig = self.calc_csig(calc) + elif not self.exists(): + sig = None else: - return calc.csig(self, cache) - elif not self.exists(): - return None - else: - return calc.csig(self, cache) + sig = self.calc_csig(calc) + self._calculated_sig = sig + return sig + + def calc_bsig(self, calc, cache=None): + """Return the node's build signature, calculating it first + if necessary. + + Note that we don't save it in the "real" build signature + attribute if we have to calculate it here; the "real" build + signature only gets updated after a file is actually built. + """ + if cache is None: cache = self + try: + return cache.bsig + except AttributeError: + try: + return cache._tempbsig + except AttributeError: + cache._tempbsig = calc.bsig(self, cache) + return cache._tempbsig def get_bsig(self): """Get the node's build signature (based on the signatures of its dependency files and build information).""" - if not hasattr(self, 'bsig'): + try: + return self.bsig + except AttributeError: return None - return self.bsig def set_bsig(self, bsig): """Set the node's build signature (based on the signatures of its dependency files and build information).""" self.bsig = bsig + try: + delattr(self, '_tempbsig') + except AttributeError: + pass def store_bsig(self): """Make the build signature permanent (that is, store it in the @@ -422,14 +456,28 @@ class Node: def del_bsig(self): """Delete the bsig from this node.""" - if hasattr(self, 'bsig'): + try: delattr(self, 'bsig') + except AttributeError: + pass def get_csig(self): """Get the signature of the node's content.""" - if not hasattr(self, 'csig'): + try: + return self.csig + except AttributeError: return None - return self.csig + + def calc_csig(self, calc, cache=None): + """Return the node's content signature, calculating it first + if necessary. + """ + if cache is None: cache = self + try: + return cache.csig + except AttributeError: + cache.csig = calc.csig(self, cache) + return cache.csig def set_csig(self, csig): """Set the signature of the node's content.""" @@ -442,8 +490,10 @@ class Node: def del_csig(self): """Delete the csig from this node.""" - if hasattr(self, 'csig'): + try: delattr(self, 'csig') + except AttributeError: + pass def get_prevsiginfo(self): """Fetch the previous signature information from the diff --git a/src/engine/SCons/Sig/MD5.py b/src/engine/SCons/Sig/MD5.py index 5239dab..c50dbb7 100644 --- a/src/engine/SCons/Sig/MD5.py +++ b/src/engine/SCons/Sig/MD5.py @@ -78,9 +78,11 @@ def collect(signatures): def signature(obj): """Generate a signature for an object """ - if not hasattr(obj, 'get_contents'): + try: + contents = str(obj.get_contents()) + except AttributeError: raise AttributeError, "unable to fetch contents of '%s'" % str(obj) - return hexdigest(md5.new(str(obj.get_contents())).digest()) + return hexdigest(md5.new(contents).digest()) def to_string(signature): """Convert a signature to a string""" |