summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2005-01-04 13:23:05 (GMT)
committerSteven Knight <knight@baldmt.com>2005-01-04 13:23:05 (GMT)
commitd93f05865083c27a642cb2db5fe0729e550cccfe (patch)
treebb3d22ae7ad6c96ff18ec746a6d676807dfb05fc
parent916ed5005004b8beeaf07da497066853c7821755 (diff)
downloadSCons-d93f05865083c27a642cb2db5fe0729e550cccfe.zip
SCons-d93f05865083c27a642cb2db5fe0729e550cccfe.tar.gz
SCons-d93f05865083c27a642cb2db5fe0729e550cccfe.tar.bz2
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.
-rw-r--r--doc/man/scons.126
-rw-r--r--src/engine/SCons/Environment.py20
-rw-r--r--src/engine/SCons/EnvironmentTests.py45
3 files changed, 79 insertions, 12 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index 16a7986..417ced4 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 96403f1..6f8e30c 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 87e2e44..2e65ac1 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')