Add a Split() function (like argmunge()) in anticipation of removing the automatic...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 2 May 2002 13:40:38 +0000 (13:40 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 2 May 2002 13:40:38 +0000 (13:40 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@355 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/RELEASE.txt
src/engine/SCons/Builder.py
src/engine/SCons/Node/__init__.py
src/engine/SCons/Script/SConscript.py
src/engine/SCons/Util.py
src/engine/SCons/UtilTests.py
test/Split.py [new file with mode: 0644]

index 3fcfc8053fc917420c223eb4b9a35eb2bd0720a1..a716147d9476f29e9b93da281f5123c498d3684a 100644 (file)
@@ -33,7 +33,7 @@
 .RE
 .fi
 ..
-.TH SCONS 1 "April 2002"
+.TH SCONS 1 "May 2002"
 .SH NAME
 scons \- a software construction tool
 .SH SYNOPSIS
@@ -630,16 +630,33 @@ env = Environment()
 
 Build rules are specified by calling builder methods on a construction
 environment. The arguments to the builder methods are target (a list of
-target files) and source (a list of source files). If a string is given
+target files) and source (a list of source files).
+If a string is given
 for target or source, then 
 .B scons 
-interprets it as a space delimited list
-of files. The following are examples of calling a builder:
+.I currently
+interprets it as a space-delimited list of files.
+NOTE:  Splitting a string into a list of files this
+way will be
+.I removed
+as of the next version of SCons.
+If you currently use space-delimited file lists,
+you must change them by next release.
+See the discussion of the Split() function
+for more information.
+
+The following are examples of calling a builder:
+
+.ES
+# The recommended ways to call a builder
+# with multiple source input files:
+env.Program('bar', ['bar.c', 'foo.c'])
+env.Program('bar', Split('bar.c foo.c'))
 
-.ES
+# Space-delimited lists.
+# The following will NOT work in version 0.08 of SCons!
 env.Program(target = 'bar', source = 'bar.c foo.c')
 env.Program('bar', 'bar.c foo.c')
-env.Program('bar', ['bar.c', 'foo.c'])
 .EE
 
 .B scons
@@ -1465,9 +1482,15 @@ is usually safe, and is always more efficient than
 .RI Default( targets )
 This specifies a list of default targets. Default targets will be built by
 .B scons
-if no explicit targets are given on the command line. Multiple targets can
-be specified either as a space delimited string of target file names or as
-separate arguments.
+if no explicit targets are given on the command line.
+Multiple targets should be specified as
+separate arguments to the
+.BR Default ()
+method.
+In this version of SCons (0.07),
+.BR Default ()
+will also accept a space-delimited string of target file names;
+this functionality will be removed in the next version of SCons (0.08).
 Target names with white space may be be enclosed in an
 array to prevent the string from being split into
 separate file names.
@@ -1497,12 +1520,13 @@ to export a list of variables from the current
 configuration file to all other configuration files. The exported variables
 are kept in a global collection, so subsequent exports
 will over-write previous exports that have the same name. 
-Multiple variable names can be passed to
+Multiple variable names should be passed to
 .BR Export ()
-in a space delimited string or as seperate arguments. Example:
+as separate arguments. Examples:
 
 .ES
 Export("env")
+Export("env", "variable")
 .EE
 
 .TP 
@@ -1536,12 +1560,15 @@ argument to
 .BR SConscript ().
 Variables exported by 
 .BR SConscript ()
-have precedence. Multiple variable names can be passed to 
+have precedence.
+Multiple variable names should be passed to 
 .BR Import ()
-in a space delimited string or as seperate arguments. Example:
+as separate arguments.
+Examples:
 
 .ES
 Import("env")
+Import("env", "variable")
 .EE
 
 .TP
@@ -1552,12 +1579,13 @@ what variable(s) to use as the return value(s) of the current configuration
 file. These variables will be returned to the "calling" configuration file
 as the return value(s) of 
 .BR SConscript ().
-Multiple variable names can be passed to 
+Multiple variable names should be passed to 
 .BR Return ()
-in a space delimited string or as seperate arguments. Example:
+as a list. Example:
 
 .ES
 Return("foo")
+Return(["foo", "bar"])
 .EE
 
 .TP
@@ -1569,8 +1597,7 @@ to execute
 as a configuration file. The optional 
 .I exports
 argument provides a list of variable names to export to
-.IR script ". " exports
-can also be a space delimited string of variables names. 
+.IR script ". "
 .I script
 must use the
 .BR Import ()
@@ -1630,6 +1657,39 @@ is that arguments to the command.
 is a dictionary of the environment variables
 in which the command should be executed.
 
+.TP
+.RI Split( arg )
+Returns a list of file names or other objects.
+If arg is a string,
+it will be split on strings of white-space characters
+within the string,
+making it easier to write long lists of file names.
+If arg is already a list,
+the list will be returned untouched.
+If arg is any other type of object,
+it will be returned as a list
+containing just the object.
+
+.ES
+files = Split("f1.c f2.c f3.c")
+files = Split("""
+       f4.c
+       f5.c
+       f6.c
+""")
+.EE
+.IP
+NOTE:  Currently, all builders perform this white-space split
+automatically on their target and source file arguments.
+As of the next version of SCons,
+Builder objects will no longer perform this split.
+If you use white-space separated strings of file names,
+you will need to convert them to lists
+by the next release of SCons by hand,
+or by using the Split() function provided here,
+or by using a similar function such as the
+string.split() function in the Python library.
+
 .TP
 .RI WhereIs( program ", [" path  ", [" pathext ]])
 
