From cff75e572311356bfd6d80c460c1140492a35073 Mon Sep 17 00:00:00 2001
From: Steven Knight <knight@baldmt.com>
Date: Mon, 26 Aug 2002 04:10:41 +0000
Subject: Add a Prepend() method to Environments.  (Chad Austin)

---
 doc/man/scons.1                      | 23 ++++++++++++++++++++++-
 src/CHANGES.txt                      |  5 +++++
 src/engine/SCons/Environment.py      | 18 ++++++++++++++++++
 src/engine/SCons/EnvironmentTests.py | 28 ++++++++++++++++++++++++++++
 4 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/doc/man/scons.1 b/doc/man/scons.1
index 3e4b64a..fd1b3ff 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -1136,7 +1136,7 @@ env.Alias('install', ['/usr/local/man'])
 .TP
 .RI Append( key = val ", [...])"
 Appends the specified keyword arguments
-to the construction variables in the environment.
+to the end of construction variables in the environment.
 If the Environment does not have
 the specified construction variable,
 it is simply added to the environment.
@@ -1147,6 +1147,7 @@ Otherwise, the construction variable
 and the value of the keyword argument
 are both coerced to lists,
 and the lists are added together.
+(See also the Prepend method, below.)
 
 .ES
 env.Append(CCFLAGS = ' -g', FOO = ['foo.yyy'])
@@ -1271,6 +1272,26 @@ Multiple targets can be passed in to a single call to
 .BR Precious ().
 
 .TP
+.RI Prepend( key = val ", [...])"
+Appends the specified keyword arguments
+to the beginning of construction variables in the environment.
+If the Environment does not have
+the specified construction variable,
+it is simply added to the environment.
+If the values of the construction variable
+and the keyword argument are the same type,
+then the two values will be simply added together.
+Otherwise, the construction variable
+and the value of the keyword argument
+are both coerced to lists,
+and the lists are added together.
+(See also the Append method, above.)
+
+.ES
+env.Prepend(CCFLAGS = '-g ', FOO = ['foo.yyy'])
+.EE
+
+.TP
 .RI Replace( key = val ", [...])"
 Replaces construction variables in the Environment
 with the specified keyword arguments.
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 80a0db6..1b74766 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -10,6 +10,11 @@
 
 RELEASE 0.09 - 
 
+ From Chad Austin:
+
+  - Add a Prepend() method to Environments, to append values to
+    the beginning of construction variables.
+
  From Steven Knight:
 
  - Add Repository() functionality.
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index 4a86ae6..47ab58b 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -269,6 +269,24 @@ class Environment:
                 self._dict[key] = self._dict[key] + kw[key]
         self.__updateBuildersAndScanners()
 
+    def Prepend(self, **kw):
+        """Prepend values to existing construction variables
+        in an Environment.
+        """
+        kw = our_deepcopy(kw)
+        for key in kw.keys():
+            if not self._dict.has_key(key):
+                self._dict[key] = kw[key]
+            elif SCons.Util.is_List(self._dict[key]) and not \
+                 SCons.Util.is_List(kw[key]):
+                self._dict[key] = [ kw[key] ] + self._dict[key]
+            elif SCons.Util.is_List(kw[key]) and not \
+                 SCons.Util.is_List(self._dict[key]):
+                self._dict[key] = kw[key] + [ self._dict[key] ]
+            else:
+                self._dict[key] = kw[key] + self._dict[key]
+        self.__updateBuildersAndScanners()
+
     def	Depends(self, target, dependency):
 	"""Explicity specify that 'target's depend on 'dependency'."""
         tlist = SCons.Node.arg2nodes(target, self.fs.File)
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index eefb605..8154990 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -345,6 +345,34 @@ class EnvironmentTestCase(unittest.TestCase):
         except:
             raise
 
+    def test_Prepend(self):
+        """Test prepending to construction variables in an Environment
+        """
+        import UserList
+        UL = UserList.UserList
+        env1 = Environment(AAA = 'a', BBB = 'b', CCC = 'c', DDD = 'd',
+                           EEE = ['e'], FFF = ['f'], GGG = ['g'], HHH = ['h'],
+                           III = UL(['i']), JJJ = UL(['j']),
+                           KKK = UL(['k']), LLL = UL(['l']))
+        env1.Prepend(BBB = 'B', CCC = ['C'], DDD = UL(['D']),
+                    FFF = 'F', GGG = ['G'], HHH = UL(['H']),
+                    JJJ = 'J', KKK = ['K'], LLL = UL(['L']))
+        env2 = Environment(AAA = 'a', BBB = 'Bb',
+                           CCC = ['C', 'c'], DDD = UL(['D', 'd']),
+                           EEE = ['e'], FFF = ['F', 'f'],
+                           GGG = ['G', 'g'], HHH = UL(['H', 'h']),
+                           III = UL(['i']), JJJ = UL(['J', 'j']),
+                           KKK = UL(['K', 'k']), LLL = UL(['L', 'l']))
+        assert env1 == env2, diff_env(env1, env2)
+
+        env3 = Environment(X = {'x' : 7})
+        try:
+            env3.Prepend(X = {'x' : 8})
+        except TypeError:
+            pass
+        except:
+            raise
+
     def test_Depends(self):
 	"""Test the explicit Depends method."""
 	env = Environment()
-- 
cgit v0.12