Warn when the user tries to set TARGET[S] or SOURCE[S] in an Environment.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 22 Feb 2003 16:17:24 +0000 (16:17 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 22 Feb 2003 16:17:24 +0000 (16:17 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@597 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Warnings.py
src/engine/SCons/WarningsTests.py

index f026b726e62a0446077ef385e7e68f29ed72d563..f76bc0152c9d693bf36a595cd5f8a6086e3ea1ec 100644 (file)
@@ -2460,6 +2460,16 @@ The prefix used for shared object file names.
 .IP SHOBJSUFFIX 
 The suffix used for shared object file names.
 
+.IP SOURCE
+A reserved variable name
+that may not be set or used in a construction environment.
+(See "Variable Substitution," below.)
+
+.IP SOURCES
+A reserved variable name
+that may not be set or used in a construction environment.
+(See "Variable Substitution," below.)
+
 .IP SPAWN
 A command interpreter function that will be called to execute command line
 strings. The function must expect 4 arguments:
@@ -2501,6 +2511,16 @@ The command line used to call the tar archiver.
 .IP TARFLAGS
 General options passed to the tar archiver.
 
+.IP TARGET
+A reserved variable name
+that may not be set or used in a construction environment.
+(See "Variable Substitution," below.)
+
+.IP TARGETS
+A reserved variable name
+that may not be set or used in a construction environment.
+(See "Variable Substitution," below.)
+
 .IP TARSUFFIX 
 The suffix used for tar file names.
 
@@ -3676,6 +3696,9 @@ first source if multiple sources are being built.
 .IP SOURCES
 The file names of the sources of the build command.
 
+(Note that the above variables are reserved
+and may not be set in a construction environment.)
+
 .LP 
 For example, given the construction variable CC='cc', targets=['foo'], and
 sources=['foo.c', 'bar.c']:
index 64708001634914a65e4f8341bf96fe6a8d2b1af6..9befe249cbd9b8f2dd45fd937ef2f4779d16f2d8 100644 (file)
@@ -28,6 +28,9 @@ RELEASE 0.12 - XXX
   - Make the error message the same as other build errors when there's a
     problem unlinking a target file in preparation for it being built.
 
+  - Make TARGET, TARGETS, SOURCE and SOURCES reserved variable names and
+    warn if the user tries to set them in a construction environment.
+
 
 
 RELEASE 0.11 - Tue, 11 Feb 2003 05:24:33 -0600
index 54c91bb912cbfd0f0a71e22275aa34eab7d750be..68571097fdd3bf7b92ad9c2d4049efaf4bbbcb2a 100644 (file)
@@ -315,7 +315,13 @@ class Environment:
        return dlist
 
     def __setitem__(self, key, value):
-        if key == 'BUILDERS':
+        if key == 'TARGET' or \
+           key == 'TARGETS' or \
+           key == 'SOURCE' or \
+           key == 'SOURCES':
+            SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning,
+                                "Ignoring attempt to set reserved variable `%s'" % key)
+        elif key == 'BUILDERS':
             try:
                 bd = self._dict[key]
                 for k in bd.keys():
index e31393948f0090276b8f1ea5c261e3641ed63d50..1163545cc87d0417ddafccc160cac8033f036fb2 100644 (file)
@@ -332,6 +332,26 @@ class EnvironmentTestCase(unittest.TestCase):
         for tnode in tgt:
             assert tnode.builder == InstallBuilder
 
+    def test_ReservedVariables(self):
+        """Test generation of warnings when reserved variable names
+        are set in an environment."""
+
+        SCons.Warnings.enableWarningClass(SCons.Warnings.ReservedVariableWarning)
+        old = SCons.Warnings.warningAsException(1)
+
+        try:
+            env4 = Environment()
+            for kw in ['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']:
+                exc_caught = None
+                try:
+                    env4[kw] = 'xyzzy'
+                except SCons.Warnings.ReservedVariableWarning:
+                    exc_caught = 1
+                assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
+                assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
+        finally:
+            SCons.Warnings.warningAsException(old)
+
     def test_Replace(self):
         """Test replacing construction variables in an Environment
 
index 30f1b0013ca4577fda8a4fee40e9f62c0dbfa986..6d75c0628d78ceb878df30fe2efb3bad81331a45 100644 (file)
@@ -43,6 +43,9 @@ class DependencyWarning(Warning):
 class CorruptSConsignWarning(Warning):
     pass
 
+class ReservedVariableWarning(Warning):
+    pass
+
 _warningAsException = 0
 
 # The below is a list of 2-tuples.  The first element is a class object.
@@ -62,8 +65,11 @@ def enableWarningClass(clazz):
     _enabled.insert(0, (clazz, 1))
 
 def warningAsException(flag=1):
+    """Turn warnings into exceptions.  Returns the old value of the flag."""
     global _warningAsException
+    old = _warningAsException
     _warningAsException = flag
+    return old
 
 def warn(clazz, *args):
     global _enabled, _warningAsException, _warningOut
index e04ffc32d04e5ad86fc37c4c344483529e19dc5a..1016fdbe5b192753629fd80e8c2e5ba605f35b4b 100644 (file)
@@ -57,16 +57,23 @@ class WarningsTestCase(unittest.TestCase):
         SCons.Warnings._warningAsException = 0
 
         SCons.Warnings.enableWarningClass(SCons.Warnings.Warning)
-        SCons.Warnings.warningAsException()
+        old = SCons.Warnings.warningAsException()
+        assert old == 0, old
+        exc_caught = 0
         try:
             SCons.Warnings.warn(SCons.Warnings.Warning, "Foo")
         except:
-            pass
-        else:
-            assert 0
+            exc_caught = 1
+        assert exc_caught == 1
 
-        SCons.Warnings.warningAsException(0)
-        SCons.Warnings.warn(SCons.Warnings.Warning, "Foo")
+        old = SCons.Warnings.warningAsException(old)
+        assert old == 1, old
+        exc_caught = 0
+        try:
+            SCons.Warnings.warn(SCons.Warnings.Warning, "Foo")
+        except:
+            exc_caught = 1
+        assert exc_caught == 0
 
     def test_Disable(self):
         """Test disabling/enabling warnings."""