Have ParseDepends() env.subst() the specified file name. Add an only_one keyword...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 4 Jan 2005 13:23:05 +0000 (13:23 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 4 Jan 2005 13:23:05 +0000 (13:23 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1204 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py

index 16a79869f0261c668240f661ce5b815990b74dd1..417ced446eb8340cfb975590589806a95f32bf0d 100644 (file)
@@ -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.
 
index 96403f19551b9546a8603f4ccbafa9b9fa823f6f..6f8e30cff9b7fee0acb38f58416688e519cb95e3 100644 (file)
@@ -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)
index 87e2e44d77ff43568b7128628ad0d948865df976..2e65ac122810de21ed71a2a4c7d7786d8d57e361 100644 (file)
@@ -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')