diff options
author | Gary Oberbrunner <garyo@oberbrunner.com> | 2012-05-27 12:23:07 -0400 |
---|---|---|
committer | Gary Oberbrunner <garyo@oberbrunner.com> | 2012-05-27 12:23:07 -0400 |
commit | ec74799028d501d7e49e0fbae5a56b7744c0826e (patch) | |
tree | ca998ac50af37d743b93c29d45b6896a11a658a9 | |
parent | fde2ef438cf5cf5d28c08fcce88f994fac06a996 (diff) | |
parent | 94265ae3b335dbd5e9f41a691c1ce31722aa86f6 (diff) | |
download | scons-ec74799028d501d7e49e0fbae5a56b7744c0826e.tar.gz |
Merged in mortoray/scons (pull request #22)
-rw-r--r-- | .hgignore | 1 | ||||
-rw-r--r-- | src/CHANGES.txt | 7 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 19 | ||||
-rw-r--r-- | src/engine/SCons/Script/Main.py | 3 | ||||
-rw-r--r-- | src/engine/SCons/Tool/textfile.xml | 2 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 14 | ||||
-rw-r--r-- | test/Fortran/FORTRANPPFILESUFFIXES.py | 89 | ||||
-rw-r--r-- | test/issue2821.py | 50 | ||||
-rw-r--r-- | test/option-s.py | 5 |
9 files changed, 173 insertions, 17 deletions
@@ -5,3 +5,4 @@ syntax:glob *.py[co] .sconsign* .svn +*~ diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d1ae455d..f7596223 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,10 @@ RELEASE 2.X.X - + From Mortoray: + - Make -s (silent mode) be silent about entering subdirs (#2976). + - Fix cloning of builders when cloning environment (#2821). + From Gary Oberbrunner: - Show valid Visual Studio architectures in error message when user passes invalid arch. @@ -25,6 +29,9 @@ RELEASE 2.X.X - From Rob Managan: - Updated the TeX builder to support LaTeX's multibib package. + From Arve Knudsen: + - Test for FORTRANPPFILESUFFIXES (#2129). + RELEASE 2.1.0 - Mon, 09 Sep 2011 20:54:57 -0700 diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index b3087655..529e3a38 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -72,6 +72,7 @@ CleanTargets = {} CalculatorArgs = {} semi_deepcopy = SCons.Util.semi_deepcopy +semi_deepcopy_dict = SCons.Util.semi_deepcopy_dict # Pull UserError into the global name space for the benefit of # Environment().SourceSignatures(), which has some import statements @@ -303,7 +304,9 @@ class BuilderDict(UserDict): UserDict.__init__(self, dict) def __semi_deepcopy__(self): - return self.__class__(self.data, self.env) + # These cannot be copied since they would both modify the same builder object, and indeed + # just copying would modify the original builder + raise TypeError( 'cannot semi_deepcopy a BuilderDict' ) def __setitem__(self, item, val): try: @@ -1374,15 +1377,15 @@ class Base(SubstitutionEnvironment): (like a function). There are no references to any mutable objects in the original Environment. """ - clone = copy.copy(self) - clone._dict = semi_deepcopy(self._dict) - try: - cbd = clone._dict['BUILDERS'] + builders = self._dict['BUILDERS'] except KeyError: pass - else: - clone._dict['BUILDERS'] = BuilderDict(cbd, clone) + + clone = copy.copy(self) + # BUILDERS is not safe to do a simple copy + clone._dict = semi_deepcopy_dict(self._dict, ['BUILDERS']) + clone._dict['BUILDERS'] = BuilderDict(builders, clone) # Check the methods added via AddMethod() and re-bind them to # the cloned environment. Only do this if the attribute hasn't @@ -1733,7 +1736,7 @@ class Base(SubstitutionEnvironment): except KeyError: pass else: - kwbd = semi_deepcopy(kwbd) + kwbd = BuilderDict(kwbd,self) del kw['BUILDERS'] self.__setitem__('BUILDERS', kwbd) kw = copy_non_reserved_keywords(kw) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 0e029b5a..bcb013e5 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -869,7 +869,8 @@ def _main(parser): script_dir = '' if script_dir and script_dir != os.getcwd(): - display("scons: Entering directory `%s'" % script_dir) + if not options.silent: + display("scons: Entering directory `%s'" % script_dir) try: os.chdir(script_dir) except OSError: diff --git a/src/engine/SCons/Tool/textfile.xml b/src/engine/SCons/Tool/textfile.xml index 54e801c4..3a53b573 100644 --- a/src/engine/SCons/Tool/textfile.xml +++ b/src/engine/SCons/Tool/textfile.xml @@ -140,7 +140,7 @@ env.Substfile('bar.in', SUBST_DICT = good_bar) # the SUBST_DICT may be in common (and not an override) substutions = {} -subst = Environment(tools = ['textfile', SUBST_DICT = substitutions) +subst = Environment(tools = ['textfile'], SUBST_DICT = substitutions) substitutions['@foo@'] = 'foo' subst['SUBST_DICT']['@bar@'] = 'bar' subst.Substfile('pgm1.c', [Value('#include "@foo@.h"'), diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 2523edac..822d5249 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -430,15 +430,15 @@ def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst, # references to anything else it finds. # # A special case is any object that has a __semi_deepcopy__() method, -# which we invoke to create the copy, which is used by the BuilderDict -# class because of its extra initialization argument. +# which we invoke to create the copy. Currently only used by +# BuilderDict to actually prevent the copy operation (as invalid on that object) # # The dispatch table approach used here is a direct rip-off from the # normal Python copy module. _semi_deepcopy_dispatch = d = {} -def _semi_deepcopy_dict(x): +def semi_deepcopy_dict(x, exclude = [] ): copy = {} for key, val in x.items(): # The regular Python copy.deepcopy() also deepcopies the key, @@ -447,9 +447,10 @@ def _semi_deepcopy_dict(x): # copy[semi_deepcopy(key)] = semi_deepcopy(val) # # Doesn't seem like we need to, but we'll comment it just in case. - copy[key] = semi_deepcopy(val) + if key not in exclude: + copy[key] = semi_deepcopy(val) return copy -d[dict] = _semi_deepcopy_dict +d[dict] = semi_deepcopy_dict def _semi_deepcopy_list(x): return list(map(semi_deepcopy, x)) @@ -467,14 +468,13 @@ def semi_deepcopy(x): if hasattr(x, '__semi_deepcopy__') and callable(x.__semi_deepcopy__): return x.__semi_deepcopy__() elif isinstance(x, UserDict): - return x.__class__(_semi_deepcopy_dict(x)) + return x.__class__(semi_deepcopy_dict(x)) elif isinstance(x, UserList): return x.__class__(_semi_deepcopy_list(x)) return x - class Proxy(object): """A simple generic Proxy class, forwarding all calls to subject. So, for the benefit of the python newbie, what does diff --git a/test/Fortran/FORTRANPPFILESUFFIXES.py b/test/Fortran/FORTRANPPFILESUFFIXES.py new file mode 100644 index 00000000..e0c69749 --- /dev/null +++ b/test/Fortran/FORTRANPPFILESUFFIXES.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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. +# +""" Test manipulating FORTRANPPFILESUFFIXES. """ + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import string +import sys +import TestSCons + +from common import write_fake_link + +_python_ = TestSCons._python_ +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +write_fake_link(test) + +test.write('myfortran.py', r""" +import getopt +import sys + +comment = '#' + sys.argv[1] +args = sys.argv[2:] +# First parse defines, since getopt won't have it +defines = [] +for a in args[:]: + if a.startswith("-D") or a.startswith("/D"): + defines.append(a[2:]) + args.remove(a) + +opts, args = getopt.getopt(args, 'co:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for d in defines: + outfile.write("#define %s\n" % (d,)) +for l in infile.readlines(): + if l[:len(comment)] != comment: + outfile.write(l) +sys.exit(0) +""") + +# Test non default file suffix: .f, .f90 and .f95 for FORTRAN +test.write('SConstruct', """ +env = Environment(LINK=r'%(_python_)s mylink.py', + LINKFLAGS=[], + CPPDEFINES=["mosdef"], + F77=r'%(_python_)s myfortran.py g77', + FORTRAN=r'%(_python_)s myfortran.py fortran', + FORTRANPPFILESUFFIXES=['.f', '.fpp'], + tools=['default', 'fortran']) +env.Program(target = 'test01', source = 'test01.f') +env.Program(target = 'test02', source = 'test02.fpp') +""" % locals()) + +test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") +test.write('test02.fpp', "This is a .fpp file.\n#link\n#fortran\n") + +test.run(arguments='.', stderr=None) + +test.must_match('test01' + _exe, "#define mosdef\nThis is a .f file.\n") +test.must_match('test02' + _exe, "#define mosdef\nThis is a .fpp file.\n") + +test.pass_test() diff --git a/test/issue2821.py b/test/issue2821.py new file mode 100644 index 00000000..b6cda716 --- /dev/null +++ b/test/issue2821.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# 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', """ +test = Environment() +def blub(): + pass + +test.Library.__call__ = blub +test.Clone() +assert test.Library.__call__ == blub +""") + +test.run() + +test.pass_test() + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option-s.py b/test/option-s.py index 6950fc98..f79c3470 100644 --- a/test/option-s.py +++ b/test/option-s.py @@ -67,6 +67,11 @@ test.run(arguments = '--quiet f1.out f2.out', stdout = "") test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.fail_test(not os.path.exists(test.workpath('f2.out'))) +# -C should also be quiet Issue#2796 +test.subdir( 'sub' ) +test.write(['sub','SConstruct'],"") +test.run(arguments = '-s -C sub', stdout = "" ) + test.pass_test() |