summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2007-04-13 23:36:39 (GMT)
committerSteven Knight <knight@baldmt.com>2007-04-13 23:36:39 (GMT)
commit43e86764943c659f53bf0d1d101708bbdf7d07e6 (patch)
tree7b0e2eadcaf969c35e8bab578471b404a5a7d380 /test
parent2174f491d8e103b7af77aa089070503a7b0863c1 (diff)
downloadSCons-43e86764943c659f53bf0d1d101708bbdf7d07e6.zip
SCons-43e86764943c659f53bf0d1d101708bbdf7d07e6.tar.gz
SCons-43e86764943c659f53bf0d1d101708bbdf7d07e6.tar.bz2
Merged revisions 1826-1882 via svnmerge from
http://scons.tigris.org/svn/scons/branches/core ........ r1828 | stevenknight | 2007-02-12 13:29:17 -0600 (Mon, 12 Feb 2007) | 1 line 0.96.D588 - Speed up Builder suffix-matching. ........ r1829 | stevenknight | 2007-02-14 08:12:32 -0600 (Wed, 14 Feb 2007) | 1 line 0.96.D589 - The scons command, branch 0.96.94. ........ r1830 | stevenknight | 2007-02-14 09:49:44 -0600 (Wed, 14 Feb 2007) | 1 line 0.96.D590 - Fix the scons-doc .tar.gz file packaging. ........ r1835 | stevenknight | 2007-02-15 11:03:20 -0600 (Thu, 15 Feb 2007) | 1 line 0.96.D591 - Update the release HOWTO. ........ r1836 | stevenknight | 2007-02-15 13:39:24 -0600 (Thu, 15 Feb 2007) | 1 line 0.96.D592 - The scons command, branch 0.96.95. ........ r1837 | stevenknight | 2007-02-15 18:34:18 -0600 (Thu, 15 Feb 2007) | 1 line 0.96.D593 - Back out (comment out) Windows registry installer changes. ........ r1838 | stevenknight | 2007-02-16 10:37:28 -0600 (Fri, 16 Feb 2007) | 1 line 0.96.D594 - Update Debian packaging to remove hard-coded references to Python 2.2. (Jean-Baptiste Lab) ........ r1839 | stevenknight | 2007-02-20 09:34:23 -0600 (Tue, 20 Feb 2007) | 1 line 0.96.D595 - Documentation fixes. In the construction variable appendix, use cross-referenced links to entries. ........ r1840 | stevenknight | 2007-02-21 05:11:35 -0600 (Wed, 21 Feb 2007) | 1 line 0.96.D596 - Handle Java '.class' attributes after non-word tokens without assuming it introduces an inner class. ........ r1841 | stevenknight | 2007-02-21 22:33:28 -0600 (Wed, 21 Feb 2007) | 1 line 0.96.D597 - CPPDEFINES regression ........ r1842 | stevenknight | 2007-02-22 14:19:10 -0600 (Thu, 22 Feb 2007) | 1 line 0.96.D598 - Do not detect a Java anonymous class when the first non-skipped token after "new" is a closing brace. ........ r1843 | stevenknight | 2007-02-23 10:45:06 -0600 (Fri, 23 Feb 2007) | 1 line 0.96.D599 - Better [Errno 21] Is a directory error message. ........ r1844 | stevenknight | 2007-02-23 13:32:11 -0600 (Fri, 23 Feb 2007) | 1 line 0.96.D600 - Fix expansion of non-Node objects within a PathList (maximum recursion / unhashable type bug). ........ r1847 | stevenknight | 2007-03-02 00:12:27 -0600 (Fri, 02 Mar 2007) | 1 line 0.96.D601 - Generate SCons API documentation from the docstrings using epydoc. ........ r1848 | stevenknight | 2007-03-02 14:10:06 -0600 (Fri, 02 Mar 2007) | 1 line 0.96.D602 - Fix use of custom include and lib paths with Visual Studio 8. (Richard Viney) ........ r1849 | stevenknight | 2007-03-03 01:00:22 -0600 (Sat, 03 Mar 2007) | 1 line 0.96.D603 - Man page fix: ParseDepends(). User's Guide updates: NoCache(), Clean(), fix CPPDEFINES output, markers for to-be-documented features, white space clean-up. ........ r1850 | stevenknight | 2007-03-06 02:29:08 -0600 (Tue, 06 Mar 2007) | 1 line 0.96.D604 - Fix use of --debug=presub with the Actions for our out-of-the-box Builders. ........ r1851 | stevenknight | 2007-03-06 09:10:43 -0600 (Tue, 06 Mar 2007) | 1 line 0.96.D605 - User Guide updates: --random, AlwaysBuild(), --tree=, --debug=presub, --debug=stacktrace. ........ r1852 | stevenknight | 2007-03-06 15:38:06 -0600 (Tue, 06 Mar 2007) | 1 line 0.96.D606 - Have the Intel toolchain use the default smart linking logic. (Dmitry Grigorenko and Gary Oberbrunner) ........ r1853 | stevenknight | 2007-03-06 17:56:44 -0600 (Tue, 06 Mar 2007) | 1 line 0.96.D607 - Fix tests: ActionTests.py for presub change, command detection in test/Intel/icpc-link.py. ........ r1854 | stevenknight | 2007-03-08 09:35:25 -0600 (Thu, 08 Mar 2007) | 1 line 0.96.D608 - Better selection of .NET Framework SDK paths. (Richard Viney) ........ r1855 | stevenknight | 2007-03-08 10:34:37 -0600 (Thu, 08 Mar 2007) | 1 line 0.96.D609 - Don't re-run TeX if the triggering strings (\makeindex, \bibliography, \tableofcontents) are commented out. (Matthias Troffaes) ........ r1856 | stevenknight | 2007-03-09 16:18:36 -0600 (Fri, 09 Mar 2007) | 1 line 0.96.D610 - Teach the new PathList module to handle nested lists within CPPPATH and the like. ........ r1857 | stevenknight | 2007-03-10 23:30:29 -0600 (Sat, 10 Mar 2007) | 1 line 0.96.D611 - Qt builders_used failure. ........ r1858 | stevenknight | 2007-03-11 15:33:34 -0500 (Sun, 11 Mar 2007) | 1 line 0.96.D612 - Document limitations of --implicit-cache w.r.t. CPPPATH/LIBPATH/etc. ........ r1859 | stevenknight | 2007-03-11 21:11:26 -0500 (Sun, 11 Mar 2007) | 1 line 0.96.D613 - Document --debug=findlibs and --taskmastertrace in the User's Guide. ........ r1860 | stevenknight | 2007-03-12 13:28:42 -0500 (Mon, 12 Mar 2007) | 1 line 0.96.D614 - Remove deleted cons file from the User's Guide MANIFEST. Fix epydoc API build if the build directory is outside the current directory. ........ r1861 | stevenknight | 2007-03-13 13:03:56 -0500 (Tue, 13 Mar 2007) | 2 lines Ignore '*.pyc' files in the compat/ subdirectory. ........ r1862 | stevenknight | 2007-03-13 19:08:19 -0500 (Tue, 13 Mar 2007) | 1 line 0.96.D615 - Fix use of $VAR expansions within CPPPATH/LIBPATH values when the expansion is itself a Dir node concatenated with a string. ........ r1866 | stevenknight | 2007-03-16 01:46:10 -0500 (Fri, 16 Mar 2007) | 1 line 0.96.D616 - Back off to the 0.96.94 of Builder.py (with some performance improvements). ........ r1867 | stevenknight | 2007-03-16 11:20:39 -0500 (Fri, 16 Mar 2007) | 1 line 0.96.D617 - Fix an unnamed variable error if we can't map the Visual Studio version to a default framework version. ........ r1868 | stevenknight | 2007-03-16 12:08:18 -0500 (Fri, 16 Mar 2007) | 1 line 0.96.D618 - Quote the MSVS build target in command lines to handle spaces target name. (Jeff Mahovsky) ........ r1869 | stevenknight | 2007-03-16 13:30:06 -0500 (Fri, 16 Mar 2007) | 1 line 0.96.D619 - Portability fixes for tests run on Windows. ........ r1870 | stevenknight | 2007-03-20 00:18:04 -0500 (Tue, 20 Mar 2007) | 1 line 0.96.D620 - Windows portability fixes: test scripts and infrastructure, detect vcexpress.exe. ........ r1871 | garyo | 2007-03-21 18:32:54 -0500 (Wed, 21 Mar 2007) | 1 line Fix bug where site_scons dir was added to sys.path as relative, not absolute. Added test case. Bug reported by Timothy Woods; thanks for the test case! ........ r1872 | stevenknight | 2007-03-22 09:43:23 -0500 (Thu, 22 Mar 2007) | 1 line 0.96.D622 - Add mention of site_scons fix to src/CHANGES.txt. ........ r1873 | stevenknight | 2007-04-02 23:49:36 -0500 (Mon, 02 Apr 2007) | 1 line 0.96.D623 - Parallel build dependencies with multiple entries in children. (Adam Simpkins) ........ r1874 | stevenknight | 2007-04-04 07:45:05 -0500 (Wed, 04 Apr 2007) | 1 line 0.96.D624 - Make all necessary LaTeX auxiliary files Precious, so bibliography contents aren't affected by whether the auxiliary files exist or not. (Joel B. Mohler) ........ r1875 | stevenknight | 2007-04-04 13:15:39 -0500 (Wed, 04 Apr 2007) | 1 line 0.96.D625 - Fix --debug-time value when -j option is used. ........ r1876 | stevenknight | 2007-04-09 19:40:08 -0500 (Mon, 09 Apr 2007) | 1 line 0.96.D626 - Fix man page example of propagating external user environment. Eliminate cut-and-paste sentence in NoCache() description. (Helmut Grohne, Joe Bloggs) [Issue 1626] [Issue 1627] ........ r1877 | stevenknight | 2007-04-09 23:20:14 -0500 (Mon, 09 Apr 2007) | 1 line 0.96.D627 - Re-run latex after bibtex runs. (Rob Managan) ........ r1878 | stevenknight | 2007-04-11 23:38:17 -0500 (Wed, 11 Apr 2007) | 1 line 0.96.D628 - Fix typo in the User's Guide. [issue 1600] ........ r1879 | stevenknight | 2007-04-12 01:06:35 -0500 (Thu, 12 Apr 2007) | 1 line 0.96.D629 - Avoid name conflicts with compat/ modules (specifically _subprocess.py). ........ r1880 | stevenknight | 2007-04-12 01:33:42 -0500 (Thu, 12 Apr 2007) | 1 line 0.96.D630 - Portability fixes and other improvements in test scripts. ........ r1882 | stevenknight | 2007-04-13 16:42:02 -0500 (Fri, 13 Apr 2007) | 1 line 0.96.D631 - The scons command, branch 0.96.96. ........
Diffstat (limited to 'test')
-rw-r--r--test/CPPDEFINES.py12
-rw-r--r--test/CPPPATH/CPPPATH.py (renamed from test/CPPPATH.py)31
-rw-r--r--test/CPPPATH/Dir.py79
-rw-r--r--test/CPPPATH/expand-object.py63
-rw-r--r--test/CPPPATH/nested-lists.py77
-rw-r--r--test/CPPPATH/null.py55
-rw-r--r--test/CXX/CC-variables.py2
-rw-r--r--test/CacheDir/up-to-date-q.py2
-rw-r--r--test/Errors/preparation.py67
-rw-r--r--test/Intel/icpc-link.py59
-rw-r--r--test/Java/JAVAC.py223
-rw-r--r--test/Java/live.py346
-rw-r--r--test/MSVS/common-prefix.py6
-rw-r--r--test/MSVS/runfile.py6
-rw-r--r--test/MSVS/vs-6.0-files.py8
-rw-r--r--test/MSVS/vs-7.0-files.py6
-rw-r--r--test/MSVS/vs-7.1-files.py6
-rw-r--r--test/MSVS/vs-8.0-files.py6
-rw-r--r--test/Parallel/duplicate-children.py68
-rw-r--r--test/QT/Tool.py148
-rw-r--r--test/TEX/auxiliaries.py139
-rw-r--r--test/TEX/bibtex-latex-rerun.py99
-rw-r--r--test/TEX/multi-run.py25
-rw-r--r--test/gnutools.py63
-rw-r--r--test/import.py3
-rw-r--r--test/option/debug-pdb.py41
-rw-r--r--test/option/debug-presub.py (renamed from test/option--debug.py)61
-rw-r--r--test/option/debug-time.py146
-rw-r--r--test/site_scons/no-site-dir.py11
-rw-r--r--test/site_scons/sys-path.py65
30 files changed, 1507 insertions, 416 deletions
diff --git a/test/CPPDEFINES.py b/test/CPPDEFINES.py
index 61aaecd..c38f857 100644
--- a/test/CPPDEFINES.py
+++ b/test/CPPDEFINES.py
@@ -50,13 +50,13 @@ test.write('SConstruct', """\
test_list = [
'xyz',
['x', 'y', 'z'],
- ['x', ['y', 123], 'z'],
+ ['x', ['y', 123], 'z', ('int', '$INTEGER')],
{ 'c' : 3, 'b': None, 'a' : 1 },
]
-env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='')
+env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='', INTEGER=0)
for i in test_list:
print env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')
-env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|')
+env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|', INTEGER=1)
for i in test_list:
print env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')
""")
@@ -65,18 +65,18 @@ expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n",
read_str = """\
-Dxyz
-Dx -Dy -Dz
--Dx -Dy=123 -Dz
+-Dx -Dy=123 -Dz -Dint=0
-Da=1 -Db -Dc=3
|xyz|
|x| |y| |z|
-|x| |y=123| |z|
+|x| |y=123| |z| |int=1|
|a=1| |b| |c=3|
""")
test.run(arguments = '.', stdout=expect)
test.write('SConstruct', """\
-foo = Environment(CPPDEFINES = ['FOO', ('VAL', 7)])
+foo = Environment(CPPDEFINES = ['FOO', ('VAL', '$VALUE')], VALUE=7)
bar = Environment(CPPDEFINES = {'BAR':None, 'VAL':8})
baz = Environment(CPPDEFINES = ['BAZ', ('VAL', 9)])
f = foo.Object(target = 'foo', source = 'prog.c')
diff --git a/test/CPPPATH.py b/test/CPPPATH/CPPPATH.py
index c9400f7..80b4aa7 100644
--- a/test/CPPPATH.py
+++ b/test/CPPPATH/CPPPATH.py
@@ -24,8 +24,8 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os
-import sys
+import os.path
+
import TestSCons
_exe = TestSCons._exe
@@ -154,7 +154,7 @@ foobar/ttt.h
# Make sure we didn't duplicate the source file in the variant subdirectory.
-test.fail_test(os.path.exists(test.workpath('variant', 'prog.c')))
+test.must_not_exist(test.workpath('variant', 'prog.c'))
test.up_to_date(arguments = args)
@@ -196,7 +196,7 @@ foobar/ttt.h
# Make sure we didn't duplicate the source file in the variant subdirectory.
-test.fail_test(os.path.exists(test.workpath('variant', 'prog.c')))
+test.must_not_exist(test.workpath('variant', 'prog.c'))
test.up_to_date(arguments = args)
@@ -238,7 +238,7 @@ foobar/ttt.h
""")
# Make sure we didn't duplicate the source file in the variant subdirectory.
-test.fail_test(os.path.exists(test.workpath('variant', 'prog.c')))
+test.must_not_exist(test.workpath('variant', 'prog.c'))
test.up_to_date(arguments = args)
@@ -301,25 +301,4 @@ test.up_to_date(arguments = args)
-# Check that neither a null-string CPPPATH nor a
-# a CPPPATH containing null values blows up.
-test.write('SConstruct', """
-env = Environment(CPPPATH = '')
-env.Library('one', source = 'empty1.c')
-env = Environment(CPPPATH = [None])
-env.Library('two', source = 'empty2.c')
-env = Environment(CPPPATH = [''])
-env.Library('three', source = 'empty3.c')
-""")
-
-test.write('empty1.c', "int a=0;\n")
-test.write('empty2.c', "int b=0;\n")
-test.write('empty3.c', "int c=0;\n")
-
-test.run(arguments = '.',
- stderr=TestSCons.noisy_ar,
- match=TestSCons.match_re_dotall)
-
-
-
test.pass_test()
diff --git a/test/CPPPATH/Dir.py b/test/CPPPATH/Dir.py
new file mode 100644
index 0000000..1059467
--- /dev/null
+++ b/test/CPPPATH/Dir.py
@@ -0,0 +1,79 @@
+#!/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__"
+
+"""
+Verify that CPPPATH values with Dir nodes work correctly.
+"""
+
+import TestSCons
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.subdir('inc1', 'inc2', 'inc3', ['inc3', 'subdir'])
+
+test.write('SConstruct', """
+env = Environment(CPPPATH = [Dir('inc1'), '$INC2', '$INC3/subdir'],
+ INC2 = Dir('inc2'),
+ INC3 = Dir('inc3'))
+env.Program('prog.c')
+""")
+
+test.write('prog.c', """\
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "one.h"
+#include "two.h"
+#include "three.h"
+int
+main(int argc, char *argv[])
+{
+ printf("%s\\n", ONE);
+ printf("%s\\n", TWO);
+ printf("%s\\n", THREE);
+ return (0);
+}
+""")
+
+test.write(['inc1', 'one.h'], """\
+#define ONE "1"
+""")
+
+test.write(['inc2', 'two.h'], """\
+#define TWO "2"
+""")
+
+test.write(['inc3', 'subdir', 'three.h'], """\
+#define THREE "3"
+""")
+
+test.run(arguments = '.')
+
+test.run(program = test.workpath('prog' + _exe), stdout = "1\n2\n3\n")
+
+test.pass_test()
diff --git a/test/CPPPATH/expand-object.py b/test/CPPPATH/expand-object.py
new file mode 100644
index 0000000..5e1b06f
--- /dev/null
+++ b/test/CPPPATH/expand-object.py
@@ -0,0 +1,63 @@
+#!/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__"
+
+"""
+Make sure that $CPPPATH expands correctly if one of the subsidiary
+expansions contains a stringable non-Node object.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+class XXX:
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return 'XXX-' + self.value + '-XXX'
+env = Environment(CPPPATH = ['#',
+ '$BUILDDIR',
+ '/tmp/xyzzy'],
+ BUILDDIR = '#scons_build/$EXPANSION',
+ EXPANSION = XXX('win32'))
+env.Object('foo.c')
+""")
+
+test.write('foo.c', """\
+#include <stdio.h>
+void
+foo(void)
+{
+ printf("foo.c\\n");
+}
+""")
+
+test.run(arguments = '.')
+
+test.must_exist(test.workpath('foo' + TestSCons._obj))
+
+test.pass_test()
diff --git a/test/CPPPATH/nested-lists.py b/test/CPPPATH/nested-lists.py
new file mode 100644
index 0000000..8ec97bc
--- /dev/null
+++ b/test/CPPPATH/nested-lists.py
@@ -0,0 +1,77 @@
+#!/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__"
+
+"""
+Verify that CPPPATH values consisting of nested lists work correctly.
+"""
+
+import TestSCons
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.subdir('inc1', 'inc2', 'inc3')
+
+test.write('SConstruct', """
+env = Environment(CPPPATH = ['inc1', ['inc2', ['inc3']]])
+env.Program('prog.c')
+""")
+
+test.write('prog.c', """\
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "one.h"
+#include "two.h"
+#include "three.h"
+int
+main(int argc, char *argv[])
+{
+ printf("%s\\n", ONE);
+ printf("%s\\n", TWO);
+ printf("%s\\n", THREE);
+ return (0);
+}
+""")
+
+test.write(['inc1', 'one.h'], """\
+#define ONE "1"
+""")
+
+test.write(['inc2', 'two.h'], """\
+#define TWO "2"
+""")
+
+test.write(['inc3', 'three.h'], """\
+#define THREE "3"
+""")
+
+test.run(arguments = '.')
+
+test.run(program = test.workpath('prog' + _exe), stdout = "1\n2\n3\n")
+
+test.pass_test()
diff --git a/test/CPPPATH/null.py b/test/CPPPATH/null.py
new file mode 100644
index 0000000..19895db
--- /dev/null
+++ b/test/CPPPATH/null.py
@@ -0,0 +1,55 @@
+#!/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__"
+
+"""
+Verify that neither a null-string CPPPATH nor a
+a CPPPATH containing null values blows up.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+env = Environment(CPPPATH = '')
+env.Library('one', source = 'empty1.c')
+env = Environment(CPPPATH = [None])
+env.Library('two', source = 'empty2.c')
+env = Environment(CPPPATH = [''])
+env.Library('three', source = 'empty3.c')
+""")
+
+test.write('empty1.c', "int a=0;\n")
+test.write('empty2.c', "int b=0;\n")
+test.write('empty3.c', "int c=0;\n")
+
+test.run(arguments = '.',
+ stderr=TestSCons.noisy_ar,
+ match=TestSCons.match_re_dotall)
+
+
+
+test.pass_test()
diff --git a/test/CXX/CC-variables.py b/test/CXX/CC-variables.py
index 93aa315..fea3dde 100644
--- a/test/CXX/CC-variables.py
+++ b/test/CXX/CC-variables.py
@@ -34,7 +34,7 @@ import TestSCons
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(tools = ['g++'])
+env = Environment(tools = ['g++'], CXX = 'g++')
env.Object(target = 'test.obj', source = 'test.cxx')
env.MergeFlags('+for_CCFLAGS -Wp,-for_CPPFLAGS')
""")
diff --git a/test/CacheDir/up-to-date-q.py b/test/CacheDir/up-to-date-q.py
index 07123c9..0a49164 100644
--- a/test/CacheDir/up-to-date-q.py
+++ b/test/CacheDir/up-to-date-q.py
@@ -60,7 +60,7 @@ int main(){ return 0; }
sconstruct = """
import os
-CacheDir('%s')
+CacheDir(r'%s')
Program('foo', 'foo.c')
""" % test.workpath('cache')
diff --git a/test/Errors/preparation.py b/test/Errors/preparation.py
new file mode 100644
index 0000000..3f98894
--- /dev/null
+++ b/test/Errors/preparation.py
@@ -0,0 +1,67 @@
+#!/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__"
+
+"""
+Verify that we print a useful message (and exit non-zero) if an external
+error occurs while deciding if a Node is current or not.
+"""
+
+import sys
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+install = test.workpath('install')
+install_file = test.workpath('install', 'file')
+work_file = test.workpath('work', 'file')
+
+test.subdir('install', 'work')
+
+test.write(['work', 'SConstruct'], """\
+Alias("install", Install(r"%(install)s", File('file')))
+
+# Make a directory where we expect the File() to be. This causes an
+# IOError or OSError when we try to open it to read its signature.
+import os
+os.mkdir(r'%(work_file)s')
+""" % locals())
+
+if sys.platform == 'win32':
+ error_message = "Permission denied"
+else:
+ error_message = "Is a directory"
+
+expect = """\
+scons: *** [%(install_file)s] %(work_file)s: %(error_message)s
+""" % locals()
+
+test.run(chdir = 'work',
+ arguments = 'install',
+ status = 2,
+ stderr = expect)
+
+test.pass_test()
diff --git a/test/Intel/icpc-link.py b/test/Intel/icpc-link.py
new file mode 100644
index 0000000..068e0f3
--- /dev/null
+++ b/test/Intel/icpc-link.py
@@ -0,0 +1,59 @@
+#!/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__"
+
+"""
+Simple "Hello, world" test of linking with the Intel C++ compiler, icpc.
+
+This tests for a bug (1415) where our initialization of the linker to
+$CC prevented automatic linking of C++ source.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+icpc = test.detect_tool('intelc', prog='icpc')
+if not icpc:
+ test.skip_test("Could not find 'icpc' from 'intelc' Tool; skipping test(s).\n")
+
+test.write('SConstruct', """\
+env = Environment(tools=['default', 'intelc'])
+env.Program('hw', 'hw.cpp')
+""")
+
+test.write('hw.cpp', """\
+#include <iostream>
+int
+main()
+{
+ std::cout<<"hw\\n";
+ return 0;
+}
+""")
+
+test.run(arguments = '.')
+
+test.pass_test()
diff --git a/test/Java/JAVAC.py b/test/Java/JAVAC.py
index 7c06324..09639ea 100644
--- a/test/Java/JAVAC.py
+++ b/test/Java/JAVAC.py
@@ -24,6 +24,10 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+"""
+Test setting the JAVAC variable.
+"""
+
import os
import os.path
import string
@@ -93,223 +97,4 @@ line 3
-ENV = test.java_ENV()
-
-if test.detect_tool('javac', ENV=ENV):
- where_javac = test.detect('JAVAC', 'javac', ENV=ENV)
-else:
- where_javac = test.where_is('javac')
-if not where_javac:
- test.skip_test("Could not find Java javac, skipping test(s).\n")
-
-
-
-test.write("wrapper.py", """\
-import os
-import string
-import sys
-open('%s', 'ab').write("wrapper.py %%s\\n" %% string.join(sys.argv[1:]))
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
-
-test.write('SConstruct', """
-foo = Environment(tools = ['javac'],
- JAVAC = r'%(where_javac)s')
-javac = foo.Dictionary('JAVAC')
-bar = foo.Clone(JAVAC = r'%(_python_)s wrapper.py ' + javac)
-foo.Java(target = 'class1', source = 'com/sub/foo')
-bar.Java(target = 'class2', source = 'com/sub/bar')
-foo.Java(target = 'class3', source = ['src1', 'src2'])
-""" % locals())
-
-test.subdir('com',
- ['com', 'sub'],
- ['com', 'sub', 'foo'],
- ['com', 'sub', 'bar'],
- 'src1',
- 'src2')
-
-test.write(['com', 'sub', 'foo', 'Example1.java'], """\
-package com.sub.foo;
-
-public class Example1
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-test.write(['com', 'sub', 'foo', 'Example2.java'], """\
-package com.other;
-
-public class Example2
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-test.write(['com', 'sub', 'foo', 'Example3.java'], """\
-package com.sub.foo;
-
-public class Example3
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-test.write(['com', 'sub', 'bar', 'Example4.java'], """\
-package com.sub.bar;
-
-public class Example4
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-test.write(['com', 'sub', 'bar', 'Example5.java'], """\
-package com.other;
-
-public class Example5
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-test.write(['com', 'sub', 'bar', 'Example6.java'], """\
-package com.sub.bar;
-
-public class Example6
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-test.write(['src1', 'Example7.java'], """\
-public class Example7
-{
-
- public static void main(String[] args)
- {
-
- }
-
-}
-""")
-
-# Acid-test file for parsing inner Java classes, courtesy Chad Austin.
-test.write(['src2', 'Test.java'], """\
-class Empty {
-}
-
-interface Listener {
- public void execute();
-}
-
-public
-class
-Test {
- class Inner {
- void go() {
- use(new Listener() {
- public void execute() {
- System.out.println("In Inner");
- }
- });
- }
- String s1 = "class A";
- String s2 = "new Listener() { }";
- /* class B */
- /* new Listener() { } */
- }
-
- public static void main(String[] args) {
- new Test().run();
- }
-
- void run() {
- use(new Listener() {
- public void execute() {
- use(new Listener( ) {
- public void execute() {
- System.out.println("Inside execute()");
- }
- });
- }
- });
-
- new Inner().go();
- }
-
- void use(Listener l) {
- l.execute();
- }
-}
-
-class Private {
- void run() {
- new Listener() {
- public void execute() {
- }
- };
- }
-}
-""")
-
-test.run(arguments = '.')
-
-expected_wrapper_out = "wrapper.py %s -d class2 -sourcepath com/sub/bar com/sub/bar/Example4.java com/sub/bar/Example5.java com/sub/bar/Example6.java\n"
-expected_wrapper_out = string.replace(expected_wrapper_out, '/', os.sep)
-test.must_match('wrapper.out', expected_wrapper_out % where_javac)
-
-test.must_exist(test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'))
-test.must_exist(test.workpath('class1', 'com', 'other', 'Example2.class'))
-test.must_exist(test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'))
-
-test.must_exist(test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'))
-test.must_exist(test.workpath('class2', 'com', 'other', 'Example5.class'))
-test.must_exist(test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'))
-
-test.must_exist(test.workpath('class3', 'Example7.class'))
-
-test.must_exist(test.workpath('class3', 'Empty.class'))
-test.must_exist(test.workpath('class3', 'Listener.class'))
-test.must_exist(test.workpath('class3', 'Private.class'))
-test.must_exist(test.workpath('class3', 'Private$1.class'))
-test.must_exist(test.workpath('class3', 'Test.class'))
-test.must_exist(test.workpath('class3', 'Test$1.class'))
-test.must_exist(test.workpath('class3', 'Test$2.class'))
-test.must_exist(test.workpath('class3', 'Test$3.class'))
-test.must_exist(test.workpath('class3', 'Test$Inner.class'))
-
-test.up_to_date(arguments = '.')
-
test.pass_test()
diff --git a/test/Java/live.py b/test/Java/live.py
new file mode 100644
index 0000000..5ad2194
--- /dev/null
+++ b/test/Java/live.py
@@ -0,0 +1,346 @@
+#!/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__"
+
+"""
+Test Java compilation with a live "javac" compiler.
+"""
+
+import os
+import os.path
+import string
+import sys
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+ENV = test.java_ENV()
+
+if test.detect_tool('javac', ENV=ENV):
+ where_javac = test.detect('JAVAC', 'javac', ENV=ENV)
+else:
+ where_javac = test.where_is('javac')
+if not where_javac:
+ test.skip_test("Could not find Java javac, skipping test(s).\n")
+
+
+
+test.write('SConstruct', """
+env = Environment(tools = ['javac'],
+ JAVAC = r'%(where_javac)s')
+env.Java(target = 'class1', source = 'com/sub/foo')
+env.Java(target = 'class2', source = 'com/sub/bar')
+env.Java(target = 'class3', source = ['src1', 'src2'])
+env.Java(target = 'class4', source = ['src4'])
+env.Java(target = 'class5', source = ['src5'])
+""" % locals())
+
+test.subdir('com',
+ ['com', 'sub'],
+ ['com', 'sub', 'foo'],
+ ['com', 'sub', 'bar'],
+ 'src1',
+ 'src2',
+ 'src4',
+ 'src5')
+
+test.write(['com', 'sub', 'foo', 'Example1.java'], """\
+package com.sub.foo;
+
+public class Example1
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example2.java'], """\
+package com.other;
+
+public class Example2
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'foo', 'Example3.java'], """\
+package com.sub.foo;
+
+public class Example3
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example4.java'], """\
+package com.sub.bar;
+
+public class Example4
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example5.java'], """\
+package com.other;
+
+public class Example5
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['com', 'sub', 'bar', 'Example6.java'], """\
+package com.sub.bar;
+
+public class Example6
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+test.write(['src1', 'Example7.java'], """\
+public class Example7
+{
+
+ public static void main(String[] args)
+ {
+
+ }
+
+}
+""")
+
+# Acid-test file for parsing inner Java classes, courtesy Chad Austin.
+test.write(['src2', 'Test.java'], """\
+class Empty {
+}
+
+interface Listener {
+ public void execute();
+}
+
+public
+class
+Test {
+ class Inner {
+ void go() {
+ use(new Listener() {
+ public void execute() {
+ System.out.println("In Inner");
+ }
+ });
+ }
+ String s1 = "class A";
+ String s2 = "new Listener() { }";
+ /* class B */
+ /* new Listener() { } */
+ }
+
+ public static void main(String[] args) {
+ new Test().run();
+ }
+
+ void run() {
+ use(new Listener() {
+ public void execute() {
+ use(new Listener( ) {
+ public void execute() {
+ System.out.println("Inside execute()");
+ }
+ });
+ }
+ });
+
+ new Inner().go();
+ }
+
+ void use(Listener l) {
+ l.execute();
+ }
+}
+
+class Private {
+ void run() {
+ new Listener() {
+ public void execute() {
+ }
+ };
+ }
+}
+""")
+
+# Testing nested anonymous inner classes, courtesy Brandon Mansfield.
+test.write(['src4', 'NestedExample.java'], """\
+// import java.util.*;
+
+public class NestedExample
+{
+ public NestedExample()
+ {
+ Thread t = new Thread() {
+ public void start()
+ {
+ Thread t = new Thread() {
+ public void start()
+ {
+ try {Thread.sleep(200);}
+ catch (Exception e) {}
+ }
+ };
+ while (true)
+ {
+ try {Thread.sleep(200);}
+ catch (Exception e) {}
+ }
+ }
+ };
+ }
+
+
+ public static void main(String argv[])
+ {
+ NestedExample e = new NestedExample();
+ }
+}
+""")
+
+# Test not finding an anonymous class when the second token after a
+# "new" is a closing brace. This duplicates a test from the unit tests,
+# but lets us make sure that we correctly determine that everything is
+# up-to-date after the build.
+test.write(['src5', 'TestSCons.java'], """\
+class TestSCons {
+ public static void main(String[] args) {
+ Foo[] fooArray = new Foo[] { new Foo() };
+ }
+}
+
+class Foo { }
+""")
+
+test.run(arguments = '.')
+
+def get_class_files(dir):
+ def find_class_files(arg, dirname, fnames):
+ for fname in fnames:
+ if fname[-6:] == '.class':
+ arg.append(os.path.join(dirname, fname))
+ result = []
+ os.path.walk(dir, find_class_files, result)
+ result.sort()
+ return result
+
+classes_1 = get_class_files(test.workpath('class1'))
+classes_2 = get_class_files(test.workpath('class2'))
+classes_3 = get_class_files(test.workpath('class3'))
+classes_4 = get_class_files(test.workpath('class4'))
+classes_5 = get_class_files(test.workpath('class5'))
+
+expect_1 = [
+ test.workpath('class1', 'com', 'other', 'Example2.class'),
+ test.workpath('class1', 'com', 'sub', 'foo', 'Example1.class'),
+ test.workpath('class1', 'com', 'sub', 'foo', 'Example3.class'),
+]
+
+expect_2 = [
+ test.workpath('class2', 'com', 'other', 'Example5.class'),
+ test.workpath('class2', 'com', 'sub', 'bar', 'Example4.class'),
+ test.workpath('class2', 'com', 'sub', 'bar', 'Example6.class'),
+]
+
+expect_3 = [
+ test.workpath('class3', 'Empty.class'),
+ test.workpath('class3', 'Example7.class'),
+ test.workpath('class3', 'Listener.class'),
+ test.workpath('class3', 'Private$1.class'),
+ test.workpath('class3', 'Private.class'),
+ test.workpath('class3', 'Test$1.class'),
+ test.workpath('class3', 'Test$2.class'),
+ test.workpath('class3', 'Test$3.class'),
+ test.workpath('class3', 'Test$Inner.class'),
+ test.workpath('class3', 'Test.class'),
+]
+
+expect_4 = [
+ test.workpath('class4', 'NestedExample$1.class'),
+ test.workpath('class4', 'NestedExample$2.class'),
+ test.workpath('class4', 'NestedExample.class'),
+]
+
+expect_5 = [
+ test.workpath('class5', 'Foo.class'),
+ test.workpath('class5', 'TestSCons.class'),
+]
+
+def classes_must_match(dir, expect, got):
+ if expect != got:
+ sys.stderr.write("Expected the following class files in '%s':\n" % dir)
+ for c in expect:
+ sys.stderr.write(' %s\n' % c)
+ sys.stderr.write("Got the following class files in '%s':\n" % dir)
+ for c in got:
+ sys.stderr.write(' %s\n' % c)
+ test.fail_test()
+
+classes_must_match('class1', expect_1, classes_1)
+classes_must_match('class2', expect_2, classes_2)
+classes_must_match('class3', expect_3, classes_3)
+classes_must_match('class4', expect_4, classes_4)
+
+test.up_to_date(arguments = '.')
+
+test.pass_test()
diff --git a/test/MSVS/common-prefix.py b/test/MSVS/common-prefix.py
index d40060c..4034a4a 100644
--- a/test/MSVS/common-prefix.py
+++ b/test/MSVS/common-prefix.py
@@ -69,9 +69,9 @@ vcproj_template = """\
\t\t\t>
\t\t\t<Tool
\t\t\t\tName="VCNMakeTool"
-\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c Test.exe"
+\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
\t\t\t\tOutput="Test.exe"
\t\t\t\tPreprocessorDefinitions=""
\t\t\t\tIncludeSearchPath=""
diff --git a/test/MSVS/runfile.py b/test/MSVS/runfile.py
index 5638916..23fd84b 100644
--- a/test/MSVS/runfile.py
+++ b/test/MSVS/runfile.py
@@ -69,9 +69,9 @@ expected_vcprojfile = """\
\t\t\t>
\t\t\t<Tool
\t\t\t\tName="VCNMakeTool"
-\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c Test.exe"
+\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
\t\t\t\tOutput="runfile.exe"
\t\t\t\tPreprocessorDefinitions=""
\t\t\t\tIncludeSearchPath=""
diff --git a/test/MSVS/vs-6.0-files.py b/test/MSVS/vs-6.0-files.py
index ce7ef46..04e7c93 100644
--- a/test/MSVS/vs-6.0-files.py
+++ b/test/MSVS/vs-6.0-files.py
@@ -77,8 +77,8 @@ CFG=Test - Win32 Release
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ""
# PROP BASE Intermediate_Dir ""
-# PROP BASE Cmd_Line "echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct Test.exe"
-# PROP BASE Rebuild_Opt "-c && echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct Test.exe"
+# PROP BASE Cmd_Line "echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
+# PROP BASE Rebuild_Opt "-c && echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
# PROP BASE Target_File "Test.exe"
# PROP BASE Bsc_Name ""
# PROP BASE Target_Dir ""
@@ -86,8 +86,8 @@ CFG=Test - Win32 Release
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ""
# PROP Intermediate_Dir ""
-# PROP Cmd_Line "echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct Test.exe"
-# PROP Rebuild_Opt "-c && echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct Test.exe"
+# PROP Cmd_Line "echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
+# PROP Rebuild_Opt "-c && echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
# PROP Target_File "Test.exe"
# PROP Bsc_Name ""
# PROP Target_Dir ""
diff --git a/test/MSVS/vs-7.0-files.py b/test/MSVS/vs-7.0-files.py
index 8f98166..b9827e7 100644
--- a/test/MSVS/vs-7.0-files.py
+++ b/test/MSVS/vs-7.0-files.py
@@ -87,9 +87,9 @@ expected_vcprojfile = """\
\t\t\tATLMinimizesCRunTimeLibraryUsage="FALSE">
\t\t\t<Tool
\t\t\t\tName="VCNMakeTool"
-\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c Test.exe"
-\t\t\t\tRebuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
+\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
+\t\t\t\tRebuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
\t\t\t\tOutput="Test.exe"/>
\t\t</Configuration>
\t</Configurations>
diff --git a/test/MSVS/vs-7.1-files.py b/test/MSVS/vs-7.1-files.py
index 3ad2e97..057f34f 100644
--- a/test/MSVS/vs-7.1-files.py
+++ b/test/MSVS/vs-7.1-files.py
@@ -87,9 +87,9 @@ expected_vcprojfile = """\
\t\t\tATLMinimizesCRunTimeLibraryUsage="FALSE">
\t\t\t<Tool
\t\t\t\tName="VCNMakeTool"
-\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c Test.exe"
-\t\t\t\tRebuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
+\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
+\t\t\t\tRebuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
\t\t\t\tOutput="Test.exe"/>
\t\t</Configuration>
\t</Configurations>
diff --git a/test/MSVS/vs-8.0-files.py b/test/MSVS/vs-8.0-files.py
index 1d3c469..d7aa0d9 100644
--- a/test/MSVS/vs-8.0-files.py
+++ b/test/MSVS/vs-8.0-files.py
@@ -87,9 +87,9 @@ expected_vcprojfile = """\
\t\t\t>
\t\t\t<Tool
\t\t\t\tName="VCNMakeTool"
-\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct Test.exe"
-\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c Test.exe"
+\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
+\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
\t\t\t\tOutput="Test.exe"
\t\t\t\tPreprocessorDefinitions=""
\t\t\t\tIncludeSearchPath=""
diff --git a/test/Parallel/duplicate-children.py b/test/Parallel/duplicate-children.py
new file mode 100644
index 0000000..26d873b
--- /dev/null
+++ b/test/Parallel/duplicate-children.py
@@ -0,0 +1,68 @@
+#!/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__"
+
+"""
+Verify that parallel builds work correctly when a Node is duplicated
+in the children (once in the sources and once in the depends list).
+"""
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+test.write('cat.py', """\
+import sys
+fp = open(sys.argv[1], 'wb')
+for fname in sys.argv[2:]:
+ fp.write(open(fname, 'rb').read())
+fp.close()
+""")
+
+test.write('sleep.py', """\
+import sys
+import time
+time.sleep(int(sys.argv[1]))
+""")
+
+test.write('SConstruct', """
+# Test case for SCons issue #1608
+# Create a file "foo.in" in the current directory before running scons.
+env = Environment()
+env.Command('foo.out', ['foo.in'], '%(_python_)s cat.py $TARGET $SOURCE && %(_python_)s sleep.py 3')
+env.Command('foobar', ['foo.out'], '%(_python_)s cat.py $TARGET $SOURCES')
+env.Depends('foobar', 'foo.out')
+""" % locals())
+
+test.write('foo.in', "foo.in\n")
+
+test.run(arguments = '-j2 .')
+
+test.must_match('foo.out', "foo.in\n")
+test.must_match('foobar', "foo.in\n")
+
+test.pass_test()
diff --git a/test/QT/Tool.py b/test/QT/Tool.py
new file mode 100644
index 0000000..9079225
--- /dev/null
+++ b/test/QT/Tool.py
@@ -0,0 +1,148 @@
+#!/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__"
+
+"""
+Verify that applying env.Tool('qt') after running Configure checks
+works properly. This was broken in 0.96.95.
+
+The configuration here is a moderately stripped-down version of the
+real-world configuration for lprof (lprof.sourceforge.net). It's probably
+not completely minimal, but we're leaving it as since it represents a
+good real-world sanity check on the interaction of some key subsystems.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+import os
+import os.path
+
+def DoWithVariables(variables, prefix, what):
+ saved_variables = { }
+ for name in variables.keys():
+ saved_variables[ name ] = env[ name ][:]
+ env[ name ].append(variables[ name ])
+
+ result = what()
+
+ for name in saved_variables.keys():
+ env[ name ] = saved_variables[ name ]
+ env[ prefix+name ] = variables[ name ]
+
+ return result
+
+def CheckForQtAt(context, qtdir):
+ context.Message('Checking for Qt at %s... ' % qtdir)
+ libp = os.path.join(qtdir, 'lib')
+ cppp = os.path.join(qtdir, 'include')
+ result = AttemptLinkWithVariables(context,
+ { "LIBS": "qt-mt", "LIBPATH": libp , "CPPPATH": cppp },
+ '''
+#include <qapplication.h>
+int main(int argc, char **argv) {
+ QApplication qapp(argc, argv);
+ return 0;
+}
+''',".cpp","QT_")
+ context.Result(result)
+ return result
+
+def CheckForQt(context):
+ # list is currently POSIX centric - what happens with Windows?
+ potential_qt_dirs = [
+ "/usr/share/qt3", # Debian unstable
+ "/usr/share/qt",
+ "/usr",
+ "/usr/local",
+ "/usr/lib/qt3", # Suse
+ "/usr/lib/qt",
+ "/usr/qt/3", # Gentoo
+ "/usr/pkg/qt3" # pkgsrc (NetBSD)
+ ]
+
+ if os.environ.has_key('QTDIR'):
+ potential_qt_dirs.insert(0, os.environ[ 'QTDIR' ])
+
+ if env[ 'qt_directory' ] != "/":
+ uic_path = os.path.join(env['qt_directory'], 'bin', 'uic')
+ if os.path.isfile(uic_path):
+ potential_qt_dirs.insert(0, env[ 'qt_directory' ])
+ else:
+ print "QT not found. Invalid qt_directory value - failed to find uic."
+ return 0
+
+ for i in potential_qt_dirs:
+ context.env.Replace(QTDIR = i)
+ if CheckForQtAt(context, i):
+ # additional checks to validate QT installation
+ if not os.path.isfile(os.path.join(i, 'bin', 'uic')):
+ print "QT - failed to find uic."
+ return 0
+ if not os.path.isfile(os.path.join(i, 'bin', 'moc')):
+ print "QT - failed to find moc."
+ return 0
+ if not os.path.exists(os.path.join(i, 'lib')):
+ print "QT - failed to find QT lib path."
+ return 0
+ if not os.path.exists(os.path.join(i, 'include')):
+ print "QT - failed to find QT include path."
+ return 0
+ return 1
+ else:
+ if i==env['qt_directory']:
+ print "QT directory not valid. Failed QT test build."
+ return 0
+ return 0
+
+def AttemptLinkWithVariables(context, variables, code, extension, prefix):
+ return DoWithVariables(variables,
+ prefix,
+ lambda c=context, code=code, e=extension:
+ c.TryLink(code, e))
+
+env = Environment(CPPPATH=['.'], LIBPATH=['.'], LIBS=[])
+
+opts = Options('lprof.conf')
+opts.Add(PathOption("qt_directory", "Path to Qt directory", "/"))
+opts.Update(env)
+
+env['QT_LIB'] = 'qt-mt'
+config = env.Configure(custom_tests = {
+ 'CheckForQt' : CheckForQt,
+})
+
+if not config.CheckForQt():
+ print "Failed to find valid QT environment."
+ Exit(1)
+
+env.Tool('qt', ['$TOOL_PATH'])
+""")
+
+test.run(arguments = '.')
+
+test.pass_test()
diff --git a/test/TEX/auxiliaries.py b/test/TEX/auxiliaries.py
new file mode 100644
index 0000000..e34ddaa
--- /dev/null
+++ b/test/TEX/auxiliaries.py
@@ -0,0 +1,139 @@
+#!/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__"
+
+"""
+Verify that sections of LaTeX output that use auxiliary files (a
+bibliography in our configuration below) are consistent when re-run
+after modifying the input file.
+
+This checks for a bug that was triggered by the presence of auxiliary
+files which were detected by SCons but then removed prior to invoking
+TeX, causing the auxiliary sections to be excluded from the output.
+That was fixed (courtesy Joel B. Mohler) by making all the relevant
+auxiliary files Precious().
+
+Test configuration courtesy Dmitry Mikhin.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+dvips = test.where_is('dvips')
+latex = test.where_is('latex')
+
+if not dvips or not latex:
+ test.skip_test("Could not find dvips or latex; skipping test(s).\n")
+
+
+test.subdir(['docs'])
+
+test.write(['SConstruct'], """\
+env = Environment(tools = ['pdftex', 'dvipdf', 'dvips', 'tex', 'latex'],
+ ENV = {},
+ BUILD_DIR = '#build/docs')
+
+# Use 'duplicate=1' because LaTeX toolchain does not work properly for
+# input/output files outside of the current directory
+
+env.BuildDir('$BUILD_DIR', 'docs', duplicate=1)
+env.SConscript('$BUILD_DIR/SConscript', exports = ['env'])
+""")
+
+test.write(['docs', 'SConscript'], """\
+Import('env')
+envc = env.Clone()
+
+test_dvi = envc.DVI(source='test.tex')
+test_ps = envc.PostScript(source='test.tex')
+test_pdf = envc.PDF(source='test.tex')
+
+envc.Default(test_dvi)
+envc.Default(test_ps)
+envc.Default(test_pdf)
+""")
+
+test.write(['docs', 'my.bib'], """\
+@ARTICLE{Mikhin,
+ author = "Dmitry {\uppercase{Y}u}. Mikhin",
+ title = "Blah!",
+ journal = "Some yellow paper",
+ year = "2007",
+ volume = "7",
+ number = "3",
+ pages = "1--2"
+}
+""")
+
+tex_input = r"""\documentclass{article}
+
+\title{BUG IN SCONS}
+
+\author{Dmitry Yu. Mikhin}
+
+\begin{document}
+
+\maketitle
+
+
+\begin{abstract}
+\noindent A bug in BibTeX processing?
+\end{abstract}
+
+
+\section{The problem}
+
+Provide a citation here: \cite{Mikhin}.
+
+
+\bibliography{my}
+\bibliographystyle{unsrtnat}
+
+\end{document}
+"""
+
+test.write(['docs', 'test.tex'], tex_input)
+
+test.run(stderr=None)
+
+pdf_output_1 = test.read(['build', 'docs', 'test.pdf'])
+ps_output_1 = test.read(['build', 'docs', 'test.ps'])
+
+# Adding blank lines will cause SCons to re-run the builds, but the
+# actual contents of the output files shouldn't be any different.
+# This assumption won't work if it's ever used with a toolchain that does
+# something to the output like put a commented-out timestamp in a header.
+test.write(['docs', 'test.tex'], tex_input + "\n\n\n")
+
+test.run(stderr=None)
+
+pdf_output_2 = test.read(['build', 'docs', 'test.pdf'])
+ps_output_2 = test.read(['build', 'docs', 'test.ps'])
+
+test.fail_test(pdf_output_1 != pdf_output_2)
+test.fail_test(ps_output_1 != ps_output_2)
+
+test.pass_test()
diff --git a/test/TEX/bibtex-latex-rerun.py b/test/TEX/bibtex-latex-rerun.py
new file mode 100644
index 0000000..2293216
--- /dev/null
+++ b/test/TEX/bibtex-latex-rerun.py
@@ -0,0 +1,99 @@
+#!/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__"
+
+"""
+Verify that we re-run LaTeX after running BibTeX in response to
+changes in a .bib file.
+
+Thanks to Rob Managan for the patch that fixed this, and to Joel B. Mohler
+for code clean up and packaging the test case.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write(['SConstruct'], """\
+PDF( 'bibtest.tex' )
+""")
+
+test.write(['bibtest.tex'], r"""
+\documentclass{article}
+\begin{document}
+Learn about cool math in \cite{koblitz:elliptic_curves}.
+\bibliographystyle{alpha}
+\bibliography{sources}
+\end{document}
+""")
+
+sources_bib_content = r"""
+@book{koblitz:elliptic_curves,
+ author = "Neal Koblitz",
+ title = "Elliptic Curves and Modular Forms",
+ year = "%s",
+ publisher = "Springer-Verlag New York Inc."
+}
+"""
+
+
+
+test.write('sources.bib', sources_bib_content % '1981')
+
+test.run()
+
+pdf_output_1 = test.read('bibtest.pdf')
+
+
+
+test.write('sources.bib', sources_bib_content % '1982')
+
+test.run()
+
+pdf_output_2 = test.read('bibtest.pdf')
+
+# If the PDF file is the same as it was previously, then it didn't
+# pick up the change from 1981 to 1982, so fail.
+test.fail_test(pdf_output_1 == pdf_output_2)
+
+
+
+# Double-check: clean everything and rebuild from scratch, which
+# should force the PDF file to be the 1982 version.
+
+test.run(arguments = '-c')
+
+test.run()
+
+pdf_output_3 = test.read('bibtest.pdf')
+
+# If the PDF file is now different than the second run, then something
+# else odd has happened, so fail. (Note that this test will be incorrect
+# if the tool does something like insert a timestamp in the PDF file.)
+test.fail_test(pdf_output_2 != pdf_output_3)
+
+
+
+test.pass_test()
diff --git a/test/TEX/multi-run.py b/test/TEX/multi-run.py
index f827ac9..d4e2d79 100644
--- a/test/TEX/multi-run.py
+++ b/test/TEX/multi-run.py
@@ -42,7 +42,7 @@ latex = test.where_is('latex')
if not tex and not latex:
test.skip_test("Could not find tex or latex; skipping test(s).\n")
-test.subdir('work1', 'work2')
+test.subdir('work1', 'work2', 'work4')
input_file = r"""
@@ -55,6 +55,15 @@ As stated in \cite{X}, this is a bug-a-boo.
\end{document}
"""
+input_file2 = r"""
+\documentclass{article}
+\begin{document}
+Hello world.
+% \bibliography{fooref}
+% \bibliographystyle{plain}
+\end{document}
+"""
+
bibfile = r"""
@Article{X,
author = "Mr. X",
@@ -86,6 +95,8 @@ PDF( "foo.tex" )
print foo_log
test.fail_test(1)
+
+
if latex:
test.write(['work2', 'SConstruct'], """\
@@ -106,4 +117,16 @@ PDF( "foo.ltx" )
print foo_log
test.fail_test(1)
+
+
+ test.write(['work4', 'SConstruct'], """\
+DVI( "foo.ltx" )
+""")
+ test.write(['work4', 'foo.ltx'], input_file2)
+
+ test.run(chdir = 'work4', arguments = '.')
+
+ test.up_to_date(chdir = 'work4', arguments = '.')
+
+
test.pass_test()
diff --git a/test/gnutools.py b/test/gnutools.py
index 4bcea00..2180217 100644
--- a/test/gnutools.py
+++ b/test/gnutools.py
@@ -31,10 +31,13 @@ Testing the gnu tool chain, i.e. the tools 'gcc', 'g++' and 'gnulink'.
import TestSCons
import string
import sys
+
_python_ = TestSCons._python_
_exe = TestSCons._exe
-_dll = TestSCons._dll
-dll_ = TestSCons.dll_
+
+def dll(s):
+ return TestSCons.dll_ + s + TestSCons._dll
+
test = TestSCons.TestSCons()
test.subdir('gnutools')
@@ -111,40 +114,32 @@ env.SharedLibrary('c-and-cpp', Split('cfile1.c cppfile1.cpp'))
test.run(chdir='work1')
-def testObject(test, obj, command, flags):
+def testObject(test, obj, expect):
contents = test.read(test.workpath('work1', obj))
line1 = string.split(contents,'\n')[0]
- items = string.split(line1, ' ')
- cmd = ''
- for i in items:
- if i != '':
- if cmd:
- cmd = cmd + ' ' + i
- else:
- cmd = i
- res = ((flags and (cmd == command + ' ' + flags)) or
- (not flags and (cmd == command)))
- if not res: print "'"+obj+command+flags+"'"+"!='"+str(line1)+"'"
- return res
-
-if sys.platform == 'cygwin':
- fpic = ''
+ actual = string.join(string.split(line1))
+ if not expect == actual:
+ print "%s: %s != %s\n" % (obj, repr(expect), repr(actual))
+ test.fail_test()
+
+if sys.platform in ('win32', 'cygwin'):
+ c_fpic = ''
else:
- fpic = ' -fPIC'
-
-test.fail_test(not testObject(test, 'cfile1.o', 'gcc', '-c') or
- not testObject(test, 'cfile2.o', 'gcc', '-c') or
- not testObject(test, 'cppfile1.o', 'g++', '-c') or
- not testObject(test, 'cppfile2.o', 'g++', '-c') or
- not testObject(test, 'cfile1.os', 'gcc', '-c' + fpic) or
- not testObject(test, 'cfile2.os', 'gcc', '-c' + fpic) or
- not testObject(test, 'cppfile1.os', 'g++', '-c' + fpic) or
- not testObject(test, 'cppfile2.os', 'g++', '-c' + fpic) or
- not testObject(test, 'c-only' + _exe, 'gcc', '') or
- not testObject(test, 'cpp-only' + _exe, 'g++', '') or
- not testObject(test, 'c-and-cpp' + _exe, 'g++', '') or
- not testObject(test, dll_ + 'c-only' + _dll, 'gcc', '-shared') or
- not testObject(test, dll_ + 'cpp-only' + _dll, 'g++', '-shared') or
- not testObject(test, dll_ + 'c-and-cpp' + _dll, 'g++', '-shared'))
+ c_fpic = ' -fPIC'
+
+testObject(test, 'cfile1.o', 'gcc -c')
+testObject(test, 'cfile2.o', 'gcc -c')
+testObject(test, 'cppfile1.o', 'g++ -c')
+testObject(test, 'cppfile2.o', 'g++ -c')
+testObject(test, 'cfile1.os', 'gcc -c' + c_fpic)
+testObject(test, 'cfile2.os', 'gcc -c' + c_fpic)
+testObject(test, 'cppfile1.os', 'g++ -c -fPIC')
+testObject(test, 'cppfile2.os', 'g++ -c -fPIC')
+testObject(test, 'c-only' + _exe, 'gcc')
+testObject(test, 'cpp-only' + _exe, 'g++')
+testObject(test, 'c-and-cpp' + _exe, 'g++')
+testObject(test, dll('c-only'), 'gcc -shared')
+testObject(test, dll('cpp-only'), 'g++ -shared')
+testObject(test, dll('c-and-cpp'), 'g++ -shared')
test.pass_test()
diff --git a/test/import.py b/test/import.py
index 92797df..d267f00 100644
--- a/test/import.py
+++ b/test/import.py
@@ -52,6 +52,7 @@ platforms = [
for platform in platforms:
test.write('SConstruct', """
+print "Platform %(platform)s"
env = Environment(platform = '%(platform)s')
import SCons.Platform.%(platform)s
x = SCons.Platform.%(platform)s.generate
@@ -198,6 +199,7 @@ error_output = {
# An SConstruct for importing Tool names that have illegal characters
# for Python variable names.
indirect_import = """\
+print "Tool %(tool)s (indirect)"
env = Environment(tools = ['%(tool)s'])
SCons = __import__('SCons.Tool.%(tool)s', globals(), locals(), [])
@@ -208,6 +210,7 @@ m.generate(env)
# An SConstruct for importing Tool names "normally."
direct_import = """\
+print "Tool %(tool)s (direct)"
env = Environment(tools = ['%(tool)s'])
import SCons.Tool.%(tool)s
diff --git a/test/option/debug-pdb.py b/test/option/debug-pdb.py
new file mode 100644
index 0000000..fa703d5
--- /dev/null
+++ b/test/option/debug-pdb.py
@@ -0,0 +1,41 @@
+#!/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 string
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """\
+env = Environment()
+""")
+
+test.run(arguments = "--debug=pdb", stdin = "n\ns\nq\n")
+test.fail_test(string.find(test.stdout(), "(Pdb)") == -1)
+test.fail_test(string.find(test.stdout(), "SCons") == -1)
+
+test.pass_test()
diff --git a/test/option--debug.py b/test/option/debug-presub.py
index a56f261..cdbefbd 100644
--- a/test/option--debug.py
+++ b/test/option/debug-presub.py
@@ -24,60 +24,12 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import sys
-import string
-import re
-import time
-
import TestSCons
_python_ = TestSCons._python_
test = TestSCons.TestSCons()
-test.write('SConstruct', """
-env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
-env.Program('foo', Split('foo.c bar.c'))
-""")
-
-test.write('foo.c', r"""
-#include "foo.h"
-int main(int argc, char *argv[])
-{
- argv[argc++] = "--";
- printf("f1.c\n");
- exit (0);
-}
-""")
-
-test.write('bar.c', """
-#include "bar.h"
-""")
-
-test.write('foo.h', """
-#ifndef FOO_H
-#define FOO_H
-#include "bar.h"
-#endif
-""")
-
-test.write('bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "foo.h"
-#endif
-""")
-
-############################
-# test --debug=pdb
-
-test.run(arguments = "--debug=pdb", stdin = "n\ns\nq\n")
-test.fail_test(string.find(test.stdout(), "(Pdb)") == -1)
-test.fail_test(string.find(test.stdout(), "SCons") == -1)
-
-############################
-# test --debug=presub
-
test.write('cat.py', """\
import sys
open(sys.argv[2], "wb").write(open(sys.argv[1], "rb").read())
@@ -96,7 +48,7 @@ FILE = Builder(action="$FILECOM")
TEMP = Builder(action="$TEMPCOM")
LIST = Builder(action="$LISTCOM")
FUNC = Builder(action=cat)
-env = Environment(PYTHON='%(_python_)s',
+env = Environment(PYTHON=r'%(_python_)s',
BUILDERS = {'FILE':FILE, 'TEMP':TEMP, 'LIST':LIST, 'FUNC':FUNC},
FILECOM="$PYTHON cat.py $SOURCES $TARGET",
TEMPCOM="$PYTHON cat.py $SOURCES temp\\n$PYTHON cat.py temp $TARGET",
@@ -119,6 +71,10 @@ env.LIST('file15.out', 'file15.in')
env.LIST('file16.out', 'file16.in')
env.FUNC('file17.out', 'file17.in')
env.FUNC('file18.out', 'file18.in')
+
+env2 = Environment(PYTHON=r'%(_python_)s',
+ CCCOM="$PYTHON cat.py $SOURCES $TARGET")
+env2.Object('file20.obj', 'file20.c')
""" % locals())
test.write('file01.in', "file01.in\n")
@@ -139,6 +95,8 @@ test.write('file16.in', "file16.in\n")
test.write('file17.in', "file17.in\n")
test.write('file18.in', "file18.in\n")
+test.write('file20.c', "file20.c\n")
+
expect = """\
Building file01.out with action:
$PYTHON cat.py $SOURCES $TARGET
@@ -215,6 +173,9 @@ cat(["file17.out"], ["file17.in"])
Building file18.out with action:
cat(target, source, env)
cat(["file18.out"], ["file18.in"])
+Building file20.obj with action:
+ $PYTHON cat.py $SOURCES $TARGET
+%(_python_)s cat.py file20.c file20.obj
""" % locals()
test.run(arguments = "--debug=presub .", stdout=test.wrap_stdout(expect))
@@ -237,4 +198,6 @@ test.must_match('file16.out', "file16.in\n")
test.must_match('file17.out', "file17.in\n")
test.must_match('file18.out', "file18.in\n")
+test.must_match('file20.obj', "file20.c\n")
+
test.pass_test()
diff --git a/test/option/debug-time.py b/test/option/debug-time.py
index b1471ba..51cfacf 100644
--- a/test/option/debug-time.py
+++ b/test/option/debug-time.py
@@ -30,49 +30,51 @@ import string
import re
import time
+_python_ = TestSCons._python_
+
test = TestSCons.TestSCons()
-test.write('SConstruct', """
-env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
-env.Program('foo', Split('foo.c bar.c'))
+test.write('sleep_cat.py', """\
+import sys
+import time
+time.sleep(int(sys.argv[1]))
+fp = open(sys.argv[2], 'wb')
+for arg in sys.argv[3:]:
+ fp.write(open(arg, 'rb').read())
+fp.close()
+sys.exit(0)
""")
-test.write('foo.c', r"""
-#include <stdio.h>
-#include <stdlib.h>
-#include "foo.h"
-int main(int argc, char *argv[])
-{
- argv[argc++] = "--";
- printf("f1.c\n");
- exit (0);
-}
-""")
+test.write('SConstruct', """
+env = Environment(PYTHON = r'%(_python_)s',
+ SLEEP_CAT = r'sleep_cat.py',
+ CATCOM = '$PYTHON $SLEEP_CAT $SECONDS $TARGET $SOURCES',
+ SECONDS = ARGUMENTS.get('SLEEP', '0'))
+f1 = env.Command('f1.out', 'f1.in', '$CATCOM')
+f2 = env.Command('f2.out', 'f2.in', '$CATCOM')
+f3 = env.Command('f3.out', 'f3.in', '$CATCOM')
+f4 = env.Command('f4.out', 'f4.in', '$CATCOM')
+env.Command('output', [f1, f2, f3, f4], '$CATCOM')
+""" % locals())
-test.write('bar.c', """
-#include "bar.h"
-""")
+test.write('f1.in', "f1.in\n")
+test.write('f2.in', "f2.in\n")
+test.write('f3.in', "f3.in\n")
+test.write('f4.in', "f4.in\n")
-test.write('foo.h', """
-#ifndef FOO_H
-#define FOO_H
-#include "bar.h"
-#endif
-""")
-test.write('bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "foo.h"
-#endif
-""")
-def num(match, line):
- return float(re.search(match, line).group(1))
+def num(s, match):
+ return float(re.search(match, s).group(1))
+
+def within_tolerance(expected, actual, tolerance):
+ return abs((expected-actual)/actual) <= tolerance
+
+
-# Try to make things a little more equal by measuring Python overhead
-# executing a minimal file, and reading the scons.py script itself from
-# disk so that it's already been cached.
+# Try to make our results a little more accurate and repeatable by
+# measuring Python overhead executing a minimal file, and reading the
+# scons.py script itself from disk so that it's already been cached.
test.write('pass.py', "pass\n")
test.read(test.program)
@@ -80,55 +82,85 @@ start_time = time.time()
test.run(program=TestSCons.python, arguments=test.workpath('pass.py'))
overhead = time.time() - start_time
+
+
start_time = time.time()
-test.run(arguments = "--debug=time .")
+test.run(arguments = "-j1 --debug=time . SLEEP=0")
complete_time = time.time() - start_time
+
+
expected_total_time = complete_time - overhead
-lines = string.split(test.stdout(), '\n')
-expected_command_time = 0.0
-for cmdline in filter(lambda x: x[:23] == "Command execution time:", lines):
- n = num(r'Command execution time: (\d+\.\d+) seconds', cmdline)
- expected_command_time = expected_command_time + n
+pattern = r'Command execution time: (\d+\.\d+) seconds'
+times = map(float, re.findall(pattern, test.stdout()))
+expected_command_time = reduce(lambda x, y: x + y, times, 0.0)
-stdout = test.stdout()
-total_time = num(r'Total build time: (\d+\.\d+) seconds', stdout)
-sconscript_time = num(r'Total SConscript file execution time: (\d+\.\d+) seconds', stdout)
-scons_time = num(r'Total SCons execution time: (\d+\.\d+) seconds', stdout)
-command_time = num(r'Total command execution time: (\d+\.\d+) seconds', stdout)
+stdout = test.stdout()
-def within_tolerance(expected, actual, tolerance):
- return abs((expected-actual)/actual) <= tolerance
+total_time = num(stdout, r'Total build time: (\d+\.\d+) seconds')
+sconscript_time = num(stdout, r'Total SConscript file execution time: (\d+\.\d+) seconds')
+scons_time = num(stdout, r'Total SCons execution time: (\d+\.\d+) seconds')
+command_time = num(stdout, r'Total command execution time: (\d+\.\d+) seconds')
failures = []
if not within_tolerance(expected_command_time, command_time, 0.01):
failures.append("""\
-SCons reported a total command execution time of %s,
-but command execution times really totalled %s,
+SCons -j1 reported a total command execution time of %(command_time)s,
+but command execution times really totalled %(expected_command_time)s,
outside of the 1%% tolerance.
-""" % (command_time, expected_command_time))
+""" % locals())
added_times = sconscript_time+scons_time+command_time
if not within_tolerance(total_time, added_times, 0.01):
failures.append("""\
-SCons reported a total build time of %s,
-but the various execution times actually totalled %s,
+SCons -j1 reported a total build time of %(total_time)s,
+but the various execution times actually totalled %(added_times)s,
outside of the 1%% tolerance.
-""" % (total_time, added_times))
+""" % locals())
if not within_tolerance(total_time, expected_total_time, 0.15):
failures.append("""\
-SCons reported total build time of %s,
-but the actual measured build time was %s
-(end-to-end time of %s less Python overhead of %s),
+SCons -j1 reported total build time of %(total_time)s,
+but the actual measured build time was %(expected_total_time)s
+(end-to-end time of %(complete_time)s less Python overhead of %(overhead)s),
outside of the 15%% tolerance.
-""" % (total_time, expected_total_time, complete_time, overhead))
+""" % locals())
if failures:
print string.join([test.stdout()] + failures, '\n')
test.fail_test(1)
+
+
+test.run(arguments = "-c")
+
+test.run(arguments = "-j4 --debug=time . SLEEP=1")
+
+
+
+stdout = test.stdout()
+
+total_time = num(stdout, r'Total build time: (\d+\.\d+) seconds')
+sconscript_time = num(stdout, r'Total SConscript file execution time: (\d+\.\d+) seconds')
+scons_time = num(stdout, r'Total SCons execution time: (\d+\.\d+) seconds')
+command_time = num(stdout, r'Total command execution time: (\d+\.\d+) seconds')
+
+failures = []
+
+added_times = sconscript_time+scons_time+command_time
+if not within_tolerance(total_time, added_times, 0.01):
+ failures.append("""\
+SCons -j4 reported a total build time of %(total_time)s,
+but the various execution times actually totalled %(added_times)s,
+outside of the 1%% tolerance.
+""" % locals())
+
+if failures:
+ print string.join([test.stdout()] + failures, '\n')
+ test.fail_test(1)
+
+
test.pass_test()
diff --git a/test/site_scons/no-site-dir.py b/test/site_scons/no-site-dir.py
index 6f2f26e..3fc5a6d 100644
--- a/test/site_scons/no-site-dir.py
+++ b/test/site_scons/no-site-dir.py
@@ -71,9 +71,14 @@ e=Environment()
print e.subst('no site: M4 is $M4, M4_MINE is $M4_MINE')
""")
-test.run(arguments = '-Q --no-site-dir .',
-stdout = """no site: M4 is m4, M4_MINE is
-scons: `.' is up to date.\n""")
+test.run(arguments = '-Q --no-site-dir .')
+
+not_expected = """Hi there, I am in site_scons/site_init.py!
+no site: M4 is my_m4, M4_MINE is 1
+scons: `.' is up to date.
+"""
+
+test.fail_test(test.stdout() == not_expected)
diff --git a/test/site_scons/sys-path.py b/test/site_scons/sys-path.py
new file mode 100644
index 0000000..7af45aa
--- /dev/null
+++ b/test/site_scons/sys-path.py
@@ -0,0 +1,65 @@
+#!/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__"
+
+"""
+Verify that the site_scons dir is added to sys.path as an
+absolute path, so it will work from a subdir.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('site_scons')
+test.subdir('sub1')
+
+test.write(['site_scons', 'testmod1.py'], """
+print "Imported site_scons/testmod1.py."
+""")
+test.write(['site_scons', 'testmod2.py'], """
+print "Imported site_scons/testmod2.py."
+""")
+
+test.write(['sub1', 'SConscript'], """
+import sys
+import testmod2 # This call did not work before the fix
+
+""")
+
+test.write('SConstruct', """
+import sys
+import testmod1 # this always worked
+SConscript('sub1/SConscript')
+""")
+
+test.run(arguments = '-Q .',
+ stdout = """Imported site_scons/testmod1.py.
+Imported site_scons/testmod2.py.
+scons: `.' is up to date.\n""")
+
+test.pass_test()
+
+# end of file