From: stevenknight Date: Tue, 4 Jan 2005 13:23:05 +0000 (+0000) Subject: Have ParseDepends() env.subst() the specified file name. Add an only_one keyword... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=97db220b1c5758008bb6ffa5ea3b3752c0ec83db;p=scons.git Have ParseDepends() env.subst() the specified file name. Add an only_one keyword argument that will sanity check that the file only contains one dependency target. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1204 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 16a79869..417ced44 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -3318,7 +3318,7 @@ construction variable. .TP .RI ParseDepends( filename ", [" must_exist ]) .TP -.RI env.ParseDepends( filename ", [" must_exist ]) +.RI env.ParseDepends( filename ", [" must_exist " " only_one ]) Parses the contents of the specified .I filename as a list of dependencies in the style of @@ -3326,6 +3326,7 @@ as a list of dependencies in the style of or .BR mkdep , and explicitly establishes all of the listed dependencies. + By default, it is not an error if the specified @@ -3339,13 +3340,34 @@ scons throw an exception and generate an error if the file does not exist, or is otherwise inaccessible. + +The optional +.I only_one +argument may be set to a non-zero +value to have +scons +thrown an exception and +generate an error +if the file contains dependency +information for more than one target. +This can provide a small sanity check +for files intended to be generated +by, for example, the +.B gcc -M +flag, +which should typically only +write dependency information for +one output file into a corresponding +.B .d +file. + The .I filename and all of the files listed therein will be interpreted relative to the directory of the .I SConscript -file which called the +file which calls the .B ParseDepends function. diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 96403f19..6f8e30cf 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -862,7 +862,7 @@ class Base(SubstitutionEnvironment): command = self.subst(command) return function(self, os.popen(command).read()) - def ParseDepends(self, filename, must_exist=None): + def ParseDepends(self, filename, must_exist=None, only_one=0): """ Parse a mkdep-style file for explicit dependencies. This is completely abusable, and should be unnecessary in the "normal" @@ -872,25 +872,33 @@ class Base(SubstitutionEnvironment): that can write a .d file, but for which writing a scanner would be too complicated. """ + filename = self.subst(filename) try: fp = open(filename, 'r') except IOError: if must_exist: raise return - for line in SCons.Util.LogicalLines(fp).readlines(): - if line[0] == '#': - continue + lines = SCons.Util.LogicalLines(fp).readlines() + lines = filter(lambda l: l[0] != '#', lines) + tdlist = [] + for line in lines: try: target, depends = string.split(line, ':', 1) except (AttributeError, TypeError, ValueError): # Python 1.5.2 throws TypeError if line isn't a string, # Python 2.x throws AttributeError because it tries - # to call line.splite(). Either can throw ValueError + # to call line.split(). Either can throw ValueError # if the line doesn't split into two or more elements. pass else: - self.Depends(string.split(target), string.split(depends)) + tdlist.append((string.split(target), string.split(depends))) + if only_one: + targets = reduce(lambda x, y: x+y, map(lambda p: p[0], tdlist)) + if len(targets) > 1: + raise SCons.Errors.UserError, "More than one dependency target found in `%s': %s" % (filename, targets) + for target, depends in tdlist: + self.Depends(target, depends) def Platform(self, platform): platform = self.subst(platform) diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 87e2e44d..2e65ac12 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -1463,11 +1463,19 @@ def exists(env): def test_ParseDepends(self): """Test the ParseDepends() method""" - env = Environment() - test = TestCmd.TestCmd(workdir = '') - test.write('mkdep', """ + test.write('single', """ +#file: dependency + +f0: \ + d1 \ + d2 \ + d3 \ + +""") + + test.write('multiple', """ f1: foo f2 f3: bar f4: abc def @@ -1478,6 +1486,8 @@ f5: \ mno \ """) + env = Environment(SINGLE = test.workpath('single')) + tlist = [] dlist = [] def my_depends(target, dependency, tlist=tlist, dlist=dlist): @@ -1486,13 +1496,40 @@ f5: \ env.Depends = my_depends - env.ParseDepends(test.workpath('mkdep')) + env.ParseDepends(test.workpath('does_not_exist')) + + exc_caught = None + try: + env.ParseDepends(test.workpath('does_not_exist'), must_exist=1) + except IOError: + exc_caught = 1 + assert exc_caught, "did not catch expected IOError" + del tlist[:] + del dlist[:] + + env.ParseDepends('$SINGLE', only_one=1) + t = map(str, tlist) + d = map(str, dlist) + assert t == ['f0'], t + assert d == ['d1', 'd2', 'd3'], d + + del tlist[:] + del dlist[:] + + env.ParseDepends(test.workpath('multiple')) t = map(str, tlist) d = map(str, dlist) assert t == ['f1', 'f2', 'f3', 'f4', 'f5'], t assert d == ['foo', 'bar', 'abc', 'def', 'ghi', 'jkl', 'mno'], d + exc_caught = None + try: + env.ParseDepends(test.workpath('multiple'), only_one=1) + except SCons.Errors.UserError: + exc_caught = 1 + assert exc_caught, "did not catch expected UserError" + def test_Platform(self): """Test the Platform() method""" env = Environment(WIN32='win32', NONE='no-such-platform')