index f152670b5832694d2dc2bb24c95478d05a4d0b82..caaaf3e4c12adece45e6afbe17ae59fa6052c8d5 100644 (file)
@@ -109,6 +109,10 @@ RELEASE 0.07 - Thu, 25 Apr 2002 06:24:50 -0500
     A -X option indicates it's an executable, not a script to feed
     to the Python interpreter.
 
+  - Add a Split() function (identical to SCons.Util.argmunge()) for use
+    in the next release, when Builders will no longer automatically split
+    strings on white space.
+
   From Steve Leblanc:
 
   - Add the SConscriptChdir() method.
index 1d0a5a9232f2f90a0429e4672ce147740beec632..803869a2ad04d9e70c321cdecd2975adabb51df6 100644 (file)
@@ -67,6 +67,38 @@ RELEASE 0.07 - Thu, 25 Apr 2002 06:24:50 -0500
            open(str(target), 'w').write(open(str(source), 'r').read())
             return 0
 
+  Please not the following UPCOMING very important change:
+
+    - As of the next SCons release (0.08), Builder objects will no longer
+      automatically split target and source file strings on white space.
+      SCons will interpret the string arguments for the target or source
+      files as the complete name of the file, even if the name contains
+      white space.
+
+      Consequently, any builder calls that you have defined which supply
+      multiple file names in a single string, such as:
+
+          env.Program(target = 'foo', source = 'f1.c f2.c')
+
+      These calls will need to be changed by next release.  You may
+      either split up the string into an array of individual file name
+      strings by hand:
+
+          env.Program(target = 'foo', source = ['f1.c', 'f2.c'])
+
+      Or you may use the newly-provided Split() function to turn a
+      string of white-space separated file names into an array:
+
+          env.Program(target = 'foo', source = Split('f1.c f2.c'))
+
+      The Split() function preserves the functionality that the builder
+      objects currently invoke internally: if the argument is a string,
+      it will be split on white space; if the argument is already a list,
+      the list will be returned.
+
+      (You may, of course, also use the string.split() function from
+      the standard Python library to convert your strings.)
+
   Owing to an extensive test suite, the SCons team believes that this
   release is of sufficient quality that you can use it for real work,
   despite the "alpha" label.
