From: stevenknight Date: Thu, 29 Jul 2004 21:25:15 +0000 (+0000) Subject: Refactorings towards a RelativeTopDir() function. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8f3d030782082989e14f06ab98237aed6bfe11c0;p=scons.git Refactorings towards a RelativeTopDir() function. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1011 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 1cb77792..31d89461 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -286,8 +286,6 @@ class ParentOfRoot: def __init__(self): self.abspath = '' self.path = '' - self.abspath_ = '' - self.path_ = '' self.name='' self.duplicate=0 self.srcdir=None @@ -305,12 +303,15 @@ class ParentOfRoot: def get_dir(self): return None - def recurse_get_path(self, dir, path_elems): - return path_elems - def src_builder(self): return _null + def entry_abspath(self, name): + return name + + def entry_path(self, name): + return name + # Cygwin's os.path.normcase pretends it's on a case-sensitive filesystem. _is_cygwin = sys.platform == "cygwin" if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_cygwin: @@ -439,18 +440,16 @@ class Base(SCons.Node.Node): self.name = name self.fs = fs - self.relpath = {} + self.relpath = {self : '.'} assert directory, "A directory must be provided" - self.abspath = directory.abspath_ + name + self.abspath = directory.entry_abspath(name) if directory.path == '.': self.path = name else: - self.path = directory.path_ + name + self.path = directory.entry_path(name) - self.path_ = self.path - self.abspath_ = self.abspath self.dir = directory self.cwd = None # will hold the SConscript directory for target nodes self.duplicate = directory.duplicate @@ -473,7 +472,7 @@ class Base(SCons.Node.Node): delattr(self, '_str_val') except AttributeError: pass - self.relpath = {} + self.relpath = {self : '.'} def get_dir(self): return self.dir @@ -543,14 +542,6 @@ class Base(SCons.Node.Node): self._srcnode = self return self._srcnode - def recurse_get_path(self, dir, path_elems): - """Recursively build a path relative to a supplied directory - node.""" - if self != dir: - path_elems.append(self.name) - path_elems = self.dir.recurse_get_path(dir, path_elems) - return path_elems - def get_path(self, dir=None): """Return path relative to the current working directory of the Node.FS.Base object that owns us.""" @@ -559,13 +550,13 @@ class Base(SCons.Node.Node): try: return self.relpath[dir] except KeyError: - if self == dir: - # Special case, return "." as the path - ret = '.' - else: - path_elems = self.recurse_get_path(dir, []) - path_elems.reverse() - ret = string.join(path_elems, os.sep) + path_elems = [] + d = self + while d != dir and not isinstance(d, ParentOfRoot): + path_elems.append(d.name) + d = d.dir + path_elems.reverse() + ret = string.join(path_elems, os.sep) self.relpath[dir] = ret return ret @@ -783,7 +774,6 @@ class FS(LocalFS): if not self.Top: self.Top = self.__doLookup(Dir, os.path.normpath(self.pathTop)) self.Top.path = '.' - self.Top.path_ = '.' + os.sep self._cwd = self.Top def getcwd(self): @@ -832,11 +822,8 @@ class FS(LocalFS): except KeyError: if not create: raise SCons.Errors.UserError - dir = Dir(drive, ParentOfRoot(), self) - dir.path = dir.path + os.sep - dir.abspath = dir.abspath + os.sep - self.Root[drive] = dir - directory = dir + directory = RootDir(drive, ParentOfRoot(), self) + self.Root[drive] = directory path_comp = path_comp[1:] else: path_comp = [ path_first, ] + path_comp[1:] @@ -856,7 +843,7 @@ class FS(LocalFS): # look at the actual filesystem and make sure there isn't # a file already there - path = directory.path_ + path_name + path = directory.entry_path(path_name) if self.isfile(path): raise TypeError, \ "File %s found where directory expected." % path @@ -874,7 +861,7 @@ class FS(LocalFS): # make sure we don't create File nodes when there is actually # a directory at that path on the disk, and vice versa - path = directory.path_ + path_comp[-1] + path = directory.entry_path(path_comp[-1]) if fsclass == File: if self.isdir(path): raise TypeError, \ @@ -1142,8 +1129,6 @@ class Dir(Base): system tree. Specify that directories (this Node) don't use signatures for calculating whether they're current.""" - self.path_ = self.path + os.sep - self.abspath_ = self.abspath + os.sep self.repositories = [] self.srcdir = None @@ -1348,6 +1333,33 @@ class Dir(Base): stamp = kid.get_timestamp() return stamp + def entry_abspath(self, name): + return self.abspath + os.sep + name + + def entry_path(self, name): + return self.path + os.sep + name + +class RootDir(Dir): + """A class for the root directory of a file system. + + This is the same as a Dir class, except that the path separator + ('/' or '\\') is actually part of the name, so we don't need to + add a separator when creating the path names of entries within + this directory. + """ + def __init__(self, name, directory, fs): + if __debug__: logInstanceCreation(self, 'Node.FS.RootDir') + Base.__init__(self, name, directory, fs) + self.path = self.path + os.sep + self.abspath = self.abspath + os.sep + self._morph() + + def entry_abspath(self, name): + return self.abspath + name + + def entry_path(self, name): + return self.path + name + class BuildInfo: bsig = None def __cmp__(self, other): diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 4a868b90..c5d064d4 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -651,21 +651,12 @@ class FSTestCase(unittest.TestCase): assert str(dir) == path, \ "str(dir) %s != expected path %s" % \ (str(dir), path) - assert dir.path_ == path_, \ - "dir.path_ %s != expected path_ %s" % \ - (dir.path_, path_) assert dir.get_abspath() == abspath, \ "dir.abspath %s != expected absolute path %s" % \ (dir.get_abspath(), abspath) - assert dir.abspath_ == abspath_, \ - "dir.abspath_ %s != expected absolute path_ %s" % \ - (dir.abspath_, abspath_) assert dir.up().path == up_path, \ "dir.up().path %s != expected parent path %s" % \ (dir.up().path, up_path) - assert dir.up().path_ == up_path_, \ - "dir.up().path_ %s != expected parent path_ %s" % \ - (dir.up().path_, up_path_) Dir_test('foo', 'foo/', sub_dir_foo, './') Dir_test('foo/bar', 'foo/bar/', sub_dir_foo_bar, 'foo/') @@ -733,19 +724,13 @@ class FSTestCase(unittest.TestCase): os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2'), os.path.join('ddd', 'f3')], kids - kids = map(lambda x: x.path_, dir.children(None)) - kids.sort() - assert kids == [os.path.join('ddd', 'd1', ''), - os.path.join('ddd', 'f1'), - os.path.join('ddd', 'f2'), - os.path.join('ddd', 'f3')], kids # Test for a bug in 0.04 that did not like looking up # dirs with a trailing slash on Win32. d=fs.Dir('./') - assert d.path_ == '.' + os.sep, d.abspath_ + assert d.path == '.', d.abspath d=fs.Dir('foo/') - assert d.path_ == 'foo' + os.sep, d.path_ + assert d.path == 'foo', d.abspath # Test for sub-classing of node building. global built_it @@ -773,56 +758,47 @@ class FSTestCase(unittest.TestCase): e1 = fs.Entry("d1") assert e1.__class__.__name__ == 'Dir' match(e1.path, "d1") - match(e1.path_, "d1/") match(e1.dir.path, ".") e2 = fs.Entry("d1/f1") assert e2.__class__.__name__ == 'File' match(e2.path, "d1/f1") - match(e2.path_, "d1/f1") match(e2.dir.path, "d1") e3 = fs.Entry("e3") assert e3.__class__.__name__ == 'Entry' match(e3.path, "e3") - match(e3.path_, "e3") match(e3.dir.path, ".") e4 = fs.Entry("d1/e4") assert e4.__class__.__name__ == 'Entry' match(e4.path, "d1/e4") - match(e4.path_, "d1/e4") match(e4.dir.path, "d1") e5 = fs.Entry("e3/e5") assert e3.__class__.__name__ == 'Dir' match(e3.path, "e3") - match(e3.path_, "e3/") match(e3.dir.path, ".") assert e5.__class__.__name__ == 'Entry' match(e5.path, "e3/e5") - match(e5.path_, "e3/e5") match(e5.dir.path, "e3") e6 = fs.Dir("d1/e4") assert e6 is e4 assert e4.__class__.__name__ == 'Dir' match(e4.path, "d1/e4") - match(e4.path_, "d1/e4/") match(e4.dir.path, "d1") e7 = fs.File("e3/e5") assert e7 is e5 assert e5.__class__.__name__ == 'File' match(e5.path, "e3/e5") - match(e5.path_, "e3/e5") match(e5.dir.path, "e3") fs.chdir(fs.Dir('subdir')) f11 = fs.File("f11") match(f11.path, "subdir/f11") d12 = fs.Dir("d12") - match(d12.path_, "subdir/d12/") e13 = fs.Entry("subdir/e13") match(e13.path, "subdir/subdir/e13") fs.chdir(fs.Dir('..')) @@ -834,13 +810,13 @@ class FSTestCase(unittest.TestCase): f1.target_scanner = Scanner(xyz) f1.scan() - assert f1.implicit[0].path_ == "xyz" + assert f1.implicit[0].path == "xyz" f1.implicit = [] f1.scan() assert f1.implicit == [] f1.implicit = None f1.scan() - assert f1.implicit[0].path_ == "xyz" + assert f1.implicit[0].path == "xyz" # Test underlying scanning functionality in get_found_includes() env = Environment() diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 0cda8c1e..80871367 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -61,13 +61,13 @@ SCons.Warnings.enableWarningClass( SConfWarning ) # action to create the source def _createSource( target, source, env ): - fd = open(target[0].get_path(), "w") + fd = open(str(target[0]), "w") fd.write(env['SCONF_TEXT']) fd.close() def _stringSource( target, source, env ): import string - return (target[0].get_path() + ' <- \n |' + + return (str(target[0]) + ' <- \n |' + string.replace( env['SCONF_TEXT'], "\n", "\n |" ) ) BooleanTypes = [types.IntType] @@ -332,8 +332,9 @@ class SConf: ok = self.TryLink(text, extension) if( ok ): prog = self.lastTarget - output = SConfFS.File(prog.get_path()+'.out') - node = self.env.Command(output, prog, [ [ prog.get_path(), ">", "${TARGET}"] ]) + pname = str(prog) + output = SConfFS.File(pname+'.out') + node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ]) ok = self.BuildNodes([node]) if ok: outputStr = output.get_contents() @@ -377,21 +378,22 @@ class SConf: if node.get_state() != SCons.Node.up_to_date: # if any of the sources has changed, we cannot use our cache needs_rebuild = 1 - if not self.cache.has_key( target[0].get_path() ): + tname = str(target[0]) + if not self.cache.has_key( tname ): # We have no recorded error, so we try to build the target needs_rebuild = 1 else: - lastBuildSig = self.cache[target[0].get_path()]['builder'] + lastBuildSig = self.cache[tname]['builder'] if lastBuildSig != buildSig: needs_rebuild = 1 if not needs_rebuild: # When we are here, we can savely pass the recorded error print ('(cached): Building "%s" failed in a previous run.' % - target[0].get_path()) + target[0]) return 1 else: # Otherwise, we try to record an error - self.cache[target[0].get_path()] = { + self.cache[tname] = { 'builder' : buildSig } @@ -399,7 +401,7 @@ class SConf: # Action after target is successfully built # # No error during build -> remove the recorded error - del self.cache[target[0].get_path()] + del self.cache[str(target[0])] def _stringCache(self, target, source, env): return None @@ -407,7 +409,7 @@ class SConf: def _loadCache(self): # try to load build-error cache try: - cacheDesc = cPickle.load(open(self.confdir.File(".cache").get_path())) + cacheDesc = cPickle.load(open(str(self.confdir.File(".cache")))) if cacheDesc['scons_version'] != SCons.__version__: raise Exception, "version mismatch" self.cache = cacheDesc['data'] @@ -423,14 +425,14 @@ class SConf: try: cacheDesc = {'scons_version' : SCons.__version__, 'data' : self.cache } - cPickle.dump(cacheDesc, open(self.confdir.File(".cache").get_path(),"w")) + cPickle.dump(cacheDesc, open(str(self.confdir.File(".cache")),"w")) except Exception, e: # this is most likely not only an IO error, but an error # inside SConf ... SCons.Warnings.warn( SConfWarning, "Couldn't dump SConf cache" ) def _createDir( self, node ): - dirName = node.get_path() + dirName = str(node) if dryrun: if not os.path.isdir( dirName ): raise SCons.Errors.ConfigureDryRunError(dirName) @@ -459,7 +461,7 @@ class SConf: log_mode = "w" else: log_mode = "a" - self.logstream = open(self.logfile.get_path(), log_mode) + self.logstream = open(str(self.logfile), log_mode) # logfile may stay in a build directory, so we tell # the build system not to override it with a eventually # existing file with the same name in the source directory @@ -468,7 +470,7 @@ class SConf: tb = traceback.extract_stack()[-3] self.logstream.write( '\nfile %s,line %d:\n\tConfigure( confdir = %s )\n\n' % - (tb[0], tb[1], self.confdir.get_path()) ) + (tb[0], tb[1], str(self.confdir)) ) else: self.logstream = None # we use a special builder to create source files from TEXT