index 05330e4f3eaf1b7d2fbe2e98c888282ec8630189..a28a31d85dd1def440398c8fb9f932da9eefaf2c 100644 (file)
@@ -218,6 +218,9 @@ class BuilderBase:
         """
         def adjustixes(files, pre, suf):
             ret = []
+            # FOR RELEASE 0.08:
+            #if not SCons.Util.is_List(files):
+            #    files = [files]
             files = SCons.Util.argmunge(files)
 
             for f in files:
index 68e4c732f8f0d977659e29aace2d941712fe609f..68a55f8d9addd19e48349ac453d006ef4f148595 100644 (file)
@@ -398,6 +398,9 @@ arg2nodes_lookups = []
 
 
 def arg2nodes(arg, node_factory=None):
+    # FOR RELEASE 0.08:
+    #"""This function converts a string or list into a list of Node
+    #instances."""
     """This function converts a string or list into a list of Node instances.
     It follows the rules outlined in the SCons design document by accepting
     any of the following inputs:
@@ -408,6 +411,9 @@ def arg2nodes(arg, node_factory=None):
           in the list are not split at spaces.
     In all cases, the function returns a list of Node instances."""
 
+    # FOR RELEASE 0.08:
+    #if not SCons.Util.is_List(arg):
+    #    arg = [arg]
     narg = SCons.Util.argmunge(arg)
 
     nodes = []
index a6f293d333e228f4eabf35abd91927595381b05d..79e2a607e49c1e9ebbe100698b1427ef5b83235d 100644 (file)
@@ -263,5 +263,6 @@ def BuildDefaultGlobals():
     globals['SConscript']        = SConscript
     globals['SConscriptChdir']   = SConscriptChdir
     globals['SetCommandHandler'] = SCons.Action.SetCommandHandler
+    globals['Split']             = SCons.Util.Split
     globals['WhereIs']           = SCons.Util.WhereIs
     return globals
index 08edde783a512fe8a07b99cedd6300f37a066813..7912abb3400ec37bf9eb635dcfa8d0d54b6bed64 100644 (file)
@@ -297,12 +297,16 @@ def to_String(s):
         return str(s)
 
 def argmunge(arg):
-    """This function converts a string or list into a list of strings or Nodes.
-    It follows the rules outlined in the SCons design document by accepting
-    any of the following inputs:
+    return Split(arg)
+
+def Split(arg):
+    """This function converts a string or list into a list of strings
+    or Nodes.  This makes things easier for users by allowing files to
+    be specified as a white-space separated list to be split.
+    The input rules are:
         - A single string containing names separated by spaces. These will be
           split apart at the spaces.
-        - A single None instance
+        - A single Node instance
         - A list containing either strings or Node instances. Any strings
           in the list are not split at spaces.
     In all cases, the function returns a list of Nodes and strings."""
index 34dba99a400f66a15f22c85fc953a2d6e5117e71..4f3195fee7cc117f61cde422f7d93d204e904a58 100644 (file)
@@ -240,10 +240,10 @@ class UtilTestCase(unittest.TestCase):
         if hasattr(types, 'UnicodeType'):
             exec "assert not is_List(u'')"
 
-    def test_argmunge(self):
-        assert argmunge("foo bar") == ["foo", "bar"]
-        assert argmunge(["foo", "bar"]) == ["foo", "bar"]
-        assert argmunge("foo") == ["foo"]
+    def test_Split(self):
+        assert Split("foo bar") == ["foo", "bar"]
+        assert Split(["foo", "bar"]) == ["foo", "bar"]
+        assert Split("foo") == ["foo"]
 
     def test_is_String(self):
         assert is_String("")
diff --git a/test/Split.py b/test/Split.py
new file mode 100644 (file)
index 0000000..ee1a435
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+print Split('aaa')
+print Split('bbb ccc')
+print Split(['ddd', 'eee'])
+SConscript('SConscript')
+""")
+
+test.write('SConscript', """
+print Split('fff')
+print Split('ggg hhh')
+print Split(['iii', 'jjj'])
+""")
+
+expect = """['aaa']
+['bbb', 'ccc']
+['ddd', 'eee']
+['fff']
+['ggg', 'hhh']
+['iii', 'jjj']
+"""
+
+test.run(stdout = expect)
+
+test.pass_test()