diff options
394 files changed, 8431 insertions, 2960 deletions
diff --git a/HOWTO/release.txt b/HOWTO/release.txt index 397033a..88f9352 100644 --- a/HOWTO/release.txt +++ b/HOWTO/release.txt @@ -93,8 +93,8 @@ Things to do to release a new X.Y version of SCons: aecp rpm/scons.spec.in vi rpm/scons.spec.in - aecp src/test_setup.py - vi src/test_setup.py + aecp QMTest/TestSCons.py + vi QMTest/TestSCons.py # Read through and update the README files if necessary [optional] aecp README diff --git a/HOWTO/subrelease.txt b/HOWTO/subrelease.txt index fb799e6..6826c81 100644 --- a/HOWTO/subrelease.txt +++ b/HOWTO/subrelease.txt @@ -39,8 +39,8 @@ Things to do to release a new X.Y.Z version of SCons: aecp src/setup.py vi src/setup.py - aecp src/test_setup.py - vi src/test_setup.py + aecp QMTest/TestSCons.py + vi QMTest/TestSCons.py # Read through and update the README files if necessary [optional] aecp README diff --git a/QMTest/TestRuntest.py b/QMTest/TestRuntest.py index a4bcd05..9452746 100644 --- a/QMTest/TestRuntest.py +++ b/QMTest/TestRuntest.py @@ -27,9 +27,11 @@ from TestCommon import __all__ __all__.extend([ 'TestRuntest', 'python', + '_python_', ]) python = python_executable +_python_ = '"' + python_executable + '"' failing_test_template = """\ @@ -53,6 +55,22 @@ sys.stderr.write('PASSING TEST STDERR\\n') sys.exit(0) """ +fake_scons_py = """ +__version__ = '1.2.3' +__build__ = 'D123' +__buildsys__ = 'fake_system' +__date__ = 'Jan 1 1970' +__developer__ = 'Anonymous' +""" + +fake___init___py = """ +__version__ = '4.5.6' +__build__ = 'D456' +__buildsys__ = 'another_fake_system' +__date__ = 'Dec 31 1999' +__developer__ = 'John Doe' +""" + class TestRuntest(TestCommon): """Class for testing the runtest.py script. @@ -91,15 +109,28 @@ class TestRuntest(TestCommon): kw['match'] = match_exact if not kw.has_key('workdir'): kw['workdir'] = '' + + try: + noqmtest = kw['noqmtest'] + except KeyError: + noqmtest = 0 + else: + del kw['noqmtest'] + orig_cwd = os.getcwd() apply(TestCommon.__init__, [self], kw) + + if not noqmtest: + qmtest_py = self.where_is('qmtest.py') + if not qmtest_py: + self.skip_test("Could not find 'qmtest.py'; skipping test(s).\n") things_to_copy = [ 'runtest.py', 'QMTest', ] - dirs = [orig_cwd] + dirs = [os.environ.get('SCONS_RUNTEST_DIR', orig_cwd)] spe = os.environ.get('SCONS_SOURCE_PATH_EXECUTABLE', orig_cwd) for d in string.split(spe, os.pathsep): @@ -127,6 +158,47 @@ class TestRuntest(TestCommon): os.environ['PYTHONPATH'] = '' os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = '' + def skip_test(self, message="Skipping test.\n"): + """Skips a test. + + Proper test-skipping behavior is dependent on whether we're being + executed as part of development of a change under Aegis. + + Technically, skipping a test is a NO RESULT, but Aegis will + treat that as a test failure and prevent the change from going + to the next step. We don't want to force anyone using Aegis + to have to install absolutely every tool used by the tests, + so we actually report to Aegis that a skipped test has PASSED + so that the workflow isn't held up. + """ + if message: + sys.stdout.write(message) + sys.stdout.flush() + devdir = os.popen("aesub '$dd' 2>/dev/null", "r").read()[:-1] + intdir = os.popen("aesub '$intd' 2>/dev/null", "r").read()[:-1] + if devdir and self._cwd[:len(devdir)] == devdir or \ + intdir and self._cwd[:len(intdir)] == intdir: + # We're under the development directory for this change, + # so this is an Aegis invocation; pass the test (exit 0). + self.pass_test() + else: + # skip=1 means skip this function when showing where this + # result came from. They only care about the line where the + # script called test.skip_test(), not the line number where + # we call test.no_result(). + self.no_result(skip=1) + + def write_fake_scons_source_tree(self): + os.mkdir('src') + os.mkdir('src/script') + self.write('src/script/scons.py', fake_scons_py) + + os.mkdir('src/engine') + os.mkdir('src/engine/SCons') + self.write('src/engine/SCons/__init__.py', fake___init___py) + os.mkdir('src/engine/SCons/Script') + self.write('src/engine/SCons/Script/__init__.py', fake___init___py) + def write_failing_test(self, name): self.write(name, failing_test_template) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 0904d31..de15526 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -24,6 +24,14 @@ import sys from TestCommon import * from TestCommon import __all__ +# Some tests which verify that SCons has been packaged properly need to +# look for specific version file names. Replicating the version number +# here provides independent verification that what we packaged conforms +# to what we expect. (If we derived the version number from the same +# data driving the build we might miss errors if the logic breaks.) + +SConsVersion = '0.96.92' + __all__.extend([ 'TestSCons', 'python', '_exe', @@ -36,6 +44,7 @@ __all__.extend([ 'TestSCons', ]) python = python_executable +_python_ = '"' + python_executable + '"' _exe = exe_suffix _obj = obj_suffix _shobj = shobj_suffix @@ -105,6 +114,8 @@ class TestSCons(TestCommon): initializations. """ + scons_version = SConsVersion + def __init__(self, **kw): """Initialize an SCons testing object. @@ -398,12 +409,12 @@ void my_qt_symbol(const char *arg) { } """) - self.write(['qt', 'lib', 'SConstruct'], r""" + self.write([dir, 'lib', 'SConstruct'], r""" env = Environment() -env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) +env.SharedLibrary( 'myqt', 'my_qobject.cpp' ) """) - self.run(chdir = self.workpath('qt', 'lib'), + self.run(chdir = self.workpath(dir, 'lib'), arguments = '.', stderr = noisy_ar, match = self.match_re_dotall) @@ -412,6 +423,7 @@ env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) self.QT_LIB = 'myqt' self.QT_MOC = '%s %s' % (python, self.workpath(dir, 'bin', 'mymoc.py')) self.QT_UIC = '%s %s' % (python, self.workpath(dir, 'bin', 'myuic.py')) + self.QT_LIB_DIR = self.workpath(dir, 'lib') def Qt_create_SConstruct(self, place): if type(place) is type([]): diff --git a/QMTest/classes.qmc b/QMTest/classes.qmc index 73e3df3..88de061 100644 --- a/QMTest/classes.qmc +++ b/QMTest/classes.qmc @@ -8,4 +8,5 @@ <class kind="result_stream" name="scons_tdb.AegisChangeStream"/> <class kind="result_stream" name="scons_tdb.AegisBaselineStream"/> <class kind="result_stream" name="scons_tdb.AegisBatchStream"/> + <class kind="result_stream" name="scons_tdb.SConsXMLResultStream"/> </class-directory> diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py index 145c2a7..e0d7683 100644 --- a/QMTest/scons_tdb.py +++ b/QMTest/scons_tdb.py @@ -46,9 +46,13 @@ from qm.test import suite from qm.test.result import Result from qm.test.file_result_stream import FileResultStream from qm.test.classes.text_result_stream import TextResultStream +from qm.test.classes.xml_result_stream import XMLResultStream from qm.test.directory_suite import DirectorySuite from qm.extension import get_extension_class_name, get_class_arguments_as_dictionary -import os, dircache + +import dircache +import os +import imp if sys.platform == 'win32': console = 'con' @@ -128,62 +132,145 @@ def check_exit_status(result, prefix, desc, status): return True -# XXX I'd like to annotate the overall test run with the following -# information about the Python version, SCons version, and environment. -# Not sure how to do that yet; ask Stefan. -# -# sys_keys = ['byteorder', 'exec_prefix', 'executable', 'maxint', 'maxunicode', 'platform', 'prefix', 'version', 'version_info'] - -# " <%s>" % tag -# " <version>%s</version>" % module.__version__ -# " <build>%s</build>" % module.__build__ -# " <buildsys>%s</buildsys>" % module.__buildsys__ -# " <date>%s</date>" % module.__date__ -# " <developer>%s</developer>" % module.__developer__ -# " </%s>" % tag - -# " <scons>" -# print_version_info("script", scons) -# print_version_info("engine", SCons) -# " </scons>" - -# environ_keys = [ -# 'PATH', -# 'SCONSFLAGS', -# 'SCONS_LIB_DIR', -# 'PYTHON_ROOT', -# 'QTDIR', -# -# 'COMSPEC', -# 'INTEL_LICENSE_FILE', -# 'INCLUDE', -# 'LIB', -# 'MSDEVDIR', -# 'OS', -# 'PATHEXT', -# 'SYSTEMROOT', -# 'TEMP', -# 'TMP', -# 'USERNAME', -# 'VXDOMNTOOLS', -# 'WINDIR', -# 'XYZZY' -# -# 'ENV', -# 'HOME', -# 'LANG', -# 'LANGUAGE', -# 'LOGNAME', -# 'MACHINE', -# 'OLDPWD', -# 'PWD', -# 'OPSYS', -# 'SHELL', -# 'TMPDIR', -# 'USER', -# ] + + +class Null: + pass + +_null = Null() + +sys_attributes = [ + 'byteorder', + 'exec_prefix', + 'executable', + 'maxint', + 'maxunicode', + 'platform', + 'prefix', + 'version', + 'version_info', +] + +def get_sys_values(): + sys_attributes.sort() + result = map(lambda k: (k, getattr(sys, k, _null)), sys_attributes) + result = filter(lambda t: not t[1] is _null, result) + result = map(lambda t: t[0] + '=' + repr(t[1]), result) + return string.join(result, '\n ') + +module_attributes = [ + '__version__', + '__build__', + '__buildsys__', + '__date__', + '__developer__', +] + +def get_module_info(module): + module_attributes.sort() + result = map(lambda k: (k, getattr(module, k, _null)), module_attributes) + result = filter(lambda t: not t[1] is _null, result) + result = map(lambda t: t[0] + '=' + repr(t[1]), result) + return string.join(result, '\n ') + +environ_keys = [ + 'PATH', + 'SCONS', + 'SCONSFLAGS', + 'SCONS_LIB_DIR', + 'PYTHON_ROOT', + 'QTDIR', + + 'COMSPEC', + 'INTEL_LICENSE_FILE', + 'INCLUDE', + 'LIB', + 'MSDEVDIR', + 'OS', + 'PATHEXT', + 'SYSTEMROOT', + 'TEMP', + 'TMP', + 'USERNAME', + 'VXDOMNTOOLS', + 'WINDIR', + 'XYZZY' + + 'ENV', + 'HOME', + 'LANG', + 'LANGUAGE', + 'LC_ALL', + 'LC_MESSAGES', + 'LOGNAME', + 'MACHINE', + 'OLDPWD', + 'PWD', + 'OPSYS', + 'SHELL', + 'TMPDIR', + 'USER', +] + +def get_environment(): + environ_keys.sort() + result = map(lambda k: (k, os.environ.get(k, _null)), environ_keys) + result = filter(lambda t: not t[1] is _null, result) + result = map(lambda t: t[0] + '-' + t[1], result) + return string.join(result, '\n ') + +class SConsXMLResultStream(XMLResultStream): + def __init__(self, *args, **kw): + super(SConsXMLResultStream, self).__init__(*args, **kw) + def WriteAllAnnotations(self, context): + # Load (by hand) the SCons modules we just unwrapped so we can + # extract their version information. Note that we have to override + # SCons.Script.main() with a do_nothing() function, because loading up + # the 'scons' script will actually try to execute SCons... + + src_engine = os.environ.get('SCONS_LIB_DIR') + if not src_engine: + src_engine = os.path.join('src', 'engine') + fp, pname, desc = imp.find_module('SCons', [src_engine]) + SCons = imp.load_module('SCons', fp, pname, desc) + + # Override SCons.Script.main() with a do-nothing function, because + # loading the 'scons' script will actually try to execute SCons... + + src_engine_SCons = os.path.join(src_engine, 'SCons') + fp, pname, desc = imp.find_module('Script', [src_engine_SCons]) + SCons.Script = imp.load_module('Script', fp, pname, desc) + def do_nothing(): + pass + SCons.Script.main = do_nothing + + scons_file = os.environ.get('SCONS') + if scons_file: + src_script, scons_py = os.path.split(scons_file) + scons = os.path.splitext(scons_py)[0] + else: + src_script = os.path.join('src', 'script') + scons = 'scons' + fp, pname, desc = imp.find_module(scons, [src_script]) + scons = imp.load_module('scons', fp, pname, desc) + fp.close() + + self.WriteAnnotation("scons_test.engine", get_module_info(SCons)) + self.WriteAnnotation("scons_test.script", get_module_info(scons)) + + self.WriteAnnotation("scons_test.sys", get_sys_values()) + self.WriteAnnotation("scons_test.os.environ", get_environment()) class AegisStream(TextResultStream): + arguments = [ + qm.fields.IntegerField( + name = "print_time", + title = "print individual test times", + description = """ + """, + default_value = 0, + ), + ] def __init__(self, *args, **kw): super(AegisStream, self).__init__(*args, **kw) self._num_tests = 0 @@ -227,7 +314,7 @@ class AegisStream(TextResultStream): self._DisplayText(result["Test.stderr"]) except KeyError: pass - if result["Test.print_time"] != "0": + if self.print_time: start = float(result['qmtest.start_time']) end = float(result['qmtest.end_time']) fmt = " Total execution time: %.1f seconds\n\n" @@ -296,18 +383,7 @@ class AegisBaselineStream(AegisStream): ) class AegisBatchStream(FileResultStream): - arguments = [ - qm.fields.TextField( - name = "results_file", - title = "Aegis Results File", - description = """ - """, - verbatim = "true", - default_value = "aegis-results.txt", - ), - ] def __init__(self, arguments): - self.filename = arguments['results_file'] super(AegisBatchStream, self).__init__(arguments) self._outcomes = {} def WriteResult(self, result): @@ -320,7 +396,11 @@ class AegisBatchStream(FileResultStream): self._outcomes[test_id] = exit_status def Summarize(self): self.file.write('test_result = [\n') - for file_name, exit_status in self._outcomes.items(): + file_names = self._outcomes.keys() + file_names.sort() + for file_name in file_names: + exit_status = self._outcomes[file_name] + file_name = string.replace(file_name, '\\', '/') self.file.write(' { file_name = "%s";\n' % file_name) self.file.write(' exit_status = %s; },\n' % exit_status) self.file.write('];\n') @@ -349,9 +429,8 @@ class Test(AegisTest): and fails otherwise. The program output is logged, but not validated.""" command = RedirectedExecutable() - args = [context.get('python', 'python'), self.script] + args = [context.get('python', sys.executable), self.script] status = command.Run(args, os.environ) - result["Test.print_time"] = context.get('print_time', '0') if not check_exit_status(result, 'Test.', self.script, status): # In case of failure record exit code, stdout, and stderr. result.Fail("Non-zero exit_code.") @@ -913,12 +913,14 @@ for p in [ scons ]: env.Command(local_targets, build_src_files, commands) scons_LICENSE = os.path.join(local, 'scons-LICENSE') - env.SCons_revision(scons_LICENSE, 'LICENSE-local') - local_targets.append(scons_LICENSE) + l = env.SCons_revision(scons_LICENSE, 'LICENSE-local') + local_targets.append(l) + Local(l) scons_README = os.path.join(local, 'scons-README') - env.SCons_revision(scons_README, 'README-local') - local_targets.append(scons_README) + l = env.SCons_revision(scons_README, 'README-local') + local_targets.append(l) + Local(l) if gzip: env.Command(local_tar_gz, diff --git a/bin/ae-cvs-ci b/bin/ae-cvs-ci new file mode 100755 index 0000000..3dcc287 --- /dev/null +++ b/bin/ae-cvs-ci @@ -0,0 +1,190 @@ +# +# aegis - project change supervisor +# Copyright (C) 2004 Peter Miller; +# All rights reserved. +# +# As a specific exception to the GPL, you are allowed to copy +# this source file into your own project and modify it, without +# releasing your project under the GPL, unless there is some other +# file or condition which would require it. +# +# MANIFEST: shell script to commit changes to CVS +# +# It is assumed that your CVSROOT and CVS_RSH environment variables have +# already been set appropriately. +# +# This script is expected to be run as by integrate_pass_notify_command +# and as such the baseline has already assumed the shape asked for by +# the change. +# +# integrate_pass_notify_command = +# "$bin/ae-cvs-ci $project $change"; +# +# Alternatively, you may wish to tailor this script to the individual +# needs of your project. Make it a source file, e.g. "etc/ae-cvs-ci.sh" +# and then use the following: +# +# integrate_pass_notify_command = +# "$sh ${s etc/ae-cvs-ci} $project $change"; +# + +USAGE="Usage: $0 <project> <change>" + +PRINT="echo" +EXECUTE="eval" + +while getopts "hnq" FLAG +do + case ${FLAG} in + h ) + echo "${USAGE}" + exit 0 + ;; + n ) + EXECUTE=":" + ;; + q ) + PRINT=":" + ;; + * ) + echo "$0: unknown option ${FLAG}" >&2 + exit 1 + ;; + esac +done + +shift `expr ${OPTIND} - 1` + +case $# in +2) + project=$1 + change=$2 + ;; +*) + echo "${USAGE}" 1>&2 + exit 1 + ;; +esac + +here=`pwd` + +AEGIS_PROJECT=$project +export AEGIS_PROJECT +AEGIS_CHANGE=$change +export AEGIS_CHANGE + +module=`echo $project | sed 's|[.].*||'` + +baseline=`aegis -cd -bl` + +if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi + +TMP=${TMPDIR}/ae-cvs-ci.$$ +mkdir ${TMP} +cd ${TMP} + +PWD=`pwd` +if test X${PWD} != X${TMP}; then + echo "$0: ended up in ${PWD}, not ${TMP}" >&2 + exit 1 +fi + +fail() +{ + set +x + cd $here + rm -rf ${TMP} + echo "FAILED" 1>&2 + exit 1 +} +trap "fail" 1 2 3 15 + +Command() +{ + ${PRINT} "$*" + ${EXECUTE} "$*" +} + +# +# Create a new CVS work area. +# +# Note: this assumes the module is checked-out into a directory of the +# same name. Is there a way to ask CVS where is is going to put a +# modules, so we can always get the "cd" right? +# +${PRINT} cvs co $module +${EXECUTE} cvs co $module > LOG 2>&1 +if test $? -ne 0; then cat LOG; fail; fi +${EXECUTE} cd $module + +# +# Now we need to extract the sources from Aegis and drop them into the +# CVS work area. There are two ways to do this. +# +# The first way is to use the generated tarball. +# This has the advantage that it has the Makefile.in file in it, and +# will work immediately. +# +# The second way is to use aetar, which will give exact sources, and +# omit all derived files. This will *not* include the Makefile.in, +# and so will not be readily compilable. +# +# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - +aetar -send -o - | tar xzf - + +# +# If any new directories have been created we will need to add them +# to CVS before we can add the new files which we know are in them, +# or they would not have been created. Do this only if the -n option +# isn't used, because if it is, we won't have actually checked out the +# source and we'd erroneously report that all of them need to be added. +# +if test "X${EXECUTE}" != "X:" +then + find . \( -name CVS -o -name Attic \) -prune -o -type d -print | + xargs --max-args=1 | + while read dir + do + if [ ! -d $dir/CVS ] + then + Command cvs add $dir + fi + done +fi + +# +# Use the Aegis meta-data to perform some CVS commands that CVS can't +# figure out for itself. +# +aegis -l cf -unf | sed 's| -> [0-9][0-9.]*||' | +while read usage action rev filename +do + if test "x$filename" = "x" + then + filename="$rev" + fi + case $action in + create) + Command cvs add $filename + ;; + remove) + Command rm -f $filename + Command cvs remove $filename + ;; + *) + ;; + esac +done + +# +# Now commit all the changes. +# +message=`aesub '${version} - ${change description}'` +Command cvs -q commit -m \"$message\" + +# +# All done. Clean up and go home. +# +cd $here +rm -rf ${TMP} +exit 0 diff --git a/bin/ae-svn-ci b/bin/ae-svn-ci new file mode 100755 index 0000000..e5b81a4 --- /dev/null +++ b/bin/ae-svn-ci @@ -0,0 +1,226 @@ +# +# aegis - project change supervisor +# Copyright (C) 2004 Peter Miller; +# All rights reserved. +# +# As a specific exception to the GPL, you are allowed to copy +# this source file into your own project and modify it, without +# releasing your project under the GPL, unless there is some other +# file or condition which would require it. +# +# MANIFEST: shell script to commit changes to Subversion +# +# This script is expected to be run by the integrate_pass_notify_command +# and as such the baseline has already assumed the shape asked for by +# the change. +# +# integrate_pass_notify_command = +# "$bin/ae-svn-ci $project $change http://svn.site.com/svn/trunk --username svn_user"; +# +# Alternatively, you may wish to tailor this script to the individual +# needs of your project. Make it a source file, e.g. "etc/ae-svn-ci.sh" +# and then use the following: +# +# integrate_pass_notify_command = +# "$sh ${s etc/ae-svn-ci} $project $change http://svn.site.com/svn/trunk --username svn_user"; +# + +USAGE="Usage: $0 [-hnq] <project> <change> <url> [<co_options>]" + +PRINT="echo" +EXECUTE="eval" + +while getopts "hnq" FLAG +do + case ${FLAG} in + h ) + echo "${USAGE}" + exit 0 + ;; + n ) + EXECUTE=":" + ;; + q ) + PRINT=":" + ;; + * ) + echo "$0: unknown option ${FLAG}" >&2 + exit 1 + ;; + esac +done + +shift `expr ${OPTIND} - 1` + +case $# in +[012]) + echo "${USAGE}" 1>&2 + exit 1 + ;; +*) + project=$1 + change=$2 + svn_url=$3 + shift 3 + svn_co_flags=$* + ;; +esac + +here=`pwd` + +AEGIS_PROJECT=$project +export AEGIS_PROJECT +AEGIS_CHANGE=$change +export AEGIS_CHANGE + +module=`echo $project | sed 's|[.].*||'` + +baseline=`aegis -cd -bl` + +if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi + +TMP=${TMPDIR}/ae-svn-ci.$$ +mkdir ${TMP} +cd ${TMP} + +PWD=`pwd` +if test X${PWD} != X${TMP}; then + echo "$0: ended up in ${PWD}, not ${TMP}" >&2 + exit 1 +fi + +fail() +{ + set +x + cd $here + rm -rf ${TMP} + echo "FAILED" 1>&2 + exit 1 +} +trap "fail" 1 2 3 15 + +Command() +{ + ${PRINT} "$*" + ${EXECUTE} "$*" +} + +# +# Create a new Subversion work area. +# +# Note: this assumes the module is checked-out into a directory of the +# same name. Is there a way to ask Subversion where it is going to put a +# module, so we can always get the "cd" right? +# +${PRINT} svn co $svn_url $module $svn_co_flags +${EXECUTE} svn co $svn_url $module $svn_co_flags > LOG 2>&1 +if test $? -ne 0; then cat LOG; fail; fi +${EXECUTE} cd $module + +# +# Now we need to extract the sources from Aegis and drop them into the +# Subversion work area. There are two ways to do this. +# +# The first way is to use the generated tarball. +# This has the advantage that it has the Makefile.in file in it, and +# will work immediately. +# +# The second way is to use aetar, which will give exact sources, and +# omit all derived files. This will *not* include the Makefile.in, +# and so will not be readily compilable. +# +# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - +aetar -send -o - | tar xzf - + +# +# If any new directories have been created we will need to add them +# to Subversion before we can add the new files which we know are in them, +# or they would not have been created. Do this only if the -n option +# isn't used, because if it is, we won't have actually checked out the +# source and we'd erroneously report that all of them need to be added. +# +if test "X${EXECUTE}" != "X:" +then + find . -name .svn -prune -o -type d -print | + xargs --max-args=1 | + while read dir + do + if [ ! -d $dir/.svn ] + then + Command svn add -N $dir + fi + done +fi + +# +# Use the Aegis meta-data to perform some commands that Subversion can't +# figure out for itself. We use an inline "aer" report script to identify +# when a remove-create pair are actually due to a move. +# +aegis -rpt -nph -f - <<_EOF_ | +auto cs; +cs = project[project_name()].state.branch.change[change_number()]; + +columns({width = 1000;}); + +auto file, moved; +for (file in cs.src) +{ + if (file.move != "") + moved[file.move] = 1; +} + +auto action; +for (file in cs.src) +{ + if (file.action == "remove" && file.move != "") + action = "move"; + else + action = file.action; + /* + * Suppress printing of any files created as the result of a move. + * These are printed as the destination when printing the line for + * the file that was *removed* as a result of the move. + */ + if (action != "create" || ! moved[file.file_name]) + print(sprintf("%s %s \\"%s\\" \\"%s\\"", file.usage, action, file.file_name, file.move)); +} +_EOF_ +while read line +do + eval set -- "$line" + usage="$1" + action="$2" + srcfile="$3" + dstfile="$4" + case $action in + create) + Command svn add $srcfile + ;; + remove) + Command rm -f $srcfile + Command svn remove $srcfile + ;; + move) + Command mv $dstfile $dstfile.move + Command svn move $srcfile $dstfile + Command cp $dstfile.move $dstfile + Command rm -f $dstfile.move + ;; + *) + ;; + esac +done + +# +# Now commit all the changes. +# +message=`aesub '${version} - ${change description}'` +Command svn commit -m \"$message\" + +# +# All done. Clean up and go home. +# +cd $here +rm -rf ${TMP} +exit 0 diff --git a/bin/caller-tree.py b/bin/caller-tree.py new file mode 100644 index 0000000..5d907b8 --- /dev/null +++ b/bin/caller-tree.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# +# Quick script to process the *summary* output from SCons.Debug.caller() +# and print indented calling trees with call counts. +# +# The way to use this is to add something like the following to a function +# for which you want information about who calls it and how many times: +# +# from SCons.Debug import caller +# caller(0, 1, 2, 3, 4, 5) +# +# Each integer represents how many stack frames back SCons will go +# and capture the calling information, so in the above example it will +# capture the calls six levels up the stack in a central dictionary. +# +# At the end of any run where SCons.Debug.caller() is used, SCons will +# print a summary of the calls and counts that looks like the following: +# +# Callers of Node/__init__.py:629(calc_signature): +# 1 Node/__init__.py:683(calc_signature) +# Callers of Node/__init__.py:676(gen_binfo): +# 6 Node/FS.py:2035(current) +# 1 Node/__init__.py:722(get_bsig) +# +# If you cut-and-paste that summary output and feed it to this script +# on standard input, it will figure out how these entries hook up and +# print a calling tree for each one looking something like: +# +# Node/__init__.py:676(gen_binfo) +# Node/FS.py:2035(current) 6 +# Taskmaster.py:253(make_ready_current) 18 +# Script/Main.py:201(make_ready) 18 +# +# Note that you should *not* look at the call-count numbers in the right +# hand column as the actual number of times each line *was called by* +# the function on the next line. Rather, it's the *total* number +# of times each function was found in the call chain for any of the +# calls to SCons.Debug.caller(). If you're looking at more than one +# function at the same time, for example, their counts will intermix. +# So use this to get a *general* idea of who's calling what, not for +# fine-grained performance tuning. + +import sys + +class Entry: + def __init__(self, file_line_func): + self.file_line_func = file_line_func + self.called_by = [] + self.calls = [] + +AllCalls = {} + +def get_call(flf): + try: + e = AllCalls[flf] + except KeyError: + e = AllCalls[flf] = Entry(flf) + return e + +prefix = 'Callers of ' + +c = None +for line in sys.stdin.readlines(): + if line[0] == '#': + pass + elif line[:len(prefix)] == prefix: + c = get_call(line[len(prefix):-2]) + else: + num_calls, flf = line.strip().split() + e = get_call(flf) + c.called_by.append((e, num_calls)) + e.calls.append(c) + +stack = [] + +def print_entry(e, level, calls): + print '%-72s%6s' % ((' '*2*level) + e.file_line_func, calls) + if e in stack: + print (' '*2*(level+1))+'RECURSION' + print + elif e.called_by: + stack.append(e) + for c in e.called_by: + print_entry(c[0], level+1, c[1]) + stack.pop() + else: + print + +for e in [ e for e in AllCalls.values() if not e.calls ]: + print_entry(e, 0, '') diff --git a/bin/scons-cdist b/bin/scons-cdist index 425e430..58b1bae 100644 --- a/bin/scons-cdist +++ b/bin/scons-cdist @@ -22,45 +22,58 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PROG=`basename $0` -FLAGS="ahnqrstz" -USAGE="Usage: ${PROG} [-${FLAGS}] change" +NOARGFLAGS="afhlnqrstz" +ARGFLAGS="p:" +ALLFLAGS="${NOARGFLAGS}${ARGFLAGS}" +USAGE="Usage: ${PROG} [-${NOARGFLAGS}] [-p project] change" HELP="$USAGE - -a Update the latest Aegis baseline (aedist) file. - -h Print this help message and exit. - -n Don't execute, just echo commands. - -q Quiet, don't print commands before executing them. - -r Rsync the Aegis repository to SourceForge. - -s Update the sourceforge.net CVS repository. - -t Update the tigris.org CVS repository. - -z Update the latest .zip file. + -a Update the latest Aegis baseline (aedist) file. + -f Force update, skipping up-front sanity check. + -h Print this help message and exit. + -l Update the local CVS repository. + -n Don't execute, just echo commands. + -p project Set the Aegis project. + -q Quiet, don't print commands before executing them. + -r Rsync the Aegis repository to SourceForge. + -s Update the sourceforge.net CVS repository. + -t Update the tigris.org CVS repository. + -z Update the latest .tar.gz and .zip files. " DO="" PRINT="echo" EXECUTE="eval" +SANITY_CHECK="yes" -while getopts $FLAGS FLAG; do - case $FLAG in - a | r | s | t | z ) - DO="${DO}${FLAG}" - ;; - h ) - echo "${HELP}" - exit 0 - ;; - n ) - EXECUTE=":" - ;; - q ) - PRINT=":" - ;; - * ) - echo "${USAGE}" >&2 - exit 1 - ;; - esac +while getopts $ALLFLAGS FLAG; do + case $FLAG in + a | l | r | s | t | z ) + DO="${DO}${FLAG}" + ;; + f ) + SANITY_CHECK="no" + ;; + h ) + echo "${HELP}" + exit 0 + ;; + n ) + EXECUTE=":" + ;; + p ) + AEGIS_PROJECT="${OPTARG}" + ;; + q ) + PRINT=":" + ;; + * ) + echo "FLAG = ${FLAG}" >&2 + echo "${USAGE}" >&2 + exit 1 + ;; + esac done shift `expr ${OPTIND} - 1` @@ -70,8 +83,14 @@ if test "X$1" = "X"; then exit 1 fi +if test "X${AEGIS_PROJECT}" = "X"; then + echo "$PROG: No AEGIS_PROJECT set." >&2 + echo "${USAGE}" >&2 + exit 1 +fi + if test "X$DO" = "X"; then - DO="arstz" + DO="alrstz" fi cmd() @@ -82,6 +101,27 @@ cmd() CHANGE=$1 +if test "X${SANITY_CHECK}" = "Xyes"; then + SCM="cvs" + SCMROOT="/home/scons/CVSROOT/scons" + DELTA=`aegis -l -ter cd ${CHANGE} | sed -n 's/.*, Delta \([0-9]*\)\./\1/p'` + if test "x${DELTA}" = "x"; then + echo "${PROG}: Could not find delta for change ${CHANGE}." >&2 + echo "Has this finished integrating? Change ${CHANGE} not distributed." >&2 + exit 1 + fi + PREV_DELTA=`expr ${DELTA} - 1` + COMMAND="scons-scmcheck -D ${PREV_DELTA} -d q -p ${AEGIS_PROJECT} -s ${SCM} ${SCMROOT}" + $PRINT "${COMMAND}" + OUTPUT=`${COMMAND}` + if test "X${OUTPUT}" != "X"; then + echo "${PROG}: ${SCMROOT} is not up to date:" >&2 + echo "${OUTPUT}" >& 2 + echo "Did you skip any changes? Change ${CHANGE} not distributed." >&2 + exit 1 + fi +fi + if test X$EXECUTE != "X:" -a "X$SSH_AGENT_PID" = "X"; then eval `ssh-agent` ssh-add @@ -95,29 +135,38 @@ BASELINE=`aesub -p ${AEGIS_PROJECT} -c ${CHANGE} '${Project trunk_name}'` TMPBLAE="/tmp/${BASELINE}.ae" TMPCAE="/tmp/${AEGIS_PROJECT}.C${CHANGE}.ae" -SFLOGIN="stevenknight" -SFHOST="scons.sourceforge.net" -SFDEST="/home/groups/s/sc/scons/htdocs" +# Original values for SourceForge. +#SFLOGIN="stevenknight" +#SFHOST="scons.sourceforge.net" +#SFDEST="/home/groups/s/sc/scons/htdocs" + +SCONSLOGIN="scons" +SCONSHOST="manam.pair.com" +#SCONSDEST="public_html/production" +SCONSDEST="public_ftp" # # Copy the baseline .ae to the constant location on SourceForge. # case "${DO}" in - *a* ) - cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}" - cmd "scp ${TMPBLAE} ${SFLOGIN}@${SFHOST}:${SFDEST}/${BASELINE}.ae" - cmd "rm ${TMPBLAE}" - ;; +*a* ) + cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}" + cmd "scp ${TMPBLAE} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/${BASELINE}.ae" + cmd "rm ${TMPBLAE}" + ;; esac # -# Copy the latest .zip file to the constant location on SourceForge. +# Copy the latest .tar.gz and .zip files to the constant location on +# SourceForge. # case "${DO}" in - *z* ) - BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist - SCONS_SRC=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`.zip - cmd "scp ${BUILD_DIST}/${SCONS_SRC} ${SFLOGIN}@${SFHOST}:${SFDEST}/scons-src-latest.zip" +*z* ) + BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist + SCONS_SRC_TAR_GZ=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.tar.gz + SCONS_SRC_ZIP=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.zip + cmd "scp ${BUILD_DIST}/${SCONS_SRC_TAR_GZ} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.tar.gz" + cmd "scp ${BUILD_DIST}/${SCONS_SRC_ZIP} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.zip" esac # @@ -144,38 +193,73 @@ esac # We no longer use the --stats option. # case "${DO}" in - *r* ) - LOCAL=/home/scons/scons - REMOTE=/home/groups/s/sc/scons/scons - cmd "/usr/bin/rsync --rsh=ssh -l -p -r -t -z \ - --exclude build \ - --exclude '*,D' \ - --exclude '*.pyc' \ - --exclude aegis.log \ - --exclude '.sconsign*' \ - --delete --delete-excluded \ - --progress -v \ - ${LOCAL}/. scons.sourceforge.net:${REMOTE}/." - ;; +*r* ) + LOCAL=/home/scons/scons + REMOTE=/home/groups/s/sc/scons/scons + cmd "/usr/bin/rsync --rsh='ssh -l stevenknight' \ + -l -p -r -t -z \ + --exclude build \ + --exclude '*,D' \ + --exclude '*.pyc' \ + --exclude aegis.log \ + --exclude '.sconsign*' \ + --delete --delete-excluded \ + --progress -v \ + ${LOCAL}/. scons.sourceforge.net:${REMOTE}/." + ;; esac # -# Sync the CVS tree with Tigris.org. +# Sync the CVS tree with the local repository. # case "${DO}" in - *t* ) - cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons" - ;; +*l* ) + ( + export CVSROOT=/home/scons/CVSROOT/scons + #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/baldmt.com/scons" + cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}" + ) + ;; +esac + +# +# Sync the Subversion tree with Tigris.org. +# +case "${DO}" in +*t* ) + ( + SVN=http://scons.tigris.org/svn/scons + case ${AEGIS_PROJECT} in + scons.0.96 ) + SVN_URL=${SVN}/branches/core + ;; + scons.0.96.513 ) + SVN_URL=${SVN}/branches/sigrefactor + ;; + * ) + echo "$PROG: Don't know SVN branch for '${AEGIS_PROJECT}'" >&2 + exit 1 + ;; + esac + SVN_CO_FLAGS="--username stevenknight" + #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons" + cmd "ae-svn-ci ${AEGIS_PROJECT} ${CHANGE} ${SVN_URL} ${SVN_CO_FLAGS}" + ) + ;; esac # # Sync the CVS tree with SourceForge. # case "${DO}" in - *s* ) +*s* ) + ( export CVS_RSH=ssh - cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons" - ;; + export CVSROOT=:ext:stevenknight@scons.cvs.sourceforge.net:/cvsroot/scons + #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons" + cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}" + ) + ;; esac # @@ -185,4 +269,4 @@ esac # #aedist -s -p ${AEGIS_PROJECT} ${CHANGE} > ${TMPCAE} #aegis -l -p ${AEGIS_PROJECT} -c ${CHANGE} cd | -# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net +# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net diff --git a/bin/scons-diff.py b/bin/scons-diff.py new file mode 100644 index 0000000..6cfe25a --- /dev/null +++ b/bin/scons-diff.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# +# scons-diff.py - diff-like utility for comparing SCons trees +# +# This supports most common diff options (with some quirks, like you can't +# just say -c and have it use a default value), but canonicalizes the +# various version strings within the file like __revision__, __build__, +# etc. so that you can diff trees without having to ignore changes in +# version lines. +# + +import difflib +import getopt +import os.path +import re +import sys + +Usage = """\ +Usage: scons-diff.py [OPTIONS] dir1 dir2 +Options: + -c NUM, --context=NUM Print NUM lines of copied context. + -h, --help Print this message and exit. + -n Don't canonicalize SCons lines. + -q, --quiet Print only whether files differ. + -r, --recursive Recursively compare found subdirectories. + -s Report when two files are the same. + -u NUM, --unified=NUM Print NUM lines of unified context. +""" + +opts, args = getopt.getopt(sys.argv[1:], + 'c:dhnqrsu:', + ['context=', 'help', 'recursive', 'unified=']) + +diff_type = None +edit_type = None +context = 2 +recursive = False +report_same = False +diff_options = [] + +def diff_line(left, right): + if diff_options: + opts = ' ' + ' '.join(diff_options) + else: + opts = '' + print 'diff%s %s %s' % (opts, left, right) + +for o, a in opts: + if o in ('-c', '-u'): + diff_type = o + context = int(a) + diff_options.append(o) + elif o in ('-h', '--help'): + print Usage + sys.exit(0) + elif o in ('-n'): + diff_options.append(o) + edit_type = o + elif o in ('-q'): + diff_type = o + diff_line = lambda l, r: None + elif o in ('-r', '--recursive'): + recursive = True + diff_options.append(o) + elif o in ('-s'): + report_same = True + +try: + left, right = args +except ValueError: + sys.stderr.write(Usage) + sys.exit(1) + +def quiet_diff(a, b, fromfile='', tofile='', + fromfiledate='', tofiledate='', n=3, lineterm='\n'): + """ + A function with the same calling signature as difflib.context_diff + (diff -c) and difflib.unified_diff (diff -u) but which prints + output like the simple, unadorned 'diff" command. + """ + if a == b: + return [] + else: + return ['Files %s and %s differ\n' % (fromfile, tofile)] + +def simple_diff(a, b, fromfile='', tofile='', + fromfiledate='', tofiledate='', n=3, lineterm='\n'): + """ + A function with the same calling signature as difflib.context_diff + (diff -c) and difflib.unified_diff (diff -u) but which prints + output like the simple, unadorned 'diff" command. + """ + sm = difflib.SequenceMatcher(None, a, b) + def comma(x1, x2): + return x1+1 == x2 and str(x2) or '%s,%s' % (x1+1, x2) + result = [] + for op, a1, a2, b1, b2 in sm.get_opcodes(): + if op == 'delete': + result.append("%sd%d\n" % (comma(a1, a2), b1)) + result.extend(map(lambda l: '< ' + l, a[a1:a2])) + elif op == 'insert': + result.append("%da%s\n" % (a1, comma(b1, b2))) + result.extend(map(lambda l: '> ' + l, b[b1:b2])) + elif op == 'replace': + result.append("%sc%s\n" % (comma(a1, a2), comma(b1, b2))) + result.extend(map(lambda l: '< ' + l, a[a1:a2])) + result.append('---\n') + result.extend(map(lambda l: '> ' + l, b[b1:b2])) + return result + +diff_map = { + '-c' : difflib.context_diff, + '-q' : quiet_diff, + '-u' : difflib.unified_diff, +} + +diff_function = diff_map.get(diff_type, simple_diff) + +baseline_re = re.compile('(# |@REM )/home/\S+/baseline/') +comment_rev_re = re.compile('(# |@REM )(\S+) 0.96.[CD]\d+ \S+ \S+( knight)') +revision_re = re.compile('__revision__ = "[^"]*"') +build_re = re.compile('__build__ = "[^"]*"') +date_re = re.compile('__date__ = "[^"]*"') + +def lines_read(file): + return open(file).readlines() + +def lines_massage(file): + text = open(file).read() + text = baseline_re.sub('\\1', text) + text = comment_rev_re.sub('\\1\\2\\3', text) + text = revision_re.sub('__revision__ = "__FILE__"', text) + text = build_re.sub('__build__ = "0.96.92.DXXX"', text) + text = date_re.sub('__date__ = "2006/08/25 02:59:00"', text) + return text.splitlines(1) + +lines_map = { + '-n' : lines_read, +} + +lines_function = lines_map.get(edit_type, lines_massage) + +def do_diff(left, right, diff_subdirs): + if os.path.isfile(left) and os.path.isfile(right): + diff_file(left, right) + elif not os.path.isdir(left): + diff_file(left, os.path.join(right, os.path.split(left)[1])) + elif not os.path.isdir(right): + diff_file(os.path.join(left, os.path.split(right)[1]), right) + elif diff_subdirs: + diff_dir(left, right) + +def diff_file(left, right): + l = lines_function(left) + r = lines_function(right) + d = diff_function(l, r, left, right, context) + try: + text = ''.join(d) + except IndexError: + sys.stderr.write('IndexError diffing %s and %s\n' % (left, right)) + else: + if text: + diff_line(left, right) + print text, + elif report_same: + print 'Files %s and %s are identical' % (left, right) + +def diff_dir(left, right): + llist = os.listdir(left) + rlist = os.listdir(right) + u = {} + for l in llist: + u[l] = 1 + for r in rlist: + u[r] = 1 + clist = [ x for x in u.keys() if x[-4:] != '.pyc' ] + clist.sort() + for x in clist: + if x in llist: + if x in rlist: + do_diff(os.path.join(left, x), + os.path.join(right, x), + recursive) + else: + print 'Only in %s: %s' % (left, x) + else: + print 'Only in %s: %s' % (right, x) + +do_diff(left, right, True) @@ -50,7 +50,7 @@ * * Look in aesub(5) for more information about command substitutions. */ -build_command = "python1.5 ${Source bootstrap.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}"; +build_command = "python2.1 ${Source bootstrap.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}"; /* * SCons removes its targets before constructing them, which qualifies it @@ -258,9 +258,9 @@ diff_command = * is set appropriately during a baseline test. So we just use the * proper aesub variable to comment out the expanded $spe. */ -test_command = "python1.5 ${Source runtest.py Absolute} -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -q --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Name}"; +test_command = "python1.5 ${Source runtest.py Absolute} --noqmtest -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -q --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Name}"; -batch_test_command = "python1.5 ${Source runtest.py Absolute} -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -o ${Output} --aegis --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Names}"; +batch_test_command = "python1.5 ${Source runtest.py Absolute} --noqmtest -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -o ${Output} --aegis --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Names}"; new_test_filename = "test/CHANGETHIS.py"; @@ -286,3 +286,14 @@ file_template = body = "${read_file ${source template/test.py abs}}"; }, ]; + +/* + * Command for distributing changes from Aegis to all of the repositories + * we want to mirror the information. + * + * XXX Uncomment after upgrading to an Aegis version that supports this. + +integrate_pass_notify_command = + "$sh ${s bin/scons-cdist} -p $project $change"; + * + */ diff --git a/doc/SConscript b/doc/SConscript index 6162f93..6f92fbc 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -169,7 +169,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. variables_gen, variables_mod] b = env.Command(doc_output_files, scons_doc_files, - "python $SCONS_PROC_PY --sgml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)") + "$PYTHON $SCONS_PROC_PY --sgml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)") env.Depends(b, "$SCONS_PROC_PY") env.Local(b) @@ -259,7 +259,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. if build_doc and ext == '.sgml': env.Command(doc_s, base + '.in', - "python $SCONSOUTPUT_PY $SOURCE > $TARGET") + "$PYTHON $SCONSOUTPUT_PY $SOURCE > $TARGET") orig_env.SCons_revision(build_s, doc_s) Local(build_s) @@ -387,7 +387,7 @@ man_i_files = ['builders.man', 'tools.man', 'variables.man'] man_intermediate_files = map(lambda x: os.path.join(build, 'man', x), man_i_files) -cmd = "python $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)" +cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)" man_intermediate_files = env.Command(man_intermediate_files, scons_doc_files, cmd) diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 49f9a30..a12bd68 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -421,6 +421,24 @@ Will not remove any targets specified by the function. .TP +.RI --cache-debug= file +Print debug information about the +.BR CacheDir () +derived-file caching +to the specified +.IR file . +If +.I file +is +.B \- +(a hyphen), +the debug information are printed to the standard output. +The printed messages describe what signature file names are +being looked for in, retrieved from, or written to the +.BR CacheDir () +directory tree. + +.TP --cache-disable, --no-cache Disable the derived-file caching specified by .BR CacheDir (). @@ -1712,6 +1730,24 @@ the specified See the section "Action Objects," below, for a complete explanation of the arguments and behavior. +Note that the +.BR env.Action () +form of the invocation will expand +construction variables in any arguments strings, +including the +.I action +argument, +at the time it is called +using the construction variables in the +.B env +construction environment through which +.BR env.Action () +was called. +The +.BR Action () +form delays all variable expansion +until the Action object is actually used. + '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI AddPostAction( target ", " action ) @@ -1993,6 +2029,24 @@ the specified See the section "Builder Objects," below, for a complete explanation of the arguments and behavior. +Note that the +.BR env.Builder () +form of the invocation will expand +construction variables in any arguments strings, +including the +.I action +argument, +at the time it is called +using the construction variables in the +.B env +construction environment through which +.BR env.Builder () +was called. +The +.BR Builder () +form delays all variable expansion +until after the Builder object is actually called. + '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI CacheDir( cache_dir ) @@ -2759,8 +2813,11 @@ Import("*") .RI Install( dir ", " source ) .TP .RI env.Install( dir ", " source ) -Installs one or more files in a destination directory. -The file names remain the same. +Installs one or more source files or directories +in a destination directory +.IR dir . +The names of the specified source files or directories +remain the same within the destination directory. .ES env.Install(dir = '/usr/local/bin', source = ['foo', 'bar']) @@ -2771,11 +2828,15 @@ env.Install(dir = '/usr/local/bin', source = ['foo', 'bar']) .RI InstallAs( target ", " source ) .TP .RI env.InstallAs( target ", " source ) -Installs one or more files as specific file names, -allowing changing a file name as part of the -installation. -It is an error if the target and source -list different numbers of files. +Installs one or more source files or directories +to specific names, +allowing changing a file or directory name +as part of the installation. +It is an error if the +.I target +and +.I source +arguments list different numbers of files or directories. .ES env.InstallAs(target = '/usr/local/bin/foo', @@ -3997,17 +4058,31 @@ env.Tool('opengl', toolpath = ['build/tools']) '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.RI Value( value ) +.RI Value( value ", [" built_value ]) .TP -.RI env.Value( value ) +.RI env.Value( value ", [" built_value ]) Returns a Node object representing the specified Python value. Value -nodes can be used as dependencies of targets. If the result of +Nodes can be used as dependencies of targets. If the result of calling .BR str( value ) changes between SCons runs, any targets depending on .BR Value( value ) -will be rebuilt. When using timestamp source signatures, Value nodes' -timestamps are equal to the system time when the node is created. +will be rebuilt. When using timestamp source signatures, Value Nodes' +timestamps are equal to the system time when the Node is created. + +The returned Value Node object has a +.BR write () +method that can be used to "build" a Value Node +by setting a new value. +The optional +.I built_value +argument can be specified +when the Value Node is created +to indicate the Node should already be considered +"built." +There is a corresponding +.BR read () +method that will return the built value of the Node. .ES def create(target, source, env): @@ -4018,6 +4093,15 @@ prefix = ARGUMENTS.get('prefix', '/usr/local') env = Environment() env['BUILDERS']['Config'] = Builder(action = create) env.Config(target = 'package-config', source = Value(prefix)) + +def build_value(target, source, env): + target[0].write(source[0].get_contents()) + +output = env.Value('before') +input = env.Value('after') + +env['BUILDERS']['UpdateValue'] = Builder(action = build_value) +env.UpdateValue(target = Value(output), source = Value(input)) .EE '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation +# __COPYRIGHT__ # # runtest.py - wrapper script for running SCons tests # @@ -96,20 +96,21 @@ import string import sys import time +if not hasattr(os, 'WEXITSTATUS'): + os.WEXITSTATUS = lambda x: x + all = 0 baseline = 0 debug = '' execute_tests = 1 format = None list_only = None -tests = [] printcommand = 1 package = None print_passed_summary = None scons = None scons_exec = None outputfile = None -qmtest = None testlistfile = None version = '' print_times = None @@ -119,13 +120,6 @@ spe = None cwd = os.getcwd() -if sys.platform == 'win32' or os.name == 'java': - lib_dir = os.path.join(sys.exec_prefix, "Lib") -else: - # The hard-coded "python" here is the directory name, - # not an executable, so it's all right. - lib_dir = os.path.join(sys.exec_prefix, "lib", "python" + sys.version[0:3]) - helpstr = """\ Usage: runtest.py [OPTIONS] [TEST ...] Options: @@ -137,6 +131,7 @@ Options: -h, --help Print this message and exit. -l, --list List available tests and exit. -n, --no-exec No execute, just print command lines. + --noqmtest Execute tests directly, not using QMTest. -o FILE, --output FILE Print test results to FILE. -P Python Use the specified Python interpreter. -p PACKAGE, --package PACKAGE @@ -167,7 +162,7 @@ Options: opts, args = getopt.getopt(sys.argv[1:], "ab:df:hlno:P:p:qv:Xx:t", ['all', 'aegis', 'baseline=', 'debug', 'file=', 'help', - 'list', 'no-exec', 'output=', + 'list', 'no-exec', 'noqmtest', 'output=', 'package=', 'passed', 'python=', 'qmtest', 'quiet', 'spe=', 'version=', 'exec=', 'time', @@ -179,7 +174,11 @@ for o, a in opts: elif o in ['-b', '--baseline']: baseline = a elif o in ['-d', '--debug']: - debug = os.path.join(lib_dir, "pdb.py") + for dir in sys.path: + pdb = os.path.join(dir, 'pdb.py') + if os.path.exists(pdb): + debug = pdb + break elif o in ['-f', '--file']: if not os.path.isabs(a): a = os.path.join(cwd, a) @@ -191,6 +190,8 @@ for o, a in opts: list_only = 1 elif o in ['-n', '--no-exec']: execute_tests = None + elif o in ['--noqmtest']: + qmtest = None elif o in ['-o', '--output']: if a != '-' and not os.path.isabs(a): a = os.path.join(cwd, a) @@ -202,7 +203,7 @@ for o, a in opts: elif o in ['-P', '--python']: python = a elif o in ['--qmtest']: - qmtest = 1 + qmtest = 'qmtest.py' elif o in ['-q', '--quiet']: printcommand = 0 elif o in ['--sp']: @@ -222,6 +223,17 @@ for o, a in opts: elif o in ['--aegis', '--xml']: format = o +if not args and not all and not testlistfile: + sys.stderr.write("""\ +runtest.py: No tests were specified. + List one or more tests on the command line, use the + -f option to specify a file containing a list of tests, + or use the -a option to find and run all tests. + +""") + sys.exit(1) + + def whereis(file): for dir in string.split(os.environ['PATH'], os.pathsep): f = os.path.join(dir, file) @@ -234,6 +246,16 @@ def whereis(file): return f return None +try: + qmtest +except NameError: + q = 'qmtest.py' + qmtest = whereis(q) + if qmtest: + qmtest = q + else: + sys.stderr.write('Warning: %s not found on $PATH, assuming --noqmtest option.\n' % q) + aegis = whereis('aegis') if format == '--aegis' and aegis: @@ -277,9 +299,9 @@ except AttributeError: return status >> 8 else: def spawn_it(command_args): + command = command_args[0] command_args = map(escape, command_args) - command_args = map(lambda s: string.replace(s, '\\','\\\\'), command_args) - return os.spawnv(os.P_WAIT, command_args[0], command_args) + return os.spawnv(os.P_WAIT, command, command_args) class Base: def __init__(self, path, spe=None): @@ -352,86 +374,8 @@ format_class = { '--aegis' : Aegis, '--xml' : XML, } -Test = format_class[format] - -if qmtest: - pass -elif args: - if spe: - for a in args: - if os.path.isabs(a): - for g in glob.glob(a): - tests.append(Test(g)) - else: - for dir in spe: - x = os.path.join(dir, a) - globs = glob.glob(x) - if globs: - for g in globs: - tests.append(Test(g)) - break - else: - for a in args: - for g in glob.glob(a): - tests.append(Test(g)) -elif all: - # Find all of the SCons functional tests in the local directory - # tree. This is anything under the 'src' subdirectory that ends - # with 'Tests.py', or any Python script (*.py) under the 'test' - # subdirectory. - # - # Note that there are some tests under 'src' that *begin* with - # 'test_', but they're packaging and installation tests, not - # functional tests, so we don't execute them by default. (They can - # still be executed by hand, though, and are routinely executed - # by the Aegis packaging build to make sure that we're building - # things correctly.) - tdict = {} - - def find_Tests_py(arg, dirname, names, tdict=tdict): - for n in filter(lambda n: n[-8:] == "Tests.py", names): - t = os.path.join(dirname, n) - if not tdict.has_key(t): - tdict[t] = Test(t) - os.path.walk('src', find_Tests_py, 0) - - def find_py(arg, dirname, names, tdict=tdict): - for n in filter(lambda n: n[-3:] == ".py", names): - t = os.path.join(dirname, n) - if not tdict.has_key(t): - tdict[t] = Test(t) - os.path.walk('test', find_py, 0) - - if format == '--aegis' and aegis: - cmd = "aegis -list -unf pf 2>/dev/null" - for line in os.popen(cmd, "r").readlines(): - a = string.split(line) - if a[0] == "test" and not tdict.has_key(a[-1]): - tdict[a[-1]] = Test(a[-1], spe) - cmd = "aegis -list -unf cf 2>/dev/null" - for line in os.popen(cmd, "r").readlines(): - a = string.split(line) - if a[0] == "test": - if a[1] == "remove": - del tdict[a[-1]] - elif not tdict.has_key(a[-1]): - tdict[a[-1]] = Test(a[-1], spe) - - keys = tdict.keys() - keys.sort() - tests = map(tdict.get, keys) -elif testlistfile: - tests = open(testlistfile, 'r').readlines() - tests = filter(lambda x: x[0] != '#', tests) - tests = map(lambda x: x[:-1], tests) - tests = map(Test, tests) -else: - sys.stderr.write("""\ -runtest.py: No tests were specified on the command line. - List one or more tests, or use the -a option - to find and run all tests. -""") +Test = format_class[format] if package: @@ -476,6 +420,8 @@ if package: scons_lib_dir = os.path.join(test_dir, dir[package], 'lib', l) pythonpath_dir = scons_lib_dir + scons_runtest_dir = os.path.join(cwd, 'build') + else: sd = None ld = None @@ -529,6 +475,8 @@ else: else: base = baseline + scons_runtest_dir = base + scons_script_dir = sd or os.path.join(base, 'src', 'script') scons_lib_dir = ld or os.path.join(base, 'src', 'engine') @@ -548,6 +496,7 @@ elif scons_lib_dir: if scons_exec: os.environ['SCONS_EXEC'] = '1' +os.environ['SCONS_RUNTEST_DIR'] = scons_runtest_dir os.environ['SCONS_SCRIPT_DIR'] = scons_script_dir os.environ['SCONS_CWD'] = cwd @@ -573,43 +522,123 @@ if old_pythonpath: os.pathsep + \ old_pythonpath +tests = [] + +if args: + if spe: + for a in args: + if os.path.isabs(a): + tests.extend(glob.glob(a)) + else: + for dir in spe: + x = os.path.join(dir, a) + globs = glob.glob(x) + if globs: + tests.extend(globs) + break + else: + for a in args: + tests.extend(glob.glob(a)) +elif testlistfile: + tests = open(testlistfile, 'r').readlines() + tests = filter(lambda x: x[0] != '#', tests) + tests = map(lambda x: x[:-1], tests) +elif all and not qmtest: + # Find all of the SCons functional tests in the local directory + # tree. This is anything under the 'src' subdirectory that ends + # with 'Tests.py', or any Python script (*.py) under the 'test' + # subdirectory. + # + # Note that there are some tests under 'src' that *begin* with + # 'test_', but they're packaging and installation tests, not + # functional tests, so we don't execute them by default. (They can + # still be executed by hand, though, and are routinely executed + # by the Aegis packaging build to make sure that we're building + # things correctly.) + tdict = {} + + def find_Tests_py(tdict, dirname, names): + for n in filter(lambda n: n[-8:] == "Tests.py", names): + t = os.path.join(dirname, n) + if not tdict.has_key(t): + tdict[t] = 1 + os.path.walk('src', find_Tests_py, tdict) + + def find_py(tdict, dirname, names): + for n in filter(lambda n: n[-3:] == ".py", names): + t = os.path.join(dirname, n) + if not tdict.has_key(t): + tdict[t] = 1 + os.path.walk('test', find_py, tdict) + + if format == '--aegis' and aegis: + cmd = "aegis -list -unf pf 2>/dev/null" + for line in os.popen(cmd, "r").readlines(): + a = string.split(line) + if a[0] == "test" and not tdict.has_key(a[-1]): + tdict[a[-1]] = Test(a[-1], spe) + cmd = "aegis -list -unf cf 2>/dev/null" + for line in os.popen(cmd, "r").readlines(): + a = string.split(line) + if a[0] == "test": + if a[1] == "remove": + del tdict[a[-1]] + elif not tdict.has_key(a[-1]): + tdict[a[-1]] = Test(a[-1], spe) + + tests = tdict.keys() + tests.sort() + if qmtest: if baseline: - result_stream = 'AegisBaselineStream' + aegis_result_stream = 'scons_tdb.AegisBaselineStream' qmr_file = 'baseline.qmr' else: - result_stream = 'AegisChangeStream' + aegis_result_stream = 'scons_tdb.AegisChangeStream' qmr_file = 'results.qmr' - #qmtest = r'D:\Applications\python23\scripts\qmtest.py' - qmtest = 'qmtest.py' - qmtest_args = [ - qmtest, + + if print_times: + aegis_result_stream = aegis_result_stream + "(print_time='1')" + + qmtest_args = [ qmtest, ] + + if format == '--aegis': + dir = os.path.join(cwd, 'build') + if not os.path.isdir(dir): + dir = cwd + qmtest_args.extend(['-D', dir]) + + qmtest_args.extend([ 'run', '--output %s' % qmr_file, '--format none', - '--result-stream=scons_tdb.%s' % result_stream, - ] + '--result-stream="%s"' % aegis_result_stream, + ]) if python: - qmtest_args.append('--context python=%s' % python) - - if print_times: - qmtest_args.append('--context print_time=1') + qmtest_args.append('--context python="%s"' % python) if outputfile: - #rs = '--result-stream=scons_tdb.AegisBatchStream(results_file=\\"%s\\")' % outputfile - rs = '\'--result-stream=scons_tdb.AegisBatchStream(results_file="%s")\'' % outputfile + if format == '--xml': + rsclass = 'scons_tdb.SConsXMLResultStream' + else: + rsclass = 'scons_tdb.AegisBatchStream' + qof = "r'" + outputfile + "'" + rs = '--result-stream="%s(filename=%s)"' % (rsclass, qof) qmtest_args.append(rs) - os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py') + if format == '--aegis': + tests = map(lambda x: string.replace(x, cwd+os.sep, ''), tests) + else: + os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py') - cmd = string.join(qmtest_args + args, ' ') + cmd = string.join(qmtest_args + tests, ' ') if printcommand: sys.stdout.write(cmd + '\n') sys.stdout.flush() status = 0 if execute_tests: - status = os.system(cmd) + status = os.WEXITSTATUS(os.system(cmd)) sys.exit(status) #try: @@ -617,6 +646,8 @@ if qmtest: #except OSError: # pass +tests = map(Test, tests) + class Unbuffered: def __init__(self, file): self.file = file @@ -644,20 +675,15 @@ if not python: # but time.time() does a better job on Linux systems, so let that be # the non-Windows default. -if print_times: - print_time_func = lambda fmt, time: sys.stdout.write(fmt % time) -else: - print_time_func = lambda fmt, time: None - if sys.platform == 'win32': time_func = time.clock else: time_func = time.time -if sys.platform == 'win32': - time_func = time.clock +if print_times: + print_time_func = lambda fmt, time: sys.stdout.write(fmt % time) else: - time_func = time.time + print_time_func = lambda fmt, time: None total_start_time = time_func() for t in tests: diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ccbc3af..88e70dc 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -10,10 +10,29 @@ RELEASE 0.97 - XXX + From Anonymous: + + - Allow Python Value Nodes to be Builder targets. + + From Matthias: + + - Only filter Visual Studio common filename prefixes on complete + directory names. + + From Chad Austin: + + - Fix the build of the SCons documentation on systems that don't + have "python" in the $PATH. + From Ken Boortz: - Enhance ParseConfig() to recognize options that begin with '+'. + From John Calcote, Elliot Murphy: + + - Document ways to override the CCPDBFLAGS variable to use the + Microsoft linker's /Zi option instead of the default /Z7. + From Christopher Drexler: - Make SCons aware bibtex must be called if any \include files @@ -29,6 +48,10 @@ RELEASE 0.97 - XXX - Preserve white space in display Action strfunction strings. + From James Y. Knight and Gerard Patel: + + - Support creation of shared object files from assembly language. + From Steven Knight: - Speed up the Taskmaster significantly by avoiding unnecessary @@ -47,16 +70,44 @@ RELEASE 0.97 - XXX This will become the default behavior as we add more functionality to the QMTest side. + - Let linking on mingw use the default function that chooses $CC (gcc) + or $CXX (g++) depending on whether there are any C++ source files. + + - Work around a bug in early versions of the Python 2.4 profile module + that caused the --profile= option to fail. + + - Only call Options validators and converters once when initializing a + construction environment. + + - Fix the ability of env.Append() and env.Prepend(), in all known Python + versions, to handle different input value types when the construction + variable being updated is a dictionary. + + - Add a --cache-debug option for information about what files it's + looking for in a CacheDir(). + + - Document the difference in construction variable expansion between + {Action,Builder}() and env.{Action,Builder}(). + From Arve Knudsen: - Support cleaning and scanning SWIG-generated files. - From Baptiste Lepilleur: + From Carsten Koch: + + - Allow selection of Visual Studio version by setting $MSVS_VERSION + after construction environment initialization. + + From Jean-Baptiste Lab: - Try using zipimport if we can't import Tool or Platform modules using the normal "imp" module. This allows SCons to be packaged using py2exe's all-in-one-zip-file approach. + From Ben Liblit: + + - Do not re-scan files if the scanner returns no implicit dependencies. + From Sanjoy Mahajan: - Change use of $SOURCES to $SOURCE in all TeX-related Tool modules. @@ -70,6 +121,19 @@ RELEASE 0.97 - XXX - Prevent scanning the TeX .aux file for additional files from trying to remove it twice when the -c option is used. + From Leanid Nazdrynau: + + - Give the MSVC RES (resource) Builder a src_builder list and a .rc + src_suffix so other builders can generate .rc files. + + From Matthew A. Nicholson: + + - Enhance Install() and InstallAs() to handle directory trees as sources. + + From Jan Nijtmans: + + - Don't use the -fPIC flag when using gcc on Windows (e.g. MinGW). + From Greg Noel: - Add an env.ParseFlags() method that provides separate logic for @@ -105,10 +169,36 @@ RELEASE 0.97 - XXX - Initial infrastructure for running SCons tests under QMTest. + From Sohail Sumani: + + - Fix tests that fail due to gcc warnings. + + From Dobes Vandermeer: + + - In stack traces, print the full paths of SConscript files. + From Atul Varma: - Fix detection of Visual C++ Express Edition. + From Dobes Vandermeer: + + - Let the src_dir option to the SConscript() function affect all the + the source file paths, instead of treating all source files paths + as relative to the SConscript directory itself. + + From Nicolas Vigier: + + - Fix finding Fortran modules in build directories. + + - Fix use of BuildDir() when the source file in the source directory + is a symlink with a relative path. + + From Edward Wang: + + - Fix the Memoizer when the SCons Python modules are executed from + .pyo files at different locations from where they were compiled. + From Johan Zander: - Fix missing os.path.join() when constructing the $FRAMEWORKSDKDIR/bin. diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 9d6c972..c762f1c 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -2,6 +2,7 @@ SCons/__init__.py SCons/Action.py SCons/Builder.py SCons/Conftest.py +SCons/cpp.py SCons/dblite.py SCons/Debug.py SCons/Defaults.py diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 1085586..57910de 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -182,6 +182,8 @@ if os.name == 'java': else: python = sys.executable +_python_ = '"' + python + '"' + class ActionTestCase(unittest.TestCase): """Test the Action() factory function""" @@ -903,7 +905,7 @@ class CommandActionTestCase(unittest.TestCase): except AttributeError: env = Environment() - cmd1 = r'%s %s %s xyzzy' % (python, act_py, outfile) + cmd1 = r'%s %s %s xyzzy' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd1) r = act([], [], env.Copy()) @@ -911,7 +913,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'xyzzy'\n", c - cmd2 = r'%s %s %s $TARGET' % (python, act_py, outfile) + cmd2 = r'%s %s %s $TARGET' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd2) r = act(DummyNode('foo'), [], env.Copy()) @@ -919,7 +921,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'foo'\n", c - cmd3 = r'%s %s %s ${TARGETS}' % (python, act_py, outfile) + cmd3 = r'%s %s %s ${TARGETS}' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd3) r = act(map(DummyNode, ['aaa', 'bbb']), [], env.Copy()) @@ -927,7 +929,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'aaa' 'bbb'\n", c - cmd4 = r'%s %s %s $SOURCES' % (python, act_py, outfile) + cmd4 = r'%s %s %s $SOURCES' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd4) r = act([], [DummyNode('one'), DummyNode('two')], env.Copy()) @@ -935,7 +937,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'one' 'two'\n", c - cmd4 = r'%s %s %s ${SOURCES[:2]}' % (python, act_py, outfile) + cmd4 = r'%s %s %s ${SOURCES[:2]}' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd4) sources = [DummyNode('three'), DummyNode('four'), DummyNode('five')] @@ -945,7 +947,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'three' 'four'\n", c - cmd5 = r'%s %s %s $TARGET XYZZY' % (python, act_py, outfile) + cmd5 = r'%s %s %s $TARGET XYZZY' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd5) env5 = Environment() @@ -978,7 +980,7 @@ class CommandActionTestCase(unittest.TestCase): def get_subst_proxy(self): return self - cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (python, act_py, outfile) + cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd6) r = act(target = [Obj('111'), Obj('222')], @@ -1016,31 +1018,31 @@ class CommandActionTestCase(unittest.TestCase): r = act([], [], env.Copy(out = outfile)) assert r == expect_nonexecutable, "r == %d" % r - act = SCons.Action.CommandAction('%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 1, r - act = SCons.Action.CommandAction('@%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 1, r - act = SCons.Action.CommandAction('@-%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@-%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r - act = SCons.Action.CommandAction('-%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('-%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r - act = SCons.Action.CommandAction('@ %s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@ %s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 1, r - act = SCons.Action.CommandAction('@- %s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@- %s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r - act = SCons.Action.CommandAction('- %s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('- %s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r @@ -1074,7 +1076,7 @@ class CommandActionTestCase(unittest.TestCase): # test redirection operators def test_redirect(self, redir, stdout_msg, stderr_msg): - cmd = r'%s %s %s xyzzy %s' % (python, act_py, outfile, redir) + cmd = r'%s %s %s xyzzy %s' % (_python_, act_py, outfile, redir) # Write the output and error messages to files because # Windows can't handle strings that are too big in its # external environment (os.spawnve() returns EINVAL, @@ -1571,7 +1573,7 @@ class ListActionTestCase(unittest.TestCase): a([], [], Environment(s = self)) assert self.inc == 3, self.inc - cmd2 = r'%s %s %s syzygy' % (python, act_py, outfile) + cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile) def function2(target, source, env): open(env['out'], 'a').write("function2\n") @@ -1644,7 +1646,7 @@ class LazyActionTestCase(unittest.TestCase): a = SCons.Action.Action('$BAR') a([], [], env=Environment(BAR = f, s = self)) assert self.test == 1, self.test - cmd = r'%s %s %s lazy' % (python, act_py, outfile) + cmd = r'%s %s %s lazy' % (_python_, act_py, outfile) a([], [], env=Environment(BAR = cmd, s = self)) c = test.read(outfile, 'r') assert c == "act.py: 'lazy'\n", c diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 1cff9c6..47d2134 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -119,20 +119,22 @@ else: caller_dicts = {} -def caller(back=0): +def caller(*backlist): import traceback - tb = traceback.extract_stack(limit=3+back) - key = tb[1][:3] - try: - entry = caller_dicts[key] - except KeyError: - entry = caller_dicts[key] = {} - key = tb[0][:3] - try: - entry[key] = entry[key] + 1 - except KeyError: - entry[key] = 1 - return '%s:%d(%s)' % func_shorten(key) + if not backlist: + backlist = [0] + result = [] + for back in backlist: + tb = traceback.extract_stack(limit=3+back) + key = tb[1][:3] + try: + entry = caller_dicts[key] + except KeyError: + entry = caller_dicts[key] = {} + key = tb[0][:3] + entry[key] = entry.get(key, 0) + 1 + result.append('%s:%d(%s)' % func_shorten(key)) + return result def dump_caller_counts(file=sys.stdout): keys = caller_dicts.keys() diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index cb628b8..7513c0d 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -173,14 +173,34 @@ Touch = ActionFactory(touch_func, lambda file: 'Touch("%s")' % file) # Internal utility functions -def copyFunc(dest, source, env): - """Install a source file into a destination by copying it (and its - permission/mode bits).""" - shutil.copy2(source, dest) - st = os.stat(source) - os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) +def installFunc(dest, source, env): + """Install a source file or directory into a destination by copying, + (including copying permission/mode bits).""" + + if os.path.isdir(source): + if os.path.exists(dest): + if not os.path.isdir(dest): + raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source)) + else: + parent = os.path.split(dest)[0] + if not os.path.exists(parent): + os.makedirs(parent) + shutil.copytree(source, dest) + else: + shutil.copy2(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + return 0 +def installStr(dest, source, env): + source = str(source) + if os.path.isdir(source): + type = 'directory' + else: + type = 'file' + return 'Install %s: "%s" as "%s"' % (type, source, dest) + def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None): """Creates a new list from 'list' by first interpolating each element in the list using the 'env' dictionary and then calling f @@ -334,13 +354,14 @@ ConstructionEnvironment = { 'SCANNERS' : [], 'CONFIGUREDIR' : '#/.sconf_temp', 'CONFIGURELOG' : '#/config.log', - 'INSTALLSTR' : 'Install file: "$SOURCE" as "$TARGET"', 'CPPSUFFIXES' : SCons.Tool.CSuffixes, 'DSUFFIXES' : SCons.Tool.DSuffixes, + 'ENV' : {}, 'IDLSUFFIXES' : SCons.Tool.IDLSuffixes, + 'INSTALL' : installFunc, + 'INSTALLSTR' : installStr, + '_installStr' : installStr, 'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes, - 'ENV' : {}, - 'INSTALL' : copyFunc, '_concat' : _concat, '_defines' : _defines, '_stripixes' : _stripixes, diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index d76f71d..7aa1909 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -84,7 +84,11 @@ def installFunc(target, source, env): return install(target[0].path, source[0].path, env) def installString(target, source, env): - return env.subst_target_source(env['INSTALLSTR'], 0, target, source) + s = env.get('INSTALLSTR', '') + if callable(s): + return s(target[0].path, source[0].path, env) + else: + return env.subst_target_source(s, 0, target, source) installAction = SCons.Action.Action(installFunc, installString) @@ -742,21 +746,31 @@ class Base(SubstitutionEnvironment): # environment before calling the tools, because they may use # some of them during initialization. apply(self.Replace, (), kw) + keys = kw.keys() if options: + keys = keys + options.keys() options.Update(self) + save = {} + for k in keys: + try: + save[k] = self._dict[k] + except KeyError: + # No value may have been set if they tried to pass in a + # reserved variable name like TARGETS. + pass + if tools is None: tools = self._dict.get('TOOLS', None) if tools is None: tools = ['default'] apply_tools(self, tools, toolpath) - # Now re-apply the passed-in variables and customizable options + # Now restore the passed-in variables and customized options # to the environment, since the values the user set explicitly # should override any values set by the tools. - apply(self.Replace, (), kw) - if options: - options.Update(self) + for key, val in save.items(): + self._dict[key] = val ####################################################################### # Utility methods that are primarily for internal use by SCons. @@ -895,19 +909,19 @@ class Base(SubstitutionEnvironment): self._dict[key] = val else: try: - # Most straightforward: just try to add them - # together. This will work in most cases, when the - # original and new values are of compatible types. - self._dict[key] = orig + val - except TypeError: + # Check if the original looks like a dictionary. + # If it is, we can't just try adding the value because + # dictionaries don't have __add__() methods, and + # things like UserList will incorrectly coerce the + # original dict to a list (which we don't want). + update_dict = orig.update + except AttributeError: try: - # Try to update a dictionary value with another. - # If orig isn't a dictionary, it won't have an - # update() method; if val isn't a dictionary, - # it won't have a keys() method. Either way, - # it's an AttributeError. - orig.update(val) - except AttributeError: + # Most straightforward: just try to add them + # together. This will work in most cases, when the + # original and new values are of compatible types. + self._dict[key] = orig + val + except (KeyError, TypeError): try: # Check if the original is a list. add_to_orig = orig.append @@ -925,6 +939,17 @@ class Base(SubstitutionEnvironment): # value to it (if there's a value to append). if val: add_to_orig(val) + else: + # The original looks like a dictionary, so update it + # based on what we think the value looks like. + if SCons.Util.is_List(val): + for v in val: + orig[v] = None + else: + try: + update_dict(val) + except (AttributeError, TypeError, ValueError): + orig[val] = None self.scanner_map_delete(kw) def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): @@ -952,7 +977,7 @@ class Base(SubstitutionEnvironment): """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): - if not self._dict.has_key(key) or not self._dict[key]: + if not self._dict.has_key(key) or self._dict[key] in ('', None): self._dict[key] = val elif SCons.Util.is_Dict(self._dict[key]) and \ SCons.Util.is_Dict(val): @@ -1134,19 +1159,19 @@ class Base(SubstitutionEnvironment): self._dict[key] = val else: try: - # Most straightforward: just try to add them - # together. This will work in most cases, when the - # original and new values are of compatible types. - self._dict[key] = val + orig - except TypeError: + # Check if the original looks like a dictionary. + # If it is, we can't just try adding the value because + # dictionaries don't have __add__() methods, and + # things like UserList will incorrectly coerce the + # original dict to a list (which we don't want). + update_dict = orig.update + except AttributeError: try: - # Try to update a dictionary value with another. - # If orig isn't a dictionary, it won't have an - # update() method; if val isn't a dictionary, - # it won't have a keys() method. Either way, - # it's an AttributeError. - orig.update(val) - except AttributeError: + # Most straightforward: just try to add them + # together. This will work in most cases, when the + # original and new values are of compatible types. + self._dict[key] = val + orig + except (KeyError, TypeError): try: # Check if the added value is a list. add_to_val = val.append @@ -1164,6 +1189,17 @@ class Base(SubstitutionEnvironment): if orig: add_to_val(orig) self._dict[key] = val + else: + # The original looks like a dictionary, so update it + # based on what we think the value looks like. + if SCons.Util.is_List(val): + for v in val: + orig[v] = None + else: + try: + update_dict(val) + except (AttributeError, TypeError, ValueError): + orig[val] = None self.scanner_map_delete(kw) def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): @@ -1191,7 +1227,7 @@ class Base(SubstitutionEnvironment): """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): - if not self._dict.has_key(key) or not self._dict[key]: + if not self._dict.has_key(key) or self._dict[key] in ('', None): self._dict[key] = val elif SCons.Util.is_Dict(self._dict[key]) and \ SCons.Util.is_Dict(val): @@ -1504,25 +1540,37 @@ class Base(SubstitutionEnvironment): try: dnodes = self.arg2nodes(dir, self.fs.Dir) except TypeError: - raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir) + fmt = "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" + raise SCons.Errors.UserError, fmt % str(dir) try: - sources = self.arg2nodes(source, self.fs.File) + sources = self.arg2nodes(source, self.fs.Entry) except TypeError: if SCons.Util.is_List(source): - raise SCons.Errors.UserError, "Source `%s' of Install() contains one or more non-files. Install() source must be one or more files." % repr(map(str, source)) + s = repr(map(str, source)) else: - raise SCons.Errors.UserError, "Source `%s' of Install() is not a file. Install() source must be one or more files." % str(source) + s = str(source) + fmt = "Source `%s' of Install() is neither a file nor a directory. Install() source must be one or more files or directories" + raise SCons.Errors.UserError, fmt % s tgt = [] for dnode in dnodes: for src in sources: - target = self.fs.File(src.name, dnode) + target = self.fs.Entry(src.name, dnode) tgt.extend(InstallBuilder(self, target, src)) return tgt def InstallAs(self, target, source): """Install sources as targets.""" - sources = self.arg2nodes(source, self.fs.File) - targets = self.arg2nodes(target, self.fs.File) + sources = self.arg2nodes(source, self.fs.Entry) + targets = self.arg2nodes(target, self.fs.Entry) + if len(sources) != len(targets): + if not SCons.Util.is_List(target): + target = [target] + if not SCons.Util.is_List(source): + source = [source] + t = repr(map(str, target)) + s = repr(map(str, source)) + fmt = "Target (%s) and source (%s) lists of InstallAs() must be the same length." + raise SCons.Errors.UserError, fmt % (t, s) result = [] for src, tgt in map(lambda x, y: (x, y), sources, targets): result.extend(InstallBuilder(self, tgt, src)) @@ -1632,10 +1680,10 @@ class Base(SubstitutionEnvironment): else: raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type - def Value(self, value): + def Value(self, value, built_value=None): """ """ - return SCons.Node.Python.Value(value) + return SCons.Node.Python.Value(value, built_value) class OverrideEnvironment(Base): """A proxy that overrides variables in a wrapped construction diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index c56f1f5..52aac23 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -23,6 +23,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import copy import os import string import StringIO @@ -595,15 +596,17 @@ sys.exit(1) save_stderr = sys.stderr + python = '"' + sys.executable + '"' + try: - cmd = '%s %s' % (sys.executable, test.workpath('stdout.py')) + cmd = '%s %s' % (python, test.workpath('stdout.py')) output = env.backtick(cmd) assert output == 'this came from stdout.py\n', output sys.stderr = StringIO.StringIO() - cmd = '%s %s' % (sys.executable, test.workpath('stderr.py')) + cmd = '%s %s' % (python, test.workpath('stderr.py')) output = env.backtick(cmd) errout = sys.stderr.getvalue() @@ -612,7 +615,7 @@ sys.exit(1) sys.stderr = StringIO.StringIO() - cmd = '%s %s' % (sys.executable, test.workpath('fail.py')) + cmd = '%s %s' % (python, test.workpath('fail.py')) try: env.backtick(cmd) except OSError, e: @@ -747,6 +750,24 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert not env1.has_key('__env__') assert not env2.has_key('__env__') + def test_options(self): + """Test that options only get applied once.""" + class FakeOptions: + def __init__(self, key, val): + self.calls = 0 + self.key = key + self.val = val + def keys(self): + return [self.key] + def Update(self, env): + env[self.key] = self.val + self.calls = self.calls + 1 + + o = FakeOptions('AAA', 'fake_opt') + env = Environment(options=o, AAA='keyword_arg') + assert o.calls == 1, o.calls + assert env['AAA'] == 'fake_opt', env['AAA'] + def test_get(self): """Test the get() method.""" env = self.TestEnvironment(aaa = 'AAA') @@ -1212,6 +1233,8 @@ def exists(env): b2 = Environment()['BUILDERS'] assert b1 == b2, diff_dict(b1, b2) + import UserDict + UD = UserDict.UserDict import UserList UL = UserList.UserList @@ -1243,6 +1266,18 @@ def exists(env): UL(['i7']), [''], UL(['i7', '']), UL(['i8']), UL(['']), UL(['i8', '']), + {'d1':1}, 'D1', {'d1':1, 'D1':None}, + {'d2':1}, ['D2'], {'d2':1, 'D2':None}, + {'d3':1}, UL(['D3']), {'d3':1, 'D3':None}, + {'d4':1}, {'D4':1}, {'d4':1, 'D4':1}, + {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}), + + UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}), + UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}), + UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}), + UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}), + UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}), + '', 'M1', 'M1', '', ['M2'], ['M2'], '', UL(['M3']), UL(['M3']), @@ -1293,14 +1328,21 @@ def exists(env): failed = 0 while cases: input, append, expect = cases[:3] - env['XXX'] = input - env.Append(XXX = append) - result = env['XXX'] - if result != expect: + env['XXX'] = copy.copy(input) + try: + env.Append(XXX = append) + except Exception, e: if failed == 0: print - print " %s Append %s => %s did not match %s" % \ - (repr(input), repr(append), repr(result), repr(expect)) + print " %s Append %s exception: %s" % \ + (repr(input), repr(append), e) failed = failed + 1 + else: + result = env['XXX'] + if result != expect: + if failed == 0: print + print " %s Append %s => %s did not match %s" % \ + (repr(input), repr(append), repr(result), repr(expect)) + failed = failed + 1 del cases[:3] assert failed == 0, "%d Append() cases failed" % failed @@ -1399,6 +1441,33 @@ def exists(env): assert env['CCC1'] == 'c1', env['CCC1'] assert env['CCC2'] == ['c2'], env['CCC2'] + env['CLVar'] = CLVar([]) + env.AppendUnique(CLVar = 'bar') + result = env['CLVar'] + if sys.version[0] == '1': + # Python 1.5.2 has a quirky behavior where CLVar([]) actually + # matches '' and [] due to different __coerce__() semantics + # in the UserList implementation. It isn't worth a lot of + # effort to get this corner case to work identically (support + # for Python 1.5 support will die soon anyway), so just treat + # it separately for now. + assert result == 'bar', result + else: + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + + env['CLVar'] = CLVar(['abc']) + env.AppendUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['abc', 'bar'], result + + env['CLVar'] = CLVar(['bar']) + env.AppendUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + def test_Copy(self): """Test construction environment copying @@ -1784,6 +1853,8 @@ f5: \ def test_Prepend(self): """Test prepending to construction variables in an Environment """ + import UserDict + UD = UserDict.UserDict import UserList UL = UserList.UserList @@ -1815,6 +1886,18 @@ f5: \ UL(['i7']), [''], UL(['', 'i7']), UL(['i8']), UL(['']), UL(['', 'i8']), + {'d1':1}, 'D1', {'d1':1, 'D1':None}, + {'d2':1}, ['D2'], {'d2':1, 'D2':None}, + {'d3':1}, UL(['D3']), {'d3':1, 'D3':None}, + {'d4':1}, {'D4':1}, {'d4':1, 'D4':1}, + {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}), + + UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}), + UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}), + UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}), + UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}), + UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}), + '', 'M1', 'M1', '', ['M2'], ['M2'], '', UL(['M3']), UL(['M3']), @@ -1865,14 +1948,21 @@ f5: \ failed = 0 while cases: input, prepend, expect = cases[:3] - env['XXX'] = input - env.Prepend(XXX = prepend) - result = env['XXX'] - if result != expect: + env['XXX'] = copy.copy(input) + try: + env.Prepend(XXX = prepend) + except Exception, e: if failed == 0: print - print " %s Prepend %s => %s did not match %s" % \ - (repr(input), repr(prepend), repr(result), repr(expect)) + print " %s Prepend %s exception: %s" % \ + (repr(input), repr(prepend), e) failed = failed + 1 + else: + result = env['XXX'] + if result != expect: + if failed == 0: print + print " %s Prepend %s => %s did not match %s" % \ + (repr(input), repr(prepend), repr(result), repr(expect)) + failed = failed + 1 del cases[:3] assert failed == 0, "%d Prepend() cases failed" % failed @@ -1965,6 +2055,33 @@ f5: \ assert env['CCC1'] == 'c1', env['CCC1'] assert env['CCC2'] == ['c2'], env['CCC2'] + env['CLVar'] = CLVar([]) + env.PrependUnique(CLVar = 'bar') + result = env['CLVar'] + if sys.version[0] == '1': + # Python 1.5.2 has a quirky behavior where CLVar([]) actually + # matches '' and [] due to different __coerce__() semantics + # in the UserList implementation. It isn't worth a lot of + # effort to get this corner case to work identically (support + # for Python 1.5 support will die soon anyway), so just treat + # it separately for now. + assert result == 'bar', result + else: + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + + env['CLVar'] = CLVar(['abc']) + env.PrependUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['bar', 'abc'], result + + env['CLVar'] = CLVar(['bar']) + env.PrependUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + def test_Replace(self): """Test replacing construction variables in an Environment @@ -2650,23 +2767,23 @@ def generate(env): for tnode in tgt: assert tnode.builder == InstallBuilder - exc_caught = None - try: - tgt = env.Install('export', 'export') - except SCons.Errors.UserError, e: - exc_caught = 1 - assert exc_caught, "UserError should be thrown when Install() target is not a file." - match = str(e) == "Source `export' of Install() is not a file. Install() source must be one or more files." - assert match, e + tgt = env.Install('export', 'build') + paths = map(str, tgt) + paths.sort() + expect = ['export/build'] + assert paths == expect, paths + for tnode in tgt: + assert tnode.builder == InstallBuilder - exc_caught = None - try: - tgt = env.Install('export', ['export', 'build/foo1']) - except SCons.Errors.UserError, e: - exc_caught = 1 - assert exc_caught, "UserError should be thrown when Install() target containins non-files." - match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files. Install() source must be one or more files." - assert match, e + tgt = env.Install('export', ['build', 'build/foo1']) + paths = map(str, tgt) + paths.sort() + expect = ['export/build', 'export/foo1'] + assert paths == expect, paths + for tnode in tgt: + assert tnode.builder == InstallBuilder + + env.File('export/foo1') exc_caught = None try: @@ -2674,8 +2791,8 @@ def generate(env): except SCons.Errors.UserError, e: exc_caught = 1 assert exc_caught, "UserError should be thrown reversing the order of Install() targets." - match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" - assert match, e + expect = "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" + assert str(e) == expect, e def test_InstallAs(self): """Test the InstallAs method""" @@ -2956,6 +3073,9 @@ def generate(env): assert not v1 is v2 assert v1.value == v2.value + v3 = env.Value('c', 'build-c') + assert v3.value == 'c', v3.value + def test_Environment_global_variable(type): diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index 134206f..c2a3027 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.py @@ -798,9 +798,14 @@ else: # Make sure filename has os.sep+'SCons'+os.sep so that # SCons.Script.find_deepest_user_frame doesn't stop here import inspect # It's OK, can't get here for Python < 2.1 + filename = inspect.getsourcefile(_MeMoIZeR_superinit) + if not filename: + # This file was compiled at a path name different from + # how it's invoked now, so just make up something. + filename = whoami('superinit', '???') superinitcode = compile( "lambda self, *args, **kw: MPI(self, cls, args, kw)", - inspect.getsourcefile(_MeMoIZeR_superinit) or '<unknown>', + filename, "eval") superinit = eval(superinitcode, {'cls':cls, diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index ce5bcc0..382bca3 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -95,10 +95,33 @@ def save_strings(val): # there should be *no* changes to the external file system(s)... # -def _copy_func(src, dest): +if hasattr(os, 'link'): + def _hardlink_func(fs, src, dst): + # If the source is a symlink, we can't just hard-link to it + # because a relative symlink may point somewhere completely + # different. We must disambiguate the symlink and then + # hard-link the final destination file. + while fs.islink(src): + link = fs.readlink(src) + if not os.path.isabs(link): + src = link + else: + src = os.path.join(os.path.dirname(src), link) + fs.link(src, dst) +else: + _hardlink_func = None + +if hasattr(os, 'symlink'): + def _softlink_func(fs, src, dst): + fs.symlink(src, dst) +else: + _softlink_func = None + +def _copy_func(fs, src, dest): shutil.copy2(src, dest) - st=os.stat(src) - os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + st = fs.stat(src) + fs.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + Valid_Duplicates = ['hard-soft-copy', 'soft-hard-copy', 'hard-copy', 'soft-copy', 'copy'] @@ -113,16 +136,6 @@ def set_duplicate(duplicate): # underlying implementations. We do this inside this function, # not in the top-level module code, so that we can remap os.link # and os.symlink for testing purposes. - try: - _hardlink_func = os.link - except AttributeError: - _hardlink_func = None - - try: - _softlink_func = os.symlink - except AttributeError: - _softlink_func = None - link_dict = { 'hard' : _hardlink_func, 'soft' : _softlink_func, @@ -152,10 +165,11 @@ def LinkFunc(target, source, env): if not Link_Funcs: # Set a default order of link functions. set_duplicate('hard-soft-copy') + fs = source[0].fs # Now link the files with the previously specified order. for func in Link_Funcs: try: - func(src,dest) + func(fs, src, dest) break except (IOError, OSError): # An OSError indicates something happened like a permissions @@ -213,13 +227,15 @@ def CacheRetrieveFunc(target, source, env): t = target[0] fs = t.fs cachedir, cachefile = t.cachepath() - if fs.exists(cachefile): - if SCons.Action.execute_actions: - fs.copy2(cachefile, t.path) - st = fs.stat(cachefile) - fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) - return 0 - return 1 + if not fs.exists(cachefile): + fs.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile) + return 1 + fs.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile) + if SCons.Action.execute_actions: + fs.copy2(cachefile, t.path) + st = fs.stat(cachefile) + fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + return 0 def CacheRetrieveString(target, source, env): t = target[0] @@ -237,9 +253,18 @@ def CachePushFunc(target, source, env): fs = t.fs cachedir, cachefile = t.cachepath() if fs.exists(cachefile): - # Don't bother copying it if it's already there. + # Don't bother copying it if it's already there. Note that + # usually this "shouldn't happen" because if the file already + # existed in cache, we'd have retrieved the file from there, + # not built it. This can happen, though, in a race, if some + # other person running the same build pushes their copy to + # the cache after we decide we need to build it but before our + # build completes. + fs.CacheDebug('CachePush(%s): %s already exists in cache\n', t, cachefile) return + fs.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile) + if not fs.isdir(cachedir): fs.makedirs(cachedir) @@ -258,7 +283,6 @@ def CachePushFunc(target, source, env): SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning, "Unable to copy %s to cache. Cache file is %s" % (str(target), cachefile)) - return CachePush = SCons.Action.Action(CachePushFunc, None) @@ -835,6 +859,14 @@ class LocalFS: def islink(self, path): return 0 # no symlinks + if hasattr(os, 'readlink'): + def readlink(self, file): + return os.readlink(file) + else: + def readlink(self, file): + return '' + + if SCons.Memoize.use_old_memoization(): _FSBase = LocalFS class LocalFS(SCons.Memoize.Memoizer, _FSBase): @@ -1139,6 +1171,21 @@ class FS(LocalFS): result.extend(dir.get_all_rdirs()) return result + def CacheDebugWrite(self, fmt, target, cachefile): + self.CacheDebugFP.write(fmt % (target, os.path.split(cachefile)[1])) + + def CacheDebugQuiet(self, fmt, target, cachefile): + pass + + CacheDebug = CacheDebugQuiet + + def CacheDebugEnable(self, file): + if file == '-': + self.CacheDebugFP = sys.stdout + else: + self.CacheDebugFP = open(file, 'w') + self.CacheDebug = self.CacheDebugWrite + def CacheDir(self, path): self.CachePath = path @@ -1776,7 +1823,7 @@ class File(Base): __cacheable__""" if not scanner: return [] - return map(lambda N: N.disambiguate(), scanner(self, env, path)) + return scanner(self, env, path) def _createDir(self): # ensure that the directories for this node are @@ -1818,11 +1865,14 @@ class File(Base): if self.fs.cache_show: if CacheRetrieveSilent(self, [], None, execute=1) == 0: self.build(presub=0, execute=0) + self.set_state(SCons.Node.executed) return 1 elif CacheRetrieve(self, [], None, execute=1) == 0: + self.set_state(SCons.Node.executed) return 1 return None + def built(self): """Called just after this node is successfully built. __cache_reset__""" diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 98e08a9..1b38ffe 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -425,57 +425,39 @@ class BuildDirTestCase(unittest.TestCase): class LinkSimulator : """A class to intercept os.[sym]link() calls and track them.""" - def __init__( self, duplicate ) : + def __init__( self, duplicate, link, symlink, copy ) : self.duplicate = duplicate - self._reset() - - def _reset( self ) : - """Reset the simulator if necessary""" - if not self._need_reset() : return # skip if not needed now - self.links_to_be_called = self.duplicate - - def _need_reset( self ) : - """ - Determines whether or not the simulator needs to be reset. - A reset is necessary if the object is first being initialized, - or if all three methods have been tried already. - """ - return ( - ( not hasattr( self , "links_to_be_called" ) ) - or - (self.links_to_be_called == "") - ) + self.have = {} + self.have['hard'] = link + self.have['soft'] = symlink + self.have['copy'] = copy + + self.links_to_be_called = [] + for link in string.split(self.duplicate, '-'): + if self.have[link]: + self.links_to_be_called.append(link) def link_fail( self , src , dest ) : - self._reset() - l = string.split(self.links_to_be_called, "-") - next_link = l[0] - assert next_link == "hard", \ + next_link = self.links_to_be_called.pop(0) + assert next_link == "hard", \ "Wrong link order: expected %s to be called "\ "instead of hard" % next_link - self.links_to_be_called = string.join(l[1:], '-') raise OSError( "Simulating hard link creation error." ) def symlink_fail( self , src , dest ) : - self._reset() - l = string.split(self.links_to_be_called, "-") - next_link = l[0] - assert next_link == "soft", \ + next_link = self.links_to_be_called.pop(0) + assert next_link == "soft", \ "Wrong link order: expected %s to be called "\ "instead of soft" % next_link - self.links_to_be_called = string.join(l[1:], '-') raise OSError( "Simulating symlink creation error." ) def copy( self , src , dest ) : - self._reset() - l = string.split(self.links_to_be_called, "-") - next_link = l[0] - assert next_link == "copy", \ + next_link = self.links_to_be_called.pop(0) + assert next_link == "copy", \ "Wrong link order: expected %s to be called "\ "instead of copy" % next_link - self.links_to_be_called = string.join(l[1:], '-') # copy succeeds, but use the real copy - self._real_copy(src, dest) + self.have['copy'](src, dest) # end class LinkSimulator try: @@ -485,32 +467,31 @@ class BuildDirTestCase(unittest.TestCase): pass for duplicate in SCons.Node.FS.Valid_Duplicates: - simulator = LinkSimulator(duplicate) - # save the real functions for later restoration - real_link = None - real_symlink = None try: real_link = os.link except AttributeError: - pass + real_link = None try: real_symlink = os.symlink except AttributeError: - pass + real_symlink = None real_copy = shutil.copy2 - simulator._real_copy = real_copy # the simulator needs the real one + + simulator = LinkSimulator(duplicate, real_link, real_symlink, real_copy) # override the real functions with our simulation os.link = simulator.link_fail os.symlink = simulator.symlink_fail shutil.copy2 = simulator.copy - SCons.Node.FS.set_duplicate(duplicate) - - src_foo = test.workpath('src', 'foo') - build_foo = test.workpath('build', 'foo') try: + + SCons.Node.FS.set_duplicate(duplicate) + + src_foo = test.workpath('src', 'foo') + build_foo = test.workpath('build', 'foo') + test.write(src_foo, 'src/foo\n') os.chmod(src_foo, stat.S_IRUSR) try: diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 99dc5b0..a639aee 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -45,16 +45,18 @@ class Value(SCons.Node.Node): NodeInfo = ValueNodeInfo BuildInfo = ValueBuildInfo - def __init__(self, value): + def __init__(self, value, built_value=None): SCons.Node.Node.__init__(self) self.value = value + if not built_value is None: + self.built_value = built_value def __str__(self): return repr(self.value) - def build(self): - """A "builder" for Values.""" - pass + def build(self, **kw): + if not hasattr(self, 'built_value'): + apply (SCons.Node.Node.build, (self,), kw) current = SCons.Node.Node.children_are_up_to_date @@ -64,9 +66,23 @@ class Value(SCons.Node.Node): # are outside the filesystem: return 1 + def write(self, built_value): + """Set the value of the node.""" + self.built_value = built_value + + def read(self): + """Return the value. If necessary, the value is built.""" + self.build() + if not hasattr(self, 'built_value'): + self.built_value = self.value + return self.built_value + def get_contents(self): - """The contents of a Value are the concatenation - of all the contents of its sources with the node's value itself.""" + """By the assumption that the node.built_value is a + deterministic product of the sources, the contents of a Value + are the concatenation of all the contents of its sources. As + the value need not be built when get_contents() is called, we + cannot use the actual node.built_value.""" contents = str(self.value) for kid in self.children(None): contents = contents + kid.get_contents() diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 0801fb3..62bcf8b 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -45,6 +45,44 @@ class ValueTestCase(unittest.TestCase): assert not v1 is v2 assert v1.value == v2.value + v3 = SCons.Node.Python.Value('c', 'cb') + assert v3.built_value == 'cb' + + def test_build(self): + """Test "building" a Value Node + """ + class fake_executor: + def __call__(self, node, exitstatfunc): + node.write('faked') + + v1 = SCons.Node.Python.Value('b', 'built') + v1.executor = fake_executor() + v1.build() + assert v1.built_value == 'built', v1.built_value + + v2 = SCons.Node.Python.Value('b') + v2.executor = fake_executor() + v2.build() + assert v2.built_value == 'faked', v2.built_value + + def test_read(self): + """Test the Value.read() method + """ + v1 = SCons.Node.Python.Value('a') + x = v1.read() + assert x == 'a', x + + def test_write(self): + """Test the Value.write() method + """ + v1 = SCons.Node.Python.Value('a') + assert v1.value == 'a', v1.value + assert not hasattr(v1, 'built_value') + + v1.write('new') + assert v1.value == 'a', v1.value + assert v1.built_value == 'new', v1.built_value + def test_get_csig(self): """Test calculating the content signature of a Value() object """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index bda3a48..42be5b1 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -474,6 +474,7 @@ class Node: d = filter(lambda x, seen=seen: not seen.has_key(x), n.get_found_includes(env, scanner, path)) if d: + d = map(lambda N: N.disambiguate(), d) deps.extend(d) for n in d: seen[n] = 1 @@ -538,7 +539,7 @@ class Node: # Here's where we implement --implicit-cache. if implicit_cache and not implicit_deps_changed: implicit = self.get_stored_implicit() - if implicit: + if implicit is not None: factory = build_env.get_factory(self.builder.source_factory) nodes = [] for i in implicit: diff --git a/src/engine/SCons/Options/ListOption.py b/src/engine/SCons/Options/ListOption.py index d14b22a..5aa508a 100644 --- a/src/engine/SCons/Options/ListOption.py +++ b/src/engine/SCons/Options/ListOption.py @@ -65,7 +65,7 @@ class _ListOption(UserList.UserList): UserList.UserList.__init__(self, filter(None, initlist)) self.allowedElems = allowedElems[:] self.allowedElems.sort() - + def __cmp__(self, other): raise NotImplementedError def __eq__(self, other): @@ -88,7 +88,7 @@ class _ListOption(UserList.UserList): return string.join(self, ',') def __repr__(self): return self.__str__() - + def _converter(val, allowedElems, mapdict): """ """ diff --git a/src/engine/SCons/Options/ListOptionTests.py b/src/engine/SCons/Options/ListOptionTests.py index a892e18..22378bc 100644 --- a/src/engine/SCons/Options/ListOptionTests.py +++ b/src/engine/SCons/Options/ListOptionTests.py @@ -122,9 +122,6 @@ class ListOptionTestCase(unittest.TestCase): l = o.converter('all') n = l.__class__(copy.copy(l)) - def test___repr__(self): - """Test copying a ListOption like an Environment would""" - if __name__ == "__main__": suite = unittest.makeSuite(ListOptionTestCase, 'test_') if not unittest.TextTestRunner().run(suite).wasSuccessful(): diff --git a/src/engine/SCons/Options/OptionsTests.py b/src/engine/SCons/Options/OptionsTests.py index aeffe2d..1d9b851 100644 --- a/src/engine/SCons/Options/OptionsTests.py +++ b/src/engine/SCons/Options/OptionsTests.py @@ -59,6 +59,19 @@ def checkSave(file, expected): class OptionsTestCase(unittest.TestCase): + def test_keys(self): + """Test the Options.keys() method""" + opts = SCons.Options.Options() + + opts.Add('VAR1') + opts.Add('VAR2', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + keys = opts.keys() + assert keys == ['VAR1', 'VAR2'], keys + def test_Add(self): """Test adding to an Options object""" opts = SCons.Options.Options() diff --git a/src/engine/SCons/Options/__init__.py b/src/engine/SCons/Options/__init__.py index 7333985..83798b3 100644 --- a/src/engine/SCons/Options/__init__.py +++ b/src/engine/SCons/Options/__init__.py @@ -76,6 +76,11 @@ class Options: self.options.append(option) + def keys(self): + """ + Returns the keywords for the options + """ + return map(lambda o: o.key, self.options) def Add(self, key, help="", default=None, validator=None, converter=None, **kw): """ @@ -100,7 +105,6 @@ class Options: self._do_add(key, help, default, validator, converter) - def AddOptions(self, *optlist): """ Add a list of options. diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index 675167e..1d4e9f7 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -70,7 +70,7 @@ def exec_spawnvpe(l, env): # returned by os.waitpid() or os.system(). return stat -def exec_fork(l, env): +def exec_fork(l, env): pid = os.fork() if not pid: # Child process. @@ -78,7 +78,7 @@ def exec_fork(l, env): try: os.execvpe(l[0], l, env) except OSError, e: - exitval = exitvalmap[e[0]] + exitval = exitvalmap.get(e[0], e[0]) sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) os._exit(exitval) else: @@ -159,7 +159,7 @@ def exec_piped_fork(l, env, stdout, stderr): try: os.execvpe(l[0], l, env) except OSError, e: - exitval = exitvalmap[e[0]] + exitval = exitvalmap.get(e[0], e[0]) stderr.write("scons: %s: %s\n" % (l[0], e[1])) os._exit(exitval) else: diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 6188098..148d9df 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -90,7 +90,11 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): ret = os.spawnve(os.P_WAIT, sh, args, env) except OSError, e: # catch any error - ret = exitvalmap[e[0]] + try: + ret = exitvalmap[e[0]] + except KeyError: + result = 127 + sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e[0], cmd, e[1])) if stderr != None: stderr.write("scons: %s: %s\n" % (cmd, e[1])) # copy child output from tempfiles to our streams @@ -114,8 +118,19 @@ def exec_spawn(l, env): try: result = os.spawnve(os.P_WAIT, l[0], l, env) except OSError, e: - result = exitvalmap[e[0]] - sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) + try: + result = exitvalmap[e[0]] + sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) + except KeyError: + result = 127 + if len(l) > 2: + if len(l[2]) < 1000: + command = string.join(l[0:3]) + else: + command = l[0] + else: + command = l[0] + sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e[0], command, e[1])) return result def spawn(sh, escape, cmd, args, env): @@ -124,9 +139,15 @@ def spawn(sh, escape, cmd, args, env): return 127 return exec_spawn([sh, '/C', escape(string.join(args))], env) -# Windows does not allow special characters in file names anyway, so -# no need for a complex escape function, we will just quote the arg. -escape = lambda x: '"' + x + '"' +# Windows does not allow special characters in file names anyway, so no +# need for a complex escape function, we will just quote the arg, except +# that "cmd /c" requires that if an argument ends with a backslash it +# needs to be escaped so as not to interfere with closing double quote +# that we add. +def escape(x): + if x[-1] == '\\': + x = x + '\\' + return '"' + x + '"' # Get the windows system directory name def get_system_root(): diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py index c57e7f7..2ca522b 100644 --- a/src/engine/SCons/Scanner/CTests.py +++ b/src/engine/SCons/Scanner/CTests.py @@ -221,6 +221,7 @@ def deps_match(self, deps, headers): class CScannerTestCase1(unittest.TestCase): def runTest(self): + """Find local files with no CPPPATH""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -230,6 +231,7 @@ class CScannerTestCase1(unittest.TestCase): class CScannerTestCase2(unittest.TestCase): def runTest(self): + """Find a file in a CPPPATH directory""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -239,6 +241,7 @@ class CScannerTestCase2(unittest.TestCase): class CScannerTestCase3(unittest.TestCase): def runTest(self): + """Find files in explicit subdirectories, ignore missing file""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -248,6 +251,7 @@ class CScannerTestCase3(unittest.TestCase): class CScannerTestCase4(unittest.TestCase): def runTest(self): + """Find files in explicit subdirectories""" env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -257,6 +261,7 @@ class CScannerTestCase4(unittest.TestCase): class CScannerTestCase5(unittest.TestCase): def runTest(self): + """Make sure files in repositories will get scanned""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -280,6 +285,7 @@ class CScannerTestCase5(unittest.TestCase): class CScannerTestCase6(unittest.TestCase): def runTest(self): + """Find a same-named file in different directories when CPPPATH changes""" env1 = DummyEnvironment(CPPPATH=[test.workpath("d1")]) env2 = DummyEnvironment(CPPPATH=[test.workpath("d1/d2")]) s = SCons.Scanner.C.CScanner() @@ -294,6 +300,7 @@ class CScannerTestCase6(unittest.TestCase): class CScannerTestCase8(unittest.TestCase): def runTest(self): + """Find files in a subdirectory relative to the current directory""" env = DummyEnvironment(CPPPATH=["include"]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -310,6 +317,7 @@ class CScannerTestCase8(unittest.TestCase): class CScannerTestCase9(unittest.TestCase): def runTest(self): + """Generate a warning when we can't find a #included file""" SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: def __call__(self, x): @@ -334,6 +342,7 @@ class CScannerTestCase9(unittest.TestCase): class CScannerTestCase10(unittest.TestCase): def runTest(self): + """Find files in the local directory when the scanned file is elsewhere""" fs = SCons.Node.FS.FS(test.workpath('')) fs.chdir(fs.Dir('include')) env = DummyEnvironment(CPPPATH=[]) @@ -348,6 +357,7 @@ class CScannerTestCase10(unittest.TestCase): class CScannerTestCase11(unittest.TestCase): def runTest(self): + """Handle dependencies on a derived .h file in a non-existent directory""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.Repository(test.workpath('repository')) @@ -367,6 +377,7 @@ class CScannerTestCase11(unittest.TestCase): class CScannerTestCase12(unittest.TestCase): def runTest(self): + """Find files in BuildDir() directories""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.BuildDir('build1', 'src', 1) @@ -388,6 +399,7 @@ class CScannerTestCase12(unittest.TestCase): class CScannerTestCase13(unittest.TestCase): def runTest(self): + """Find files in directories named in a substituted environment variable""" class SubstEnvironment(DummyEnvironment): def subst(self, arg, test=test): return test.workpath("d1") @@ -400,6 +412,7 @@ class CScannerTestCase13(unittest.TestCase): class CScannerTestCase14(unittest.TestCase): def runTest(self): + """Find files when there's no space between "#include" and the name""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -409,6 +422,7 @@ class CScannerTestCase14(unittest.TestCase): class CScannerTestCase15(unittest.TestCase): def runTest(self): + """Verify scanner initialization with the suffixes in $CPPSUFFIXES""" suffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", ".F", ".fpp", ".FPP", diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 73f96e2..2c18112 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -588,29 +588,29 @@ def _create_path(plist): path = path + '/' + d return path +def version_string(label, module): + fmt = "\t%s: v%s.%s, %s, by %s on %s\n" + return fmt % (label, + module.__version__, + module.__build__, + module.__date__, + module.__developer__, + module.__buildsys__) class OptParser(OptionParser): def __init__(self): import __main__ - import SCons + parts = ["SCons by Steven Knight et al.:\n"] try: - parts.append("\tscript: v%s.%s, %s, by %s on %s\n" % (__main__.__version__, - __main__.__build__, - __main__.__date__, - __main__.__developer__, - __main__.__buildsys__)) + parts.append(version_string("script", __main__)) except KeyboardInterrupt: raise except: # On Windows there is no scons.py, so there is no # __main__.__version__, hence there is no script version. pass - parts.append("\tengine: v%s.%s, %s, by %s on %s\n" % (SCons.__version__, - SCons.__build__, - SCons.__date__, - SCons.__developer__, - SCons.__buildsys__)) + parts.append(version_string("engine", SCons)) parts.append("__COPYRIGHT__") OptionParser.__init__(self, version=string.join(parts, ''), usage="usage: scons [OPTION] [TARGET] ...") @@ -630,6 +630,10 @@ class OptParser(OptionParser): metavar="DIR", help="Change to DIR before doing anything.") + self.add_option('--cache-debug', action="store", + dest="cache_debug", metavar="FILE", + help="Print CacheDir debug info to FILE.") + self.add_option('--cache-disable', '--no-cache', action="store_true", dest='cache_disable', default=0, help="Do not retrieve built targets from CacheDir.") @@ -1048,6 +1052,9 @@ def _main(args, parser): display.set_mode(0) if options.silent: SCons.Action.print_actions = None + + if options.cache_debug: + fs.CacheDebugEnable(options.cache_debug) if options.cache_disable: def disable(self): pass fs.CacheDir = disable @@ -1291,8 +1298,21 @@ def _exec_main(): import pdb pdb.Pdb().runcall(_main, args, parser) elif options.profile_file: - import profile - prof = profile.Profile() + from profile import Profile + + # Some versions of Python 2.4 shipped a profiler that had the + # wrong 'c_exception' entry in its dispatch table. Make sure + # we have the right one. (This may put an unnecessary entry + # in the table in earlier versions of Python, but its presence + # shouldn't hurt anything). + try: + dispatch = Profile.dispatch + except AttributeError: + pass + else: + dispatch['c_exception'] = Profile.trace_dispatch_return + + prof = Profile() try: prof.runcall(_main, args, parser) except SystemExit: diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index f932d30..dc896a0 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -176,7 +176,7 @@ def _SConscript(fs, *files, **kw): # fs match so we can open the SConscript. fs.chdir(top, change_os_dir=1) if f.rexists(): - _file_ = open(f.rstr(), "r") + _file_ = open(f.rfile().get_abspath(), "r") elif f.has_src_builder(): # The SConscript file apparently exists in a source # code management system. Build it, but then clear @@ -185,7 +185,7 @@ def _SConscript(fs, *files, **kw): f.build() f.builder_set(None) if f.exists(): - _file_ = open(str(f), "r") + _file_ = open(f.get_abspath(), "r") if _file_: # Chdir to the SConscript directory. Use a path # name relative to the SConstruct file so that if @@ -197,7 +197,18 @@ def _SConscript(fs, *files, **kw): # where the SConstruct and SConscript files might be # in different Repositories. For now, cross that # bridge when someone comes to it. - ldir = fs.Dir(f.dir.get_path(sd)) + try: + src_dir = kw['src_dir'] + except KeyError: + ldir = fs.Dir(f.dir.get_path(sd)) + else: + ldir = fs.Dir(src_dir) + if not ldir.is_under(f.dir): + # They specified a source directory, but + # it's above the SConscript directory. + # Do the sensible thing and just use the + # SConcript directory. + ldir = fs.Dir(f.dir.get_path(sd)) try: fs.chdir(ldir, change_os_dir=sconscript_chdir) except OSError: @@ -208,6 +219,7 @@ def _SConscript(fs, *files, **kw): # interpret the stuff within the SConscript file # relative to where we are logically. fs.chdir(ldir, change_os_dir=0) + # TODO Not sure how to handle src_dir here os.chdir(f.rfile().dir.get_abspath()) # Append the SConscript directory to the beginning @@ -223,7 +235,16 @@ def _SConscript(fs, *files, **kw): # SConscript can base the printed frames at this # level and not show SCons internals as well. call_stack[-1].globals.update({stack_bottom:1}) - exec _file_ in call_stack[-1].globals + old_file = call_stack[-1].globals.get('__file__') + try: + del call_stack[-1].globals['__file__'] + except KeyError: + pass + try: + exec _file_ in call_stack[-1].globals + finally: + if old_file is not None: + call_stack[-1].globals.update({__file__:old_file}) else: SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, "Ignoring missing SConscript '%s'" % f.path) @@ -374,6 +395,7 @@ class SConsEnvironment(SCons.Environment.Base): src_dir = kw.get('src_dir') if not src_dir: src_dir, fname = os.path.split(str(files[0])) + files = [os.path.join(str(build_dir), fname)] else: if not isinstance(src_dir, SCons.Node.Node): src_dir = self.fs.Dir(src_dir) @@ -383,11 +405,11 @@ class SConsEnvironment(SCons.Environment.Base): if fn.is_under(src_dir): # Get path relative to the source directory. fname = fn.get_path(src_dir) + files = [os.path.join(str(build_dir), fname)] else: - # Fast way to only get the terminal path component of a Node. - fname = fn.get_path(fn.dir) + files = [fn.abspath] + kw['src_dir'] = build_dir self.fs.BuildDir(build_dir, src_dir, duplicate) - files = [os.path.join(str(build_dir), fname)] return (files, exports) @@ -490,8 +512,8 @@ class SConsEnvironment(SCons.Environment.Base): subst_kw[key] = val files, exports = self._get_SConscript_filenames(ls, subst_kw) - - return apply(_SConscript, [self.fs,] + files, {'exports' : exports}) + subst_kw['exports'] = exports + return apply(_SConscript, [self.fs,] + files, subst_kw) def SConscriptChdir(self, flag): global sconscript_chdir diff --git a/src/engine/SCons/Tool/as.py b/src/engine/SCons/Tool/as.py index 5a267a5..1b1b4b3 100644 --- a/src/engine/SCons/Tool/as.py +++ b/src/engine/SCons/Tool/as.py @@ -52,11 +52,15 @@ def generate(env): for suffix in ASSuffixes: static_obj.add_action(suffix, SCons.Defaults.ASAction) + shared_obj.add_action(suffix, SCons.Defaults.ASAction) static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) for suffix in ASPPSuffixes: static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + shared_obj.add_action(suffix, SCons.Defaults.ASPPAction) static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) env['AS'] = env.Detect(assemblers) or 'as' env['ASFLAGS'] = SCons.Util.CLVar('') diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py index b694a58..b83e7d3 100644 --- a/src/engine/SCons/Tool/fortran.py +++ b/src/engine/SCons/Tool/fortran.py @@ -146,7 +146,7 @@ def add_to_env(env): env['FORTRANMODDIR'] = '' # where the compiler should place .mod files env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX - env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__)} $)' + env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)' env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes) diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py index 1be665a..ad02e0d 100644 --- a/src/engine/SCons/Tool/gcc.py +++ b/src/engine/SCons/Tool/gcc.py @@ -46,7 +46,7 @@ def generate(env): cc.generate(env) env['CC'] = env.Detect(compilers) or 'gcc' - if env['PLATFORM'] == 'cygwin': + if env['PLATFORM'] in ['cygwin', 'win32']: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') else: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py index 5765e25..d679b53 100644 --- a/src/engine/SCons/Tool/mingw.py +++ b/src/engine/SCons/Tool/mingw.py @@ -118,7 +118,7 @@ def generate(env): # Most of mingw is the same as gcc and friends... - gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas'] + gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas', 'm4'] for tool in gnu_tools: SCons.Tool.Tool(tool)(env) @@ -130,7 +130,6 @@ def generate(env): env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') env['SHLINKCOM'] = shlib_action env.Append(SHLIBEMITTER = [shlib_emitter]) - env['LINK'] = 'g++' env['AS'] = 'as' env['WIN32DEFPREFIX'] = '' diff --git a/src/engine/SCons/Tool/mslink.xml b/src/engine/SCons/Tool/mslink.xml index 58cfb1d..6499cfe 100644 --- a/src/engine/SCons/Tool/mslink.xml +++ b/src/engine/SCons/Tool/mslink.xml @@ -37,6 +37,20 @@ Example: <example> env['PDB'] = 'hello.pdb' </example> + +The Visual C++ compiler switch that SCons uses by default +to generate PDB information is <option>/Z7</option>. +This works correctly with parallel (<option>-j</option>) builds +because it embeds the debug information in the intermediate object files, +as opposed to sharing a single PDB file between multiple object files. +This is also the only way to get debug information +embedded into a static library. +Using the <option>/Zi</option> instead may yield improved +link-time performance, +although parallel builds will no longer work. +You can generate PDB files with the <option>/Zi</option> +switch by overriding the default &cv-CCPDBFLAGS; variable; +see the entry for that variable for specific examples. </summary> </cvar> diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index 86cde78..80b5926 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -517,9 +517,10 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs): include_paths.append( env_include_path ) if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'): - include_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'include' ) ) - lib_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'lib' ) ) - exe_paths.append( paths['FRAMEWORKSDKDIR'], 'bin' ) + fwdir = paths['FRAMEWORKSDKDIR'] + include_paths.append( os.path.join( fwdir, 'include' ) ) + lib_paths.append( os.path.join( fwdir, 'lib' ) ) + exe_paths.append( os.path.join( fwdir, 'bin' ) ) if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'): exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) ) @@ -658,7 +659,10 @@ pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', emitter=pch_emitter, source_scanner=SCons.Tool.SourceFileScanner) res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') -res_builder = SCons.Builder.Builder(action=res_action, suffix='.res', +res_builder = SCons.Builder.Builder(action=res_action, + src_suffix='.rc', + suffix='.res', + src_builder=[], source_scanner=SCons.Tool.SourceFileScanner) SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index 252d962..1c0f3fa 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -47,6 +47,53 @@ env.RES('resource.rc') </summary> </builder> +<cvar name="CCPCHFLAGS"> +<summary> +Options added to the compiler command line +to support building with precompiled headers. +The default value expands expands to the appropriate +Microsoft Visual C++ command-line options +when the &cv-PCH; construction variable is set. +</summary> + +<cvar name="CCPDBFLAGS"> +<summary> +Options added to the compiler command line +to support storing debugging information in a +Microsoft Visual C++ PDB file. +The default value expands expands to appropriate +Microsoft Visual C++ command-line options +when the &cv-PDB; construction variable is set. + +The Visual C++ compiler option that SCons uses by default +to generate PDB information is <option>/Z7</option>. +This works correctly with parallel (<option>-j</option>) builds +because it embeds the debug information in the intermediate object files, +as opposed to sharing a single PDB file between multiple object files. +This is also the only way to get debug information +embedded into a static library. +Using the <option>/Zi</option> instead may yield improved +link-time performance, +although parallel builds will no longer work. + +You can generate PDB files with the <option>/Zi</option> +switch by overriding the default &cv-CCPDBFLAGS; variable as follows: + +<example> +import SCons.Util +env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}']) +</example> + +An alternative would be to use the <option>/Zi</option> +to put the debugging information in a separate <filename>.pdb</filename> +file for each object file by overriding +the &cv-CCPDBFLAGS; variable as follows: + +<example> +env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' +</example> +</summary> + <cvar name="PCH"> <summary> The Microsoft Visual C++ precompiled header that will be used when compiling diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index e8aaf83..e35c92a 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -297,7 +297,7 @@ class _DSPGenerator: for n in sourcenames: self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower())) - def AddConfig(variant, buildtarget, outdir, runfile, cmdargs): + def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile): config = Config() config.buildtarget = buildtarget config.outdir = outdir @@ -316,7 +316,7 @@ class _DSPGenerator: print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'" for i in range(len(variants)): - AddConfig(variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) + AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) self.platforms = [] for key in self.configs.keys(): @@ -690,6 +690,29 @@ class _GenerateV7DSP(_DSPGenerator): pdata = base64.encodestring(pdata) self.file.write(pdata + '-->\n') + def printSources(self, hierarchy, commonprefix): + sorteditems = hierarchy.items() + sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower())) + + # First folders, then files + for key, value in sorteditems: + if SCons.Util.is_Dict(value): + self.file.write('\t\t\t<Filter\n' + '\t\t\t\tName="%s"\n' + '\t\t\t\tFilter="">\n' % (key)) + self.printSources(value, commonprefix) + self.file.write('\t\t\t</Filter>\n') + + for key, value in sorteditems: + if SCons.Util.is_String(value): + file = value + if commonprefix: + file = os.path.join(commonprefix, value) + file = os.path.normpath(file) + self.file.write('\t\t\t<File\n' + '\t\t\t\tRelativePath="%s">\n' + '\t\t\t</File>\n' % (file)) + def PrintSourceFiles(self): categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', 'Header Files': 'h;hpp;hxx;hm;inl', @@ -708,43 +731,26 @@ class _GenerateV7DSP(_DSPGenerator): '\t\t\tName="%s"\n' '\t\t\tFilter="%s">\n' % (kind, categories[kind])) - - def printSources(hierarchy, commonprefix): - sorteditems = hierarchy.items() - sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower())) - - # First folders, then files - for key, value in sorteditems: - if SCons.Util.is_Dict(value): - self.file.write('\t\t\t<Filter\n' - '\t\t\t\tName="%s"\n' - '\t\t\t\tFilter="">\n' % (key)) - printSources(value, commonprefix) - self.file.write('\t\t\t</Filter>\n') - - for key, value in sorteditems: - if SCons.Util.is_String(value): - file = value - if commonprefix: - file = os.path.join(commonprefix, value) - file = os.path.normpath(file) - self.file.write('\t\t\t<File\n' - '\t\t\t\tRelativePath="%s">\n' - '\t\t\t</File>\n' % (file)) - sources = self.sources[kind] # First remove any common prefix commonprefix = None if len(sources) > 1: s = map(os.path.normpath, sources) - cp = os.path.commonprefix(s) + # take the dirname because the prefix may include parts + # of the filenames (e.g. if you have 'dir\abcd' and + # 'dir\acde' then the cp will be 'dir\a' ) + cp = os.path.dirname( os.path.commonprefix(s) ) if cp and s[0][len(cp)] == os.sep: - sources = map(lambda s, l=len(cp): s[l:], sources) + # +1 because the filename starts after the separator + sources = map(lambda s, l=len(cp)+1: s[l:], sources) commonprefix = cp + elif len(sources) == 1: + commonprefix = os.path.dirname( sources[0] ) + sources[0] = os.path.basename( sources[0] ) hierarchy = makeHierarchy(sources) - printSources(hierarchy, commonprefix=commonprefix) + self.printSources(hierarchy, commonprefix=commonprefix) if len(cats)>1: self.file.write('\t\t</Filter>\n') @@ -873,7 +879,7 @@ class _GenerateV7DSW(_DSWGenerator): if self.nokeep == 0 and os.path.exists(self.dswfile): self.Parse() - def AddConfig(variant): + def AddConfig(self, variant, dswfile=dswfile): config = Config() match = re.match('(.*)\|(.*)', variant) @@ -892,10 +898,10 @@ class _GenerateV7DSW(_DSWGenerator): "You must specify a 'variant' argument (i.e. 'Debug' or " +\ "'Release') to create an MSVS Solution File." elif SCons.Util.is_String(env['variant']): - AddConfig(env['variant']) + AddConfig(self, env['variant']) elif SCons.Util.is_List(env['variant']): for variant in env['variant']: - AddConfig(variant) + AddConfig(self, variant) self.platforms = [] for key in self.configs.keys(): @@ -1127,32 +1133,24 @@ def GenerateDSW(dswfile, source, env): def get_default_visualstudio_version(env): """Returns the version set in the env, or the latest version installed, if it can find it, or '6.0' if all else fails. Also - updated the environment with what it found.""" + updates the environment with what it found.""" - version = '6.0' - versions = [version] + versions = ['6.0'] if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']): - env['MSVS'] = {} - - if env['MSVS'].has_key('VERSIONS'): - versions = env['MSVS']['VERSIONS'] - elif SCons.Util.can_read_reg: - v = get_visualstudio_versions() - if v: - versions = v - if env.has_key('MSVS_VERSION'): - version = env['MSVS_VERSION'] - else: - version = versions[0] #use highest version by default - - env['MSVS_VERSION'] = version - env['MSVS']['VERSIONS'] = versions - env['MSVS']['VERSION'] = version + v = get_visualstudio_versions() + if v: + versions = v + env['MSVS'] = {'VERSIONS' : versions} else: - version = env['MSVS']['VERSION'] + versions = env['MSVS'].get('VERSIONS', versions) + + if not env.has_key('MSVS_VERSION'): + env['MSVS_VERSION'] = versions[0] #use highest version by default + + env['MSVS']['VERSION'] = env['MSVS_VERSION'] - return version + return env['MSVS_VERSION'] def get_visualstudio_versions(): """ diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 6095dff..b1125e7 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -471,6 +471,18 @@ class msvsTestCase(unittest.TestCase): assert env['MSVS']['VERSION'] == '7.0', env['MSVS']['VERSION'] assert v2 == '7.0', v2 + env = DummyEnv() + v3 = get_default_visualstudio_version(env) + if v3 == '7.1': + override = '7.0' + else: + override = '7.1' + env['MSVS_VERSION'] = override + v3 = get_default_visualstudio_version(env) + assert env['MSVS_VERSION'] == override, env['MSVS_VERSION'] + assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION'] + assert v3 == override, v3 + def test_get_visual_studio_versions(self): """Test retrieval of the list of visual studio versions""" v1 = get_visualstudio_versions() diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py new file mode 100644 index 0000000..9bf5779 --- /dev/null +++ b/src/engine/SCons/cpp.py @@ -0,0 +1,561 @@ +# +# __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__" + +__doc__ = """ +SCons C Pre-Processor module +""" + +import os +import re +import string +import sys + + + +import __builtin__ +try: + __builtin__.zip +except AttributeError: + def zip(*lists): + result = [] + for i in xrange(len(lists[0])): + result.append(tuple(map(lambda l, i=i: l[i], lists))) + return result + + + +# +# First "subsystem" of regular expressions that we set up: +# +# Stuff to turn the C preprocessor directives in a file's contents into +# a list of tuples that we can process easily. +# + +# A table of regular expressions that fetch the arguments from the rest of +# a C preprocessor line. Different directives have different arguments +# that we want to fetch, using the regular expressions to which the lists +# of preprocessor directives map. +cpp_lines_dict = { + # Fetch the rest of a #if/#elif/#ifdef/#ifndef/#import/#include/ + # #include_next line as one argument. + ('if', 'elif', 'ifdef', 'ifndef', 'import', 'include', 'include_next',) + : '\s+(.+)', + + # We don't care what comes after a #else or #endif line. + ('else', 'endif',) : '', + + # Fetch three arguments from a #define line: + # 1) The #defined keyword. + # 2) The optional parentheses and arguments (if it's a function-like + # macro, '' if it's not). + # 3) The expansion value. + ('define',) : '\s+([_A-Za-z][_A-Za-z0-9_]+)(\([^)]*\))?\s*(.*)', + + # Fetch the #undefed keyword from a #undef line. + ('undef',) : '\s+([_A-Za-z][A-Za-z0-9_]+)', +} + +# Create a table that maps each individual C preprocessor directive to +# the corresponding compiled regular expression that fetches the arguments +# we care about. +Table = {} +for op_list, expr in cpp_lines_dict.items(): + e = re.compile(expr) + for op in op_list: + Table[op] = e +del e +del op +del op_list + +# Create a list of the expressions we'll use to match all of the +# preprocessor directives. These are the same as the directives +# themselves *except* that we must use a negative lookahead assertion +# when matching "if" so it doesn't match the "if" in "ifdef." +override = { + 'if' : 'if(?!def)', +} +l = map(lambda x, o=override: o.get(x, x), Table.keys()) + + +# Turn the list of expressions into one big honkin' regular expression +# that will match all the preprocessor lines at once. This will return +# a list of tuples, one for each preprocessor line. The preprocessor +# directive will be the first element in each tuple, and the rest of +# the line will be the second element. +e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$' + +# And last but not least, compile the expression. +CPP_Expression = re.compile(e, re.M) + + + + +# +# Second "subsystem" of regular expressions that we set up: +# +# Stuff to translate a C preprocessor expression (as found on a #if or +# #elif line) into an equivalent Python expression that we can eval(). +# + +# A dictionary that maps the C representation of Boolean operators +# to their Python equivalents. +CPP_to_Python_Ops_Dict = { + '!' : ' not ', + '!=' : ' != ', + '&&' : ' and ', + '||' : ' or ', + '?' : ' and ', + ':' : ' or ', + '\r' : '', +} + +CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)] + +# We have to sort the keys by length so that longer expressions +# come *before* shorter expressions--in particular, "!=" must +# come before "!" in the alternation. Without this, the Python +# re module, as late as version 2.2.2, empirically matches the +# "!" in "!=" first, instead of finding the longest match. +# What's up with that? +l = CPP_to_Python_Ops_Dict.keys() +l.sort(lambda a, b: cmp(len(b), len(a))) + +# Turn the list of keys into one regular expression that will allow us +# to substitute all of the operators at once. +expr = string.join(map(re.escape, l), '|') + +# ...and compile the expression. +CPP_to_Python_Ops_Expression = re.compile(expr) + +# A separate list of expressions to be evaluated and substituted +# sequentially, not all at once. +CPP_to_Python_Eval_List = [ + ['defined\s+(\w+)', '__dict__.has_key("\\1")'], + ['defined\s*\((\w+)\)', '__dict__.has_key("\\1")'], + ['/\*.*\*/', ''], + ['/\*.*', ''], + ['//.*', ''], + ['(0x[0-9A-Fa-f]*)[UL]+', '\\1L'], +] + +# Replace the string representations of the regular expressions in the +# list with compiled versions. +for l in CPP_to_Python_Eval_List: + l[0] = re.compile(l[0]) + +# Wrap up all of the above into a handy function. +def CPP_to_Python(s): + """ + Converts a C pre-processor expression into an equivalent + Python expression that can be evaluated. + """ + s = CPP_to_Python_Ops_Expression.sub(CPP_to_Python_Ops_Sub, s) + for expr, repl in CPP_to_Python_Eval_List: + s = expr.sub(repl, s) + return s + + + +del expr +del l +del override + + + +class FunctionEvaluator: + """ + Handles delayed evaluation of a #define function call. + """ + def __init__(self, name, args, expansion): + """ + Squirrels away the arguments and expansion value of a #define + macro function for later evaluation when we must actually expand + a value that uses it. + """ + self.name = name + self.args = function_arg_separator.split(args) + self.expansion = string.split(expansion, '##') + def __call__(self, *values): + """ + Evaluates the expansion of a #define macro function called + with the specified values. + """ + if len(self.args) != len(values): + raise ValueError, "Incorrect number of arguments to `%s'" % self.name + # Create a dictionary that maps the macro arguments to the + # corresponding values in this "call." We'll use this when we + # eval() the expansion so that arguments will get expanded to + # the right values. + locals = {} + for k, v in zip(self.args, values): + locals[k] = v + + parts = [] + for s in self.expansion: + if not s in self.args: + s = repr(s) + parts.append(s) + statement = string.join(parts, ' + ') + + return eval(statement, globals(), locals) + + + +# Find line continuations. +line_continuations = re.compile('\\\\\r?\n') + +# Search for a "function call" macro on an expansion. Returns the +# two-tuple of the "function" name itself, and a string containing the +# arguments within the call parentheses. +function_name = re.compile('(\S+)\(([^)]*)\)') + +# Split a string containing comma-separated function call arguments into +# the separate arguments. +function_arg_separator = re.compile(',\s*') + + + +class PreProcessor: + """ + The main workhorse class for handling C pre-processing. + """ + def __init__(self, current='.', cpppath=[], dict={}, all=0): + global Table + + self.searchpath = { + '"' : [current] + cpppath, + '<' : cpppath + [current], + } + + # Initialize our C preprocessor namespace for tracking the + # values of #defined keywords. We use this namespace to look + # for keywords on #ifdef/#ifndef lines, and to eval() the + # expressions on #if/#elif lines (after massaging them from C to + # Python). + self.cpp_namespace = dict.copy() + self.cpp_namespace['__dict__'] = self.cpp_namespace + + if all: + self.do_include = self.all_include + + # For efficiency, a dispatch table maps each C preprocessor + # directive (#if, #define, etc.) to the method that should be + # called when we see it. We accomodate state changes (#if, + # #ifdef, #ifndef) by pushing the current dispatch table on a + # stack and changing what method gets called for each relevant + # directive we might see next at this level (#else, #elif). + # #endif will simply pop the stack. + d = {} + for op in Table.keys(): + d[op] = getattr(self, 'do_' + op) + self.default_table = d + + # Controlling methods. + + def tupleize(self, contents): + """ + Turns the contents of a file into a list of easily-processed + tuples describing the CPP lines in the file. + + The first element of each tuple is the line's preprocessor + directive (#if, #include, #define, etc., minus the initial '#'). + The remaining elements are specific to the type of directive, as + pulled apart by the regular expression. + """ + global CPP_Expression, Table + contents = line_continuations.sub('', contents) + cpp_tuples = CPP_Expression.findall(contents) + return map(lambda m, t=Table: + (m[0],) + t[m[0]].match(m[1]).groups(), + cpp_tuples) + + def __call__(self, contents): + """ + Pre-processes a file contents. + + This is the main entry point, which + """ + self.stack = [] + self.dispatch_table = self.default_table.copy() + self.tuples = self.tupleize(contents) + + self.result = [] + while self.tuples: + t = self.tuples.pop(0) + # Uncomment to see the list of tuples being processed (e.g., + # to validate the CPP lines are being translated correctly). + #print t + self.dispatch_table[t[0]](t) + + return self.result + + # Dispatch table stack manipulation methods. + + def save(self): + """ + Pushes the current dispatch table on the stack and re-initializes + the current dispatch table to the default. + """ + self.stack.append(self.dispatch_table) + self.dispatch_table = self.default_table.copy() + + def restore(self): + """ + Pops the previous dispatch table off the stack and makes it the + current one. + """ + try: self.dispatch_table = self.stack.pop() + except IndexError: pass + + # Utility methods. + + def do_nothing(self, t): + """ + Null method for when we explicitly want the action for a + specific preprocessor directive to do nothing. + """ + pass + + def eval_expression(self, t): + """ + Evaluates a C preprocessor expression. + + This is done by converting it to a Python equivalent and + eval()ing it in the C preprocessor namespace we use to + track #define values. + """ + t = CPP_to_Python(string.join(t[1:])) + try: return eval(t, self.cpp_namespace) + except (NameError, TypeError): return 0 + + def find_include_file(self, t): + """ + Finds the #include file for a given preprocessor tuple. + """ + fname = t[2] + for d in self.searchpath[t[1]]: + f = os.path.join(d, fname) + if os.path.isfile(f): + return f + return None + + # Start and stop processing include lines. + + def start_handling_includes(self, t=None): + """ + Causes the PreProcessor object to start processing #import, + #include and #include_next lines. + + This method will be called when a #if, #ifdef, #ifndef or #elif + evaluates True, or when we reach the #else in a #if, #ifdef, + #ifndef or #elif block where a condition already evaluated + False. + + """ + d = self.dispatch_table + d['import'] = self.do_import + d['include'] = self.do_include + d['include_next'] = self.do_include + + def stop_handling_includes(self, t=None): + """ + Causes the PreProcessor object to stop processing #import, + #include and #include_next lines. + + This method will be called when a #if, #ifdef, #ifndef or #elif + evaluates False, or when we reach the #else in a #if, #ifdef, + #ifndef or #elif block where a condition already evaluated True. + """ + d = self.dispatch_table + d['import'] = self.do_nothing + d['include'] = self.do_nothing + d['include_next'] = self.do_nothing + + # Default methods for handling all of the preprocessor directives. + # (Note that what actually gets called for a given directive at any + # point in time is really controlled by the dispatch_table.) + + def _do_if_else_condition(self, condition): + """ + Common logic for evaluating the conditions on #if, #ifdef and + #ifndef lines. + """ + self.save() + d = self.dispatch_table + if condition: + self.start_handling_includes() + d['elif'] = self.stop_handling_includes + d['else'] = self.stop_handling_includes + else: + self.stop_handling_includes() + d['elif'] = self.do_elif + d['else'] = self.start_handling_includes + + def do_ifdef(self, t): + """ + Default handling of a #ifdef line. + """ + self._do_if_else_condition(self.cpp_namespace.has_key(t[1])) + + def do_ifndef(self, t): + """ + Default handling of a #ifndef line. + """ + self._do_if_else_condition(not self.cpp_namespace.has_key(t[1])) + + def do_if(self, t): + """ + Default handling of a #if line. + """ + self._do_if_else_condition(self.eval_expression(t)) + + def do_elif(self, t): + """ + Default handling of a #elif line. + """ + d = self.dispatch_table + if self.eval_expression(t): + self.start_handling_includes() + d['elif'] = self.stop_handling_includes + d['else'] = self.stop_handling_includes + + def do_else(self, t): + """ + Default handling of a #else line. + """ + pass + + def do_endif(self, t): + """ + Default handling of a #endif line. + """ + self.restore() + + def do_define(self, t): + """ + Default handling of a #define line. + """ + _, name, args, expansion = t + try: + expansion = int(expansion) + except (TypeError, ValueError): + pass + if args: + evaluator = FunctionEvaluator(name, args[1:-1], expansion) + self.cpp_namespace[name] = evaluator + else: + self.cpp_namespace[name] = expansion + + def do_undef(self, t): + """ + Default handling of a #undef line. + """ + try: del self.cpp_namespace[t[1]] + except KeyError: pass + + def do_import(self, t): + """ + Default handling of a #import line. + """ + # XXX finish this -- maybe borrow/share logic from do_include()...? + pass + + def do_include(self, t): + """ + Default handling of a #include line. + """ + t = self.resolve_include(t) + include_file = self.find_include_file(t) + if include_file: + #print "include_file =", include_file + self.result.append(include_file) + contents = open(include_file).read() + new_tuples = self.tupleize(contents) + self.tuples[:] = new_tuples + self.tuples + + # Date: Tue, 22 Nov 2005 20:26:09 -0500 + # From: Stefan Seefeld <seefeld@sympatico.ca> + # + # By the way, #include_next is not the same as #include. The difference + # being that #include_next starts its search in the path following the + # path that let to the including file. In other words, if your system + # include paths are ['/foo', '/bar'], and you are looking at a header + # '/foo/baz.h', it might issue an '#include_next <baz.h>' which would + # correctly resolve to '/bar/baz.h' (if that exists), but *not* see + # '/foo/baz.h' again. See http://www.delorie.com/gnu/docs/gcc/cpp_11.html + # for more reasoning. + # + # I have no idea in what context 'import' might be used. + + # XXX is #include_next really the same as #include ? + do_include_next = do_include + + # Utility methods for handling resolution of include files. + + def resolve_include(self, t): + """Resolve a tuple-ized #include line. + + This handles recursive expansion of values without "" or <> + surrounding the name until an initial " or < is found, to handle + #include FILE + where FILE is a #define somewhere else. + """ + s = t[1] + while not s[0] in '<"': + #print "s =", s + try: + s = self.cpp_namespace[s] + except KeyError: + m = function_name.search(s) + s = self.cpp_namespace[m.group(1)] + if callable(s): + args = function_arg_separator.split(m.group(2)) + s = apply(s, args) + if not s: + return None + return (t[0], s[0], s[1:-1]) + + def all_include(self, t): + """ + """ + self.result.append(self.resolve_include(t)) + +class DumbPreProcessor(PreProcessor): + """A preprocessor that ignores all #if/#elif/#else/#endif directives + and just reports back *all* of the #include files (like the classic + SCons scanner did). + + This is functionally equivalent to using a regular expression to + find all of the #include lines, only slower. It exists mainly as + an example of how the main PreProcessor class can be sub-classed + to tailor its behavior. + """ + def __init__(self, *args, **kw): + apply(PreProcessor.__init__, (self,)+args, kw) + d = self.default_table + for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']: + d[func] = d[func] = self.do_nothing + +del __revision__ diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py new file mode 100644 index 0000000..0959e2c --- /dev/null +++ b/src/engine/SCons/cppTests.py @@ -0,0 +1,573 @@ +# +# __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 sys +import unittest + +print sys.path +import cpp + + + +basic_input = """ +#include "file1-yes" +#include <file2-yes> +""" + + +substitution_input = """ +#define FILE3 "file3-yes" +#define FILE4 <file4-yes> + +#include FILE3 +#include FILE4 + +#define XXX_FILE5 YYY_FILE5 +#define YYY_FILE5 ZZZ_FILE5 +#define ZZZ_FILE5 FILE5 + +#define FILE5 "file5-yes" +#define FILE6 <file6-yes> + +#define XXX_FILE6 YYY_FILE6 +#define YYY_FILE6 ZZZ_FILE6 +#define ZZZ_FILE6 FILE6 + +#include XXX_FILE5 +#include XXX_FILE6 +""" + + +ifdef_input = """ +#define DEFINED 0 + +#ifdef DEFINED +#include "file7-yes" +#else +#include "file7-no" +#endif + +#ifdef NOT_DEFINED +#include <file8-no> +#else +#include <file8-yes> +#endif +""" + + +if_boolean_input = """ +#define ZERO 0 +#define ONE 1 + +#if ZERO +#include "file9-no" +#else +#include "file9-yes" +#endif + +#if ONE +#include <file10-yes> +#else +#include <file10-no> +#endif + +#if ZERO +#include "file11-no-1" +#elif ZERO +#include "file11-no-2" +#else +#include "file11-yes" +#endif + +#if ZERO +#include <file12-no-1> +#elif ONE +#include <file12-yes> +#else +#include <file12-no-2> +#endif + +#if ONE +#include "file13-yes" +#elif ZERO +#include "file13-no-1" +#else +#include "file13-no-2" +#endif + +#if ONE +#include <file14-yes> +#elif ONE +#include <file14-no-1> +#else +#include <file14-no-2> +#endif +""" + + +if_defined_input = """ +#define DEFINED 0 + +#if defined(DEFINED) +#include "file15-yes" +#endif + +#if ! defined(DEFINED) +#include <file16-no> +#else +#include <file16-yes> +#endif + +#if defined DEFINED +#include "file17-yes" +#endif + +#if ! defined DEFINED +#include <file18-no> +#else +#include <file18-yes> +#endif +""" + + +expression_input = """ +#define ZERO 0 +#define ONE 1 + +#if ZERO && ZERO +#include "file19-no" +#else +#include "file19-yes" +#endif + +#if ZERO && ONE +#include <file20-no> +#else +#include <file20-yes> +#endif + +#if ONE && ZERO +#include "file21-no" +#else +#include "file21-yes" +#endif + +#if ONE && ONE +#include <file22-yes> +#else +#include <file22-no> +#endif + +#if ZERO || ZERO +#include "file23-no" +#else +#include "file23-yes" +#endif + +#if ZERO || ONE +#include <file24-yes> +#else +#include <file24-no> +#endif + +#if ONE || ZERO +#include "file25-yes" +#else +#include "file25-no" +#endif + +#if ONE || ONE +#include <file26-yes> +#else +#include <file26-no> +#endif + +#if ONE == ONE +#include "file27-yes" +#else +#include "file27-no" +#endif + +#if ONE != ONE +#include <file28-no> +#else +#include <file28-yes> +#endif + +#if ! (ONE == ONE) +#include "file29-no" +#else +#include "file29-yes" +#endif + +#if ! (ONE != ONE) +#include <file30-yes> +#else +#include <file30-no> +#endif +""" + + +undef_input = """ +#define UNDEFINE 0 + +#ifdef UNDEFINE +#include "file31-yes" +#else +#include "file31-no" +#endif + +#undef UNDEFINE + +#ifdef UNDEFINE +#include <file32-no> +#else +#include <file32-yes> +#endif +""" + + +macro_function_input = """ +#define ZERO 0 +#define ONE 1 + +#define FUNC33(x) "file33-yes" +#define FUNC34(x) <file34-yes> + +#include FUNC33(ZERO) +#include FUNC34(ZERO) + +#define FILE35 "file35-yes" +#define FILE36 <file36-yes> + +#define FUNC35(x, y) FILE35 +#define FUNC36(x, y) FILE36 + +#include FUNC35(ZERO, ONE) +#include FUNC36(ZERO, ONE) + +#define FILE37 "file37-yes" +#define FILE38 <file38-yes> + +#define FUNC37a(x, y) FILE37 +#define FUNC38a(x, y) FILE38 + +#define FUNC37b(x, y) FUNC37a(x, y) +#define FUNC38b(x, y) FUNC38a(x, y) + +#define FUNC37c(x, y) FUNC37b(x, y) +#define FUNC38c(x, y) FUNC38b(x, y) + +#include FUNC37c(ZERO, ONE) +#include FUNC38c(ZERO, ONE) + +#define FILE39 "file39-yes" +#define FILE40 <file40-yes> + +#define FUNC39a(x0, y0) FILE39 +#define FUNC40a(x0, y0) FILE40 + +#define FUNC39b(x1, y2) FUNC39a(x1, y1) +#define FUNC40b(x1, y2) FUNC40a(x1, y1) + +#define FUNC39c(x2, y2) FUNC39b(x2, y2) +#define FUNC40c(x2, y2) FUNC40b(x2, y2) + +#include FUNC39c(ZERO, ONE) +#include FUNC40c(ZERO, ONE) +""" + + +token_pasting_input = """ +#define PASTE_QUOTE(q, name) q##name##-yes##q +#define PASTE_ANGLE(name) <##name##-yes> + +#define FUNC41 PASTE_QUOTE(", file41) +#define FUNC42 PASTE_ANGLE(file42) + +#include FUNC41 +#include FUNC42 +""" + + + +# pp_class = PreProcessor +# #pp_class = DumbPreProcessor + +# pp = pp_class(current = ".", +# cpppath = ['/usr/include'], +# print_all = 1) +# #pp(open(sys.argv[1]).read()) +# pp(input) + + +class cppTestCase(unittest.TestCase): + def setUp(self): + self.cpp = self.cpp_class(current = ".", + cpppath = ['/usr/include']) + + def test_basic(self): + """Test basic #include scanning""" + expect = self.basic_expect + result = self.cpp(basic_input) + assert expect == result, (expect, result) + + def test_substitution(self): + """Test substitution of #include files using CPP variables""" + expect = self.substitution_expect + result = self.cpp(substitution_input) + assert expect == result, (expect, result) + + def test_ifdef(self): + """Test basic #ifdef processing""" + expect = self.ifdef_expect + result = self.cpp(ifdef_input) + assert expect == result, (expect, result) + + def test_if_boolean(self): + """Test #if with Boolean values""" + expect = self.if_boolean_expect + result = self.cpp(if_boolean_input) + assert expect == result, (expect, result) + + def test_if_defined(self): + """Test #if defined() idioms""" + expect = self.if_defined_expect + result = self.cpp(if_defined_input) + assert expect == result, (expect, result) + + def test_expression(self): + """Test #if with arithmetic expressions""" + expect = self.expression_expect + result = self.cpp(expression_input) + assert expect == result, (expect, result) + + def test_undef(self): + """Test #undef handling""" + expect = self.undef_expect + result = self.cpp(undef_input) + assert expect == result, (expect, result) + + def test_macro_function(self): + """Test using macro functions to express file names""" + expect = self.macro_function_expect + result = self.cpp(macro_function_input) + assert expect == result, (expect, result) + + def test_token_pasting(self): + """Test taken-pasting to construct file names""" + expect = self.token_pasting_expect + result = self.cpp(token_pasting_input) + assert expect == result, (expect, result) + +class cppAllTestCase(cppTestCase): + def setUp(self): + self.cpp = self.cpp_class(current = ".", + cpppath = ['/usr/include'], + all=1) + +class PreProcessorTestCase(cppAllTestCase): + cpp_class = cpp.PreProcessor + + basic_expect = [ + ('include', '"', 'file1-yes'), + ('include', '<', 'file2-yes'), + ] + + substitution_expect = [ + ('include', '"', 'file3-yes'), + ('include', '<', 'file4-yes'), + ('include', '"', 'file5-yes'), + ('include', '<', 'file6-yes'), + ] + + ifdef_expect = [ + ('include', '"', 'file7-yes'), + ('include', '<', 'file8-yes'), + ] + + if_boolean_expect = [ + ('include', '"', 'file9-yes'), + ('include', '<', 'file10-yes'), + ('include', '"', 'file11-yes'), + ('include', '<', 'file12-yes'), + ('include', '"', 'file13-yes'), + ('include', '<', 'file14-yes'), + ] + + if_defined_expect = [ + ('include', '"', 'file15-yes'), + ('include', '<', 'file16-yes'), + ('include', '"', 'file17-yes'), + ('include', '<', 'file18-yes'), + ] + + expression_expect = [ + ('include', '"', 'file19-yes'), + ('include', '<', 'file20-yes'), + ('include', '"', 'file21-yes'), + ('include', '<', 'file22-yes'), + ('include', '"', 'file23-yes'), + ('include', '<', 'file24-yes'), + ('include', '"', 'file25-yes'), + ('include', '<', 'file26-yes'), + ('include', '"', 'file27-yes'), + ('include', '<', 'file28-yes'), + ('include', '"', 'file29-yes'), + ('include', '<', 'file30-yes'), + ] + + undef_expect = [ + ('include', '"', 'file31-yes'), + ('include', '<', 'file32-yes'), + ] + + macro_function_expect = [ + ('include', '"', 'file33-yes'), + ('include', '<', 'file34-yes'), + ('include', '"', 'file35-yes'), + ('include', '<', 'file36-yes'), + ('include', '"', 'file37-yes'), + ('include', '<', 'file38-yes'), + ('include', '"', 'file39-yes'), + ('include', '<', 'file40-yes'), + ] + + token_pasting_expect = [ + ('include', '"', 'file41-yes'), + ('include', '<', 'file42-yes'), + ] + +class DumbPreProcessorTestCase(cppAllTestCase): + cpp_class = cpp.DumbPreProcessor + + basic_expect = [ + ('include', '"', 'file1-yes'), + ('include', '<', 'file2-yes'), + ] + + substitution_expect = [ + ('include', '"', 'file3-yes'), + ('include', '<', 'file4-yes'), + ('include', '"', 'file5-yes'), + ('include', '<', 'file6-yes'), + ] + + ifdef_expect = [ + ('include', '"', 'file7-yes'), + ('include', '"', 'file7-no'), + ('include', '<', 'file8-no'), + ('include', '<', 'file8-yes'), + ] + + if_boolean_expect = [ + ('include', '"', 'file9-no'), + ('include', '"', 'file9-yes'), + ('include', '<', 'file10-yes'), + ('include', '<', 'file10-no'), + ('include', '"', 'file11-no-1'), + ('include', '"', 'file11-no-2'), + ('include', '"', 'file11-yes'), + ('include', '<', 'file12-no-1'), + ('include', '<', 'file12-yes'), + ('include', '<', 'file12-no-2'), + ('include', '"', 'file13-yes'), + ('include', '"', 'file13-no-1'), + ('include', '"', 'file13-no-2'), + ('include', '<', 'file14-yes'), + ('include', '<', 'file14-no-1'), + ('include', '<', 'file14-no-2'), + ] + + if_defined_expect = [ + ('include', '"', 'file15-yes'), + ('include', '<', 'file16-no'), + ('include', '<', 'file16-yes'), + ('include', '"', 'file17-yes'), + ('include', '<', 'file18-no'), + ('include', '<', 'file18-yes'), + ] + + expression_expect = [ + ('include', '"', 'file19-no'), + ('include', '"', 'file19-yes'), + ('include', '<', 'file20-no'), + ('include', '<', 'file20-yes'), + ('include', '"', 'file21-no'), + ('include', '"', 'file21-yes'), + ('include', '<', 'file22-yes'), + ('include', '<', 'file22-no'), + ('include', '"', 'file23-no'), + ('include', '"', 'file23-yes'), + ('include', '<', 'file24-yes'), + ('include', '<', 'file24-no'), + ('include', '"', 'file25-yes'), + ('include', '"', 'file25-no'), + ('include', '<', 'file26-yes'), + ('include', '<', 'file26-no'), + ('include', '"', 'file27-yes'), + ('include', '"', 'file27-no'), + ('include', '<', 'file28-no'), + ('include', '<', 'file28-yes'), + ('include', '"', 'file29-no'), + ('include', '"', 'file29-yes'), + ('include', '<', 'file30-yes'), + ('include', '<', 'file30-no'), + ] + + undef_expect = [ + ('include', '"', 'file31-yes'), + ('include', '"', 'file31-no'), + ('include', '<', 'file32-no'), + ('include', '<', 'file32-yes'), + ] + + macro_function_expect = [ + ('include', '"', 'file33-yes'), + ('include', '<', 'file34-yes'), + ('include', '"', 'file35-yes'), + ('include', '<', 'file36-yes'), + ('include', '"', 'file37-yes'), + ('include', '<', 'file38-yes'), + ('include', '"', 'file39-yes'), + ('include', '<', 'file40-yes'), + ] + + token_pasting_expect = [ + ('include', '"', 'file41-yes'), + ('include', '<', 'file42-yes'), + ] + +if __name__ == '__main__': + suite = unittest.TestSuite() + tclasses = [ PreProcessorTestCase, + DumbPreProcessorTestCase, + ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(map(tclass, names)) + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + diff --git a/src/test_copyrights.py b/src/test_copyrights.py index 195649b..3f7d1c9 100644 --- a/src/test_copyrights.py +++ b/src/test_copyrights.py @@ -46,9 +46,12 @@ try: except KeyError: cwd = os.getcwd() -build_scons = os.path.join(cwd, 'build', 'scons') -build_local = os.path.join(cwd, 'build', 'scons-local', 'scons-local-0.96.92') -build_src = os.path.join(cwd, 'build', 'scons-src') +def build_path(*args): + return apply(os.path.join, (cwd, 'build',)+args) + +build_scons = build_path('scons') +build_local = build_path('scons-local', 'scons-local-'+test.scons_version) +build_src = build_path('scons-src') class Collect: expression = re.compile('Copyright.*The SCons Foundation') diff --git a/src/test_files.py b/src/test_files.py new file mode 100644 index 0000000..1424c62 --- /dev/null +++ b/src/test_files.py @@ -0,0 +1,100 @@ +#!/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 have certain important files in our distribution +packages. + +Note that this is a packaging test, not a functional test, so the +name of this script doesn't end in *Tests.py. +""" + +import os +import os.path +import re +import string + +import TestSCons + +test = TestSCons.TestSCons() + +try: + cwd = os.environ['SCONS_CWD'] +except KeyError: + cwd = os.getcwd() + +def build_path(*args): + return apply(os.path.join, (cwd, 'build',) + args) + +build_scons_tar_gz = build_path('unpack-tar-gz', 'scons-'+test.scons_version) +build_scons_zip = build_path('unpack-zip', 'scons-'+test.scons_version) +build_local_tar_gz = build_path('test-local-tar-gz') +build_local_zip = build_path('test-local-zip') + +scons_files = [ + 'CHANGES.txt', + 'LICENSE.txt', + 'README.txt', + 'RELEASE.txt', +] + +local_files = [ + 'scons-LICENSE', + 'scons-README', +] + +# Map each directory to search (dictionary keys) to a list of its +# subsidiary files and directories to exclude from copyright checks. +check = { + build_scons_tar_gz : scons_files, + build_scons_zip : scons_files, + build_local_tar_gz : local_files, + build_local_zip : local_files, +} + +missing = [] +no_result = [] + +for directory, check_list in check.items(): + if os.path.exists(directory): + for c in check_list: + f = os.path.join(directory, c) + if not os.path.isfile(f): + missing.append(f) + else: + no_result.append(directory) + +if missing: + print "Missing the following files:\n" + print "\t" + string.join(missing, "\n\t") + test.fail_test(1) + +if no_result: + print "Cannot check files, the following have apparently not been built:" + print "\t" + string.join(no_result, "\n\t") + test.no_result(1) + +test.pass_test() diff --git a/src/test_setup.py b/src/test_setup.py index d612897..e2bb48b 100644 --- a/src/test_setup.py +++ b/src/test_setup.py @@ -40,15 +40,11 @@ import sys try: WindowsError except NameError: WindowsError = OSError -#try: -# version = os.environ['SCONS_VERSION'] -#except KeyError: -# version = '__VERSION__' -version = '0.96.92' +import TestSCons -scons_version = 'scons-%s' % version +version = TestSCons.TestSCons.scons_version -import TestSCons +scons_version = 'scons-%s' % version python = TestSCons.python @@ -203,8 +199,9 @@ if not os.path.isdir(scons_version) and os.path.isfile(tar_gz): os.system("gunzip -c %s | tar xf -" % tar_gz) if not os.path.isdir(scons_version): - print "Found neither SCons package `%s' nor `%s'." % (tar_gz, zip) - print "Cannot test package installation." + print "Cannot test package installation, found none of the following packages:" + print "\t" + tar_gz + print "\t" + zip test.no_result(1) # Verify that a virgin installation installs the version library, diff --git a/test/AR/AR.py b/test/AR/AR.py index 32419fa..cb11175 100644 --- a/test/AR/AR.py +++ b/test/AR/AR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) ar = foo.Dictionary('AR') -bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], AR = r'%s wrapper.py ' + ar) +bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], AR = r'%(_python_)s wrapper.py ' + ar) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -53,9 +53,11 @@ obj = foo.Object('main', 'main.c') foo.Program(target = 'f', source = obj) bar.Program(target = 'b', source = obj) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> + void library_function(void) { @@ -64,6 +66,8 @@ library_function(void) """) test.write('bar.c', r""" +#include <stdio.h> + void library_function(void) { @@ -72,6 +76,9 @@ library_function(void) """) test.write('main.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/AR/ARCOM.py b/test/AR/ARCOM.py index c8ac1d8..73c36fc 100644 --- a/test/AR/ARCOM.py +++ b/test/AR/ARCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $ARCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,12 +51,12 @@ test.write('myranlib.py', """ test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n") test.write('file.2', "file.2\n/*ar*/\n") diff --git a/test/AR/ARCOMSTR.py b/test/AR/ARCOMSTR.py index ae63ea0..914031b 100644 --- a/test/AR/ARCOMSTR.py +++ b/test/AR/ARCOMSTR.py @@ -32,7 +32,7 @@ the displayed archiver string. import TestSCons import string -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,13 +53,13 @@ test.write('myranlib.py', """ test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', ARCOMSTR = 'Archiving $TARGET from $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n") test.write('file.2', "file.2\n/*ar*/\n") diff --git a/test/AR/ARFLAGS.py b/test/AR/ARFLAGS.py index 399170e..d4d122e 100644 --- a/test/AR/ARFLAGS.py +++ b/test/AR/ARFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], - AR = '', ARFLAGS = foo.subst(r'%s wrapper.py $AR $ARFLAGS')) + AR = '', ARFLAGS = foo.subst(r'%(_python_)s wrapper.py $AR $ARFLAGS')) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -53,9 +53,11 @@ obj = foo.Object('main', 'main.c') foo.Program(target = 'f', source = obj) bar.Program(target = 'b', source = obj) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> + void library_function(void) { @@ -64,6 +66,8 @@ library_function(void) """) test.write('bar.c', r""" +#include <stdio.h> + void library_function(void) { @@ -72,6 +76,8 @@ library_function(void) """) test.write('main.c', r""" +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/AS/AS.py b/test/AS/AS.py index 0543a0c..2c9e624 100644 --- a/test/AS/AS.py +++ b/test/AS/AS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -110,17 +110,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', - LINKFLAGS = [], - AS = r'%s myas.py', - CC = r'%s myas.py') +env = Environment(LINK = r'%(_python_)s mylink.py', + AS = r'%(_python_)s myas.py', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.s') env.Program(target = 'test2', source = 'test2.S') env.Program(target = 'test3', source = 'test3.asm') env.Program(target = 'test4', source = 'test4.ASM') env.Program(target = 'test5', source = 'test5.spp') env.Program(target = 'test6', source = 'test6.SPP') -""" % (python, python, python)) +""" % locals()) test.write('test1.s', r"""This is a .s file. #as @@ -183,12 +182,12 @@ os.system(cmd) test.write('SConstruct', """\ aaa = Environment() -bbb = aaa.Copy(AS = r'%s wrapper.py ' + WhereIs('as')) +bbb = aaa.Copy(AS = r'%(_python_)s wrapper.py ' + WhereIs('as')) ccc = aaa.Copy(CPPPATH=['.']) aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c']) bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c']) ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c']) -""" % python) +""" % locals()) test.write('aaa.s', """ .file "aaa.s" @@ -226,6 +225,9 @@ name: """) test.write('aaa_main.c', r""" +#include <stdlib.h> +#include <stdio.h> + extern char name[]; int @@ -238,6 +240,9 @@ main(int argc, char *argv[]) """) test.write('bbb_main.c', r""" +#include <stdlib.h> +#include <stdio.h> + extern char name[]; int @@ -250,6 +255,9 @@ main(int argc, char *argv[]) """) test.write('ccc_main.c', r""" +#include <stdlib.h> +#include <stdio.h> + extern char name[]; int @@ -309,10 +317,10 @@ import os ccc = Environment(tools = ['msvc', 'mslink', 'masm'], ASFLAGS = '/nologo /coff') ccc['ENV']['PATH'] = ccc['ENV']['PATH'] + os.pathsep + os.environ['PATH'] -ddd = ccc.Copy(AS = r'%s wrapper.py ' + ccc['AS']) +ddd = ccc.Copy(AS = r'%(_python_)s wrapper.py ' + ccc['AS']) ccc.Program(target = 'ccc', source = ['ccc.asm', 'ccc_main.c']) ddd.Program(target = 'ddd', source = ['ddd.asm', 'ddd_main.c']) -""" % python) +""" % locals()) test.write('ccc.asm', """ @@ -398,11 +406,11 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ eee = Environment(tools = ['gcc', 'gnulink', 'nasm'], - ASFLAGS = '-f %s') -fff = eee.Copy(AS = r'%s wrapper.py ' + WhereIs('nasm')) + ASFLAGS = '-f %(nasm_format)s') +fff = eee.Copy(AS = r'%(_python_)s wrapper.py ' + WhereIs('nasm')) eee.Program(target = 'eee', source = ['eee.asm', 'eee_main.c']) fff.Program(target = 'fff', source = ['fff.asm', 'fff_main.c']) -""" % (nasm_format, python)) +""" % locals()) test.write('eee.asm', """ diff --git a/test/AS/ASCOM.py b/test/AS/ASCOM.py index da66bca..4292581 100644 --- a/test/AS/ASCOM.py +++ b/test/AS/ASCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -56,18 +56,27 @@ else: alt_asm_suffix = '.asm' test.write('SConstruct', """ -env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE', - OBJSUFFIX = '.obj') +env = Environment(ASCOM = r'%(_python_)s myas.py $TARGET $SOURCE', + OBJSUFFIX = '.obj', + SHOBJSUFFIX = '.shobj') env.Object(target = 'test1', source = 'test1.s') env.Object(target = 'test2', source = 'test2%(alt_s_suffix)s') env.Object(target = 'test3', source = 'test3.asm') env.Object(target = 'test4', source = 'test4%(alt_asm_suffix)s') +env.SharedObject(target = 'test5', source = 'test5.s') +env.SharedObject(target = 'test6', source = 'test6%(alt_s_suffix)s') +env.SharedObject(target = 'test7', source = 'test7.asm') +env.SharedObject(target = 'test8', source = 'test8%(alt_asm_suffix)s') """ % locals()) test.write('test1.s', "test1.s\n#as\n") test.write('test2'+alt_s_suffix, "test2.S\n#as\n") test.write('test3.asm', "test3.asm\n#as\n") test.write('test4'+alt_asm_suffix, "test4.ASM\n#as\n") +test.write('test5.s', "test5.s\n#as\n") +test.write('test6'+alt_s_suffix, "test6.S\n#as\n") +test.write('test7.asm', "test7.asm\n#as\n") +test.write('test8'+alt_asm_suffix, "test8.ASM\n#as\n") test.run(arguments = '.') @@ -75,6 +84,10 @@ test.fail_test(test.read('test1.obj') != "test1.s\n") test.fail_test(test.read('test2.obj') != "test2.S\n") test.fail_test(test.read('test3.obj') != "test3.asm\n") test.fail_test(test.read('test4.obj') != "test4.ASM\n") +test.fail_test(test.read('test5.shobj') != "test5.s\n") +test.fail_test(test.read('test6.shobj') != "test6.S\n") +test.fail_test(test.read('test7.shobj') != "test7.asm\n") +test.fail_test(test.read('test8.shobj') != "test8.ASM\n") diff --git a/test/AS/ASCOMSTR.py b/test/AS/ASCOMSTR.py index c8eed62..287da16 100644 --- a/test/AS/ASCOMSTR.py +++ b/test/AS/ASCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,7 +57,7 @@ else: alt_asm_suffix = '.asm' test.write('SConstruct', """ -env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE', +env = Environment(ASCOM = r'%(_python_)s myas.py $TARGET $SOURCE', ASCOMSTR = 'Assembling $TARGET from $SOURCE', OBJSUFFIX = '.obj') env.Object(target = 'test1', source = 'test1.s') diff --git a/test/AS/ASFLAGS.py b/test/AS/ASFLAGS.py index 6396c45..a0da9ff 100644 --- a/test/AS/ASFLAGS.py +++ b/test/AS/ASFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -126,17 +126,17 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - AS = r'%s myas.py', ASFLAGS = '-x', - CC = r'%s myas.py') + AS = r'%(_python_)s myas.py', ASFLAGS = '-x', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.s') env.Program(target = 'test2', source = 'test2.S') env.Program(target = 'test3', source = 'test3.asm') env.Program(target = 'test4', source = 'test4.ASM') env.Program(target = 'test5', source = 'test5.spp') env.Program(target = 'test6', source = 'test6.SPP') -""" % (python, python, python)) +""" % locals()) test.write('test1.s', r"""This is a .s file. #as diff --git a/test/AS/ASPP.py b/test/AS/ASPP.py index da47618..2045a3d 100644 --- a/test/AS/ASPP.py +++ b/test/AS/ASPP.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -110,13 +110,13 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - ASPP = r'%s myas.py', - CC = r'%s myas.py') + ASPP = r'%(_python_)s myas.py', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.spp') env.Program(target = 'test2', source = 'test2.SPP') -""" % (python, python, python)) +""" % locals()) test.write('test1.spp', r"""This is a .spp file. #as diff --git a/test/AS/ASPPCOM.py b/test/AS/ASPPCOM.py index e877354..bb330dc 100644 --- a/test/AS/ASPPCOM.py +++ b/test/AS/ASPPCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,19 +49,26 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(ASPPCOM = r'%(python)s myas.py $TARGET $SOURCE', - OBJSUFFIX = '.obj') +env = Environment(ASPPCOM = r'%(_python_)s myas.py $TARGET $SOURCE', + OBJSUFFIX = '.obj', + SHOBJSUFFIX = '.shobj') env.Object(target = 'test1', source = 'test1.spp') env.Object(target = 'test2', source = 'test2.SPP') +env.SharedObject(target = 'test3', source = 'test3.spp') +env.SharedObject(target = 'test4', source = 'test4.SPP') """ % locals()) test.write('test1.spp', "test1.spp\n#as\n") test.write('test2.SPP', "test2.SPP\n#as\n") +test.write('test3.spp', "test3.spp\n#as\n") +test.write('test4.SPP', "test4.SPP\n#as\n") test.run(arguments = '.') test.fail_test(test.read('test1.obj') != "test1.spp\n") test.fail_test(test.read('test2.obj') != "test2.SPP\n") +test.fail_test(test.read('test3.shobj') != "test3.spp\n") +test.fail_test(test.read('test4.shobj') != "test4.SPP\n") diff --git a/test/AS/ASPPCOMSTR.py b/test/AS/ASPPCOMSTR.py index 21e8033..1956154 100644 --- a/test/AS/ASPPCOMSTR.py +++ b/test/AS/ASPPCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(ASPPCOM = r'%(python)s myas.py $TARGET $SOURCE', +env = Environment(ASPPCOM = r'%(_python_)s myas.py $TARGET $SOURCE', ASPPCOMSTR = 'Assembling $TARGET from $SOURCE', OBJSUFFIX = '.obj') env.Object(target = 'test1', source = 'test1.spp') diff --git a/test/AS/ASPPFLAGS.py b/test/AS/ASPPFLAGS.py index cbd4339..27858bd 100644 --- a/test/AS/ASPPFLAGS.py +++ b/test/AS/ASPPFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -126,10 +126,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%(python)s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - ASPP = r'%(python)s myas.py', ASPPFLAGS = '-x', - CC = r'%(python)s myas.py') + ASPP = r'%(_python_)s myas.py', ASPPFLAGS = '-x', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.spp') env.Program(target = 'test2', source = 'test2.SPP') """ % locals()) diff --git a/test/Actions/actions.py b/test/Actions/actions.py index 7ae951a..61c3c7d 100644 --- a/test/Actions/actions.py +++ b/test/Actions/actions.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,10 +41,10 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGET 1 $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGET 1 $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.write('foo.in', "foo.in\n") @@ -55,10 +55,10 @@ test.fail_test(test.read('foo.out') != "1\nfoo.in\n") test.up_to_date(arguments = '.') test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGET 2 $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGET 2 $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.') @@ -70,14 +70,14 @@ test.write('SConstruct', """ import os import string def func(env, target, source): - cmd = r'%s build.py %%s 3 %%s' %% (string.join(map(str, target)), + cmd = r'%(_python_)s build.py %%s 3 %%s' %% (string.join(map(str, target)), string.join(map(str, source))) print cmd return os.system(cmd) B = Builder(action = func) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.', stderr = None) @@ -91,7 +91,7 @@ assert not globals().has_key('string') import string class bld: def __init__(self): - self.cmd = r'%s build.py %%s 4 %%s' + self.cmd = r'%(_python_)s build.py %%s 4 %%s' def __call__(self, env, target, source): cmd = self.get_contents(env, target, source) print cmd @@ -102,7 +102,7 @@ class bld: B = Builder(action = bld()) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.') diff --git a/test/Actions/pre-post.py b/test/Actions/pre-post.py index e25def5..e076f24 100644 --- a/test/Actions/pre-post.py +++ b/test/Actions/pre-post.py @@ -34,7 +34,7 @@ import sys import TestSCons _exe = TestSCons._exe -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -187,7 +187,7 @@ def post_action(target, source, env): env = Environment() o = env.Command(['pre-post', 'file.out'], 'file.in', - "%(python)s build.py ${TARGETS[1]} $SOURCE") + '%(_python_)s build.py ${TARGETS[1]} $SOURCE') env.AddPreAction(o, pre_action) env.AddPostAction(o, post_action) """ % locals()) diff --git a/test/Alias/Alias.py b/test/Alias/Alias.py index 56efafd..b53b8ce 100644 --- a/test/Alias/Alias.py +++ b/test/Alias/Alias.py @@ -29,7 +29,7 @@ import sys import TestSCons import TestCmd -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match=TestCmd.match_re) @@ -42,7 +42,7 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(action = r"%s build.py $TARGET $SOURCES") +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment() env['BUILDERS']['B'] = B env.B(target = 'f1.out', source = 'f1.in') @@ -62,7 +62,7 @@ env.Depends('f1.out', 'bar') assert Alias('foo') == foo assert Alias('bar') == bar -""" % python) +""" % locals()) test.write(['sub1', 'SConscript'], """ Import("env") @@ -134,7 +134,7 @@ test.up_to_date(arguments = 'f1.out') test.write('SConstruct', """ TargetSignatures('content') -B = Builder(action = r"%s build.py $TARGET $SOURCES") +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment() env['BUILDERS']['B'] = B env.B(target = 'f1.out', source = 'f1.in') @@ -147,7 +147,7 @@ env.Alias('bar', ['sub2', 'f3.out']) env.Alias('blat', ['sub2', 'f3.out']) env.Alias('blat', ['f2.out', 'sub1']) env.Depends('f1.out', 'bar') -""" % python) +""" % locals()) os.unlink(test.workpath('f1.out')) @@ -157,12 +157,12 @@ test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.write('f3.in', "f3.in 3 \n") -test.run(arguments = 'f1.out', - match = TestCmd.match_exact, - stdout = test.wrap_stdout("""\ -%s build.py f3.out f3.in -%s build.py f1.out f1.in -""" % (python, python))) +expect = test.wrap_stdout("""\ +%(_python_)s build.py f3.out f3.in +%(_python_)s build.py f1.out f1.in +""" % locals()) + +test.run(arguments = 'f1.out', match = TestCmd.match_exact, stdout = expect) test.up_to_date(arguments = 'f1.out') diff --git a/test/BadBuilder.py b/test/BadBuilder.py index 4667a21..8c28ea5 100644 --- a/test/BadBuilder.py +++ b/test/BadBuilder.py @@ -34,6 +34,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + sconstruct = """ def buildop(env, source, target): outf = open(str(target[0]), 'wb') @@ -58,42 +60,42 @@ built ### Gross mistake in Builder spec -test.write('SConstruct', sconstruct % '\ +test.write(SConstruct_path, sconstruct % '\ b2 = Builder(act__ion=buildop, src_suffix=".b", suffix=".c")') -test.run(arguments='.', - stderr="""\ +expect_stderr = """\ scons: *** Builder b2 must have an action to build ['foo.c']. -File "SConstruct", line 14, in ? -""", -status = 2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='.', stderr=expect_stderr, status = 2) ### Subtle mistake in Builder spec -test.write('SConstruct', sconstruct % '\ +test.write(SConstruct_path, sconstruct % '\ b2 = Builder(actoin=buildop, src_suffix=".b", suffix=".c")') -test.run(arguments='test2', - stderr="""\ +expect_stderr="""\ scons: *** Builder b2 must have an action to build ['foo.c']. -File "SConstruct", line 14, in ? -""", -status = 2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='test2', stderr=expect_stderr, status=2) ### Missing action in Builder spec -test.write('SConstruct', sconstruct % '\ +test.write(SConstruct_path, sconstruct % '\ b2 = Builder(src_suffix=".b", suffix=".c")') -test.run(arguments='test2', - stderr="""\ +expect_stderr = """\ scons: *** Builder b2 must have an action to build ['foo.c']. -File "SConstruct", line 14, in ? -""", -status = 2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='test2', stderr=expect_stderr, status = 2) test.pass_test() diff --git a/test/BitKeeper/BITKEEPERCOM.py b/test/BitKeeper/BITKEEPERCOM.py index 2b76cc3..a4bdd90 100644 --- a/test/BitKeeper/BITKEEPERCOM.py +++ b/test/BitKeeper/BITKEEPERCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'BitKeeper'], BUILDERS={'Cat':Builder(action=cat)}, - BITKEEPERCOM='%(python)s my-bk-get.py $TARGET') + BITKEEPERCOM='%(_python_)s my-bk-get.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['BitKeeper', 'sub', 'fff.in'], "BitKeeper/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-bk-get.py %(sub_SConscript)s +%(_python_)s my-bk-get.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-bk-get.py aaa.in +%(_python_)s my-bk-get.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-bk-get.py ccc.in +%(_python_)s my-bk-get.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-bk-get.py %(sub_ddd_in)s +%(_python_)s my-bk-get.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-bk-get.py %(sub_fff_in)s +%(_python_)s my-bk-get.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/BitKeeper/BITKEEPERCOMSTR.py b/test/BitKeeper/BITKEEPERCOMSTR.py index 604642b..aa9e2a0 100644 --- a/test/BitKeeper/BITKEEPERCOMSTR.py +++ b/test/BitKeeper/BITKEEPERCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'BitKeeper'], BUILDERS={'Cat':Builder(action=cat)}, - BITKEEPERCOM='%(python)s my-bk-get.py $TARGET', + BITKEEPERCOM='%(_python_)s my-bk-get.py $TARGET', BITKEEPERCOMSTR='Checking out $TARGET from our fake BitKeeper') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/BuildDir/BuildDir.py b/test/BuildDir/BuildDir.py index 0bae185..f655bf9 100644 --- a/test/BuildDir/BuildDir.py +++ b/test/BuildDir/BuildDir.py @@ -129,6 +129,9 @@ if fortran and env.Detect(fortran): """ % (fortran_runtime, fortran_runtime)) test.write(['work1', 'src', 'f1.c'], r""" +#include <stdio.h> +#include <stdlib.h> + #include "f1.h" int @@ -141,6 +144,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f2.in'], r""" +#include <stdio.h> +#include <stdlib.h> + #include "f2.h" int @@ -153,6 +159,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f3.c'], r""" +#include <stdio.h> +#include <stdlib.h> + #include "f3.h" int @@ -165,6 +174,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f4.in'], r""" +#include <stdio.h> +#include <stdlib.h> + #include "f4.h" int @@ -325,6 +337,9 @@ env.Program('prog.c') """) test.write(['work2', 'prog.c'], r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/BuildDir/Sconscript-build_dir.py b/test/BuildDir/Sconscript-build_dir.py index 298eb9b..685011d 100644 --- a/test/BuildDir/Sconscript-build_dir.py +++ b/test/BuildDir/Sconscript-build_dir.py @@ -212,6 +212,9 @@ env.Program('foo', [foo_obj, 'bar.c']) """) test.write(['test2', 'bar.c'], r""" +#include <stdio.h> +#include <stdlib.h> + void bar(void) { printf("bar.c\n"); @@ -219,6 +222,9 @@ bar(void) { """) test.write(['test2', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { bar(); diff --git a/test/BuildDir/errors.py b/test/BuildDir/errors.py index 285b996..4fcd625 100644 --- a/test/BuildDir/errors.py +++ b/test/BuildDir/errors.py @@ -155,17 +155,22 @@ f.close() # build directory results in an error message, rather # than just silently failing. test.subdir('duplicate', ['duplicate', 'src1'], ['duplicate', 'src2']) -test.write(['duplicate', 'SConstruct'], """\ + +duplicate_SConstruct_path = test.workpath('duplicate', 'SConstruct') + +test.write(duplicate_SConstruct_path, """\ BuildDir('build', 'src1') BuildDir('build', 'src2') """) +expect_stderr = """ +scons: *** 'build' already has a source directory: 'src1'. +File "%(duplicate_SConstruct_path)s", line 2, in ? +""" % locals() + test.run(chdir = 'duplicate', arguments = ".", status = 2, - stderr = """ -scons: *** 'build' already has a source directory: 'src1'. -File "SConstruct", line 2, in ? -""") + stderr = expect_stderr) test.pass_test() diff --git a/test/BuildDir/nested-sconscripts.py b/test/BuildDir/nested-sconscripts.py new file mode 100644 index 0000000..d9e110e --- /dev/null +++ b/test/BuildDir/nested-sconscripts.py @@ -0,0 +1,64 @@ +#!/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 that nested SConscript files in a BuildDir don't throw +an OSError exception looking for the wrong file. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir(['src'], + ['src', 'md'], + ['src', 'md', 'test']) + +test.write(['src', 'SConstruct'], """\ +BUILD_DIR = '../build' + +base_env = Environment() + +for flavor in ['prod', 'debug']: + build_env = base_env.Copy() + # In real life, we would modify build_env appropriately here + FLAVOR_DIR = BUILD_DIR + '/' + flavor + Export('build_env') + BuildDir(FLAVOR_DIR, 'md', duplicate=0) + SConscript(FLAVOR_DIR + '/SConscript') +""") + +test.write(['src', 'md', 'SConscript'], """\ +SConscript('test/SConscript') +""") + +test.write(['src', 'md', 'test', 'SConscript'], """\ +# empty +""") + +test.run(chdir='src') + +test.pass_test() diff --git a/test/BuildDir/reflect.py b/test/BuildDir/reflect.py index beb7df0..9a25029 100644 --- a/test/BuildDir/reflect.py +++ b/test/BuildDir/reflect.py @@ -39,8 +39,9 @@ import re import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python -re_python = re.escape(python) + +_python_ = TestSCons._python_ +re_python = re.escape(TestSCons.python) test.write("mycc.py", """ print 'Compile' @@ -51,8 +52,8 @@ print 'Link' """) sconstruct = """ -env = Environment(CC = r'%(python)s mycc.py', - LINK = r'%(python)s mylink.py', +env = Environment(CC = r'%(_python_)s mycc.py', + LINK = r'%(_python_)s mylink.py', INCPREFIX = 'INC_', INCSUFFIX = '_CNI', CPPPATH='%(cpppath)s') # note no leading '#' @@ -86,17 +87,16 @@ test.write('SConstruct', sconstruct % locals() ) targets = re.escape(os.path.join('dir1', 'dir2')) INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2', 'dir1', 'dir2_CNI')) -# The .* after mycc\\.py below handles /nologo flags from Visual C/C++. -test.run(arguments = '', - stdout=test.wrap_stdout("""\ +# The .+ after mycc\\.py below handles /nologo flags from Visual C/C++. +expect = test.wrap_stdout("""\ scons: building associated BuildDir targets: %(targets)s -%(re_python)s mycc\\.py.* %(INC_CNI)s .+ +"%(re_python)s" mycc\\.py.* %(INC_CNI)s .+ Compile -%(re_python)s mylink\\.py .+ +"%(re_python)s" mylink\\.py .+ Link -""" % locals()), - match=TestSCons.match_re, - ) +""" % locals()) + +test.run(arguments = '', match=TestSCons.match_re, stdout=expect) # Note that we don't check for the existence of dir1/dir2/foo.h, because # this bad cpppath will expand to dir1/dir2/dir1/dir2, which means it @@ -120,9 +120,9 @@ INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2_CNI')) test.run(arguments = '', stdout=test.wrap_stdout("""\ scons: building associated BuildDir targets: %(targets)s -%(re_python)s mycc\\.py.* %(INC_CNI)s .+ +"%(re_python)s" mycc\\.py.* %(INC_CNI)s .+ Compile -%(re_python)s mylink\\.py .+ +"%(re_python)s" mylink\\.py .+ Link """ % locals()), match=TestSCons.match_re, diff --git a/test/CC/CC.py b/test/CC/CC.py index a790baa..c57b7db 100644 --- a/test/CC/CC.py +++ b/test/CC/CC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -108,13 +108,13 @@ sys.exit(0) test.write('SConstruct', """ cc = Environment().Dictionary('CC') -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CC = r'%s mycc.py', + CC = r'%(_python_)s mycc.py', CXX = cc, CXXFLAGS = []) env.Program(target = 'test1', source = 'test1.c') -""" % (python, python)) +""" % locals()) test.write('test1.c', r"""This is a .c file. /*cc*/ @@ -129,11 +129,11 @@ if os.path.normcase('.c') == os.path.normcase('.C'): test.write('SConstruct', """ cc = Environment().Dictionary('CC') -env = Environment(LINK = r'%s mylink.py', - CC = r'%s mycc.py', +env = Environment(LINK = r'%(_python_)s mylink.py', + CC = r'%(_python_)s mycc.py', CXX = cc) env.Program(target = 'test2', source = 'test2.C') -""" % (python, python)) +""" % locals()) test.write('test2.C', r"""This is a .C file. /*cc*/ @@ -158,12 +158,15 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() cc = foo.Dictionary('CC') -bar = Environment(CC = r'%s wrapper.py ' + cc) +bar = Environment(CC = r'%(_python_)s wrapper.py ' + cc) foo.Program(target = 'foo', source = 'foo.c') bar.Program(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { @@ -174,6 +177,9 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/CC/CCCOM.py b/test/CC/CCCOM.py index 1be89a3..ca13ec8 100644 --- a/test/CC/CCCOM.py +++ b/test/CC/CCCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.c') env.Object(target = 'test2', source = 'test2%(alt_c_suffix)s') diff --git a/test/CC/CCCOMSTR.py b/test/CC/CCCOMSTR.py index 1dd6a57..50ddb5a 100644 --- a/test/CC/CCCOMSTR.py +++ b/test/CC/CCCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', CCCOMSTR = 'Building $TARGET from $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.c') diff --git a/test/CC/CCFLAGS.py b/test/CC/CCFLAGS.py index d05cdef..bee2499 100644 --- a/test/CC/CCFLAGS.py +++ b/test/CC/CCFLAGS.py @@ -50,6 +50,9 @@ foo.Program(target = 'prog', source = 'prog.c', """ % (fooflags, barflags, _obj, _obj, _obj, _obj)) test.write('prog.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/CC/SHCC.py b/test/CC/SHCC.py index 3679a9e..9a025b1 100644 --- a/test/CC/SHCC.py +++ b/test/CC/SHCC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,12 +44,15 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() shcc = foo.Dictionary('SHCC') -bar = Environment(SHCC = r'%s wrapper.py ' + shcc) +bar = Environment(SHCC = r'%(_python_)s wrapper.py ' + shcc) foo.SharedObject(target = 'foo/foo', source = 'foo.c') bar.SharedObject(target = 'bar/bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { @@ -60,6 +63,9 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/CC/SHCCCOM.py b/test/CC/SHCCCOM.py index 13cdaa8..5606fd0 100644 --- a/test/CC/SHCCCOM.py +++ b/test/CC/SHCCCOM.py @@ -33,7 +33,7 @@ import TestSCons Test the ability to configure the $SHCCCOM construction variable. """ -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -54,7 +54,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.c') env.SharedObject(target = 'test2', source = 'test2%(alt_c_suffix)s') diff --git a/test/CC/SHCCCOMSTR.py b/test/CC/SHCCCOMSTR.py index 27e5cbc..4d240ae 100644 --- a/test/CC/SHCCCOMSTR.py +++ b/test/CC/SHCCCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHCCCOMSTR = 'Building $TARGET from $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.c') diff --git a/test/CC/SHCCFLAGS.py b/test/CC/SHCCFLAGS.py index 1f4fd3d..316da0f 100644 --- a/test/CC/SHCCFLAGS.py +++ b/test/CC/SHCCFLAGS.py @@ -28,16 +28,13 @@ import sys import TestSCons import os import string - -if sys.platform == 'win32': - fooflags = '/nologo -DFOO' - barflags = '/nologo -DBAR' -else: - fooflags = '-DFOO' - barflags = '-DBAR' test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCCFLAGS'] + ' -DFOO' +barflags = e['SHCCFLAGS'] + ' -DBAR' + if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' if string.find(sys.platform, 'irix') > -1: @@ -79,6 +76,8 @@ EXPORTS """) test.write('prog.c', r""" +#include <stdio.h> + void doIt() { diff --git a/test/CFILESUFFIX.py b/test/CFILESUFFIX.py index a122fe0..9cbadf2 100644 --- a/test/CFILESUFFIX.py +++ b/test/CFILESUFFIX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,10 +46,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', tools = ['lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) env.CFile(target = 'foo', source = 'foo.l') env.Copy(CFILESUFFIX = '.xyz').CFile(target = 'bar', source = 'bar.l') -""" % python) +""" % locals()) input = r""" int diff --git a/test/CPPDEFINES.py b/test/CPPDEFINES.py index 7c65401..8639eb2 100644 --- a/test/CPPDEFINES.py +++ b/test/CPPDEFINES.py @@ -87,6 +87,9 @@ baz.Program(target = 'baz', source = 'baz.cpp') """) test.write('prog.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/CPPFLAGS.py b/test/CPPFLAGS.py index 72b10b7..ce8bd77 100644 --- a/test/CPPFLAGS.py +++ b/test/CPPFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj _shobj = TestSCons._shobj @@ -102,14 +102,14 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(CPPFLAGS = '-x', - LINK = r'%s mylink.py', + LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CC = r'%s mygcc.py cc', - CXX = r'%s mygcc.py c++', + CC = r'%(_python_)s mygcc.py cc', + CXX = r'%(_python_)s mygcc.py c++', CXXFLAGS = [], - FORTRAN = r'%s mygcc.py g77') + FORTRAN = r'%(_python_)s mygcc.py g77') env.Program(target = 'foo', source = Split('test1.c test2.cpp test3.F')) -""" % (python, python, python, python)) +""" % locals()) test.write('test1.c', r"""test1.c #cc @@ -139,15 +139,15 @@ else: test.write('SConstruct', """ env = Environment(CPPFLAGS = '-x', - SHLINK = r'%s mylink.py', + SHLINK = r'%(_python_)s mylink.py', SHLINKFLAGS = [], - CC = r'%s mygcc.py cc', - CXX = r'%s mygcc.py c++', + CC = r'%(_python_)s mygcc.py cc', + CXX = r'%(_python_)s mygcc.py c++', CXXFLAGS = [], - FORTRAN = r'%s mygcc.py g77') + FORTRAN = r'%(_python_)s mygcc.py g77') env.SharedLibrary(target = File('foo.bar'), source = Split('test1.c test2.cpp test3.F')) -""" % (python, python, python, python)) +""" % locals()) test.write('test1.c', r"""test1.c #cc diff --git a/test/CPPSUFFIXES.py b/test/CPPSUFFIXES.py index a340a4a..305cf04 100644 --- a/test/CPPSUFFIXES.py +++ b/test/CPPSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $CPPSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(CPPPATH = ['.'], - CC = r'%s mycc.py', + CC = r'%(_python_)s mycc.py', CCFLAGS = [], CCCOM = '$CC $TARGET $SOURCES', OBJSUFFIX = '.o') @@ -60,7 +60,7 @@ env.Object(target = 'test1', source = 'test1.c') env.InstallAs('test1_c', 'test1.c') env.InstallAs('test1_h', 'test1.h') env.InstallAs('test1_x', 'test1.x') -""" % (python,)) +""" % locals()) test.write('test1.c', """\ test1.c 1 @@ -80,12 +80,14 @@ test1.x 1 test.write('foo.h', "foo.h 1\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c Install file: "test1.c" as "test1_c" Install file: "test1.h" as "test1_h" Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 @@ -99,9 +101,11 @@ test.up_to_date(arguments='.') test.write('foo.h', "foo.h 2\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c -""" % (python,))) +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 @@ -118,10 +122,12 @@ test1.x 2 #include <foo.h> """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 @@ -138,10 +144,12 @@ test1.h 2 #include <foo.h> """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c Install file: "test1.h" as "test1_h" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 diff --git a/test/CVS.py b/test/CVS.py index 3002ee7..c21d9ad 100644 --- a/test/CVS.py +++ b/test/CVS.py @@ -97,7 +97,8 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(ENV = { 'PATH' : os.environ['PATH'] }, +env = Environment(ENV = { 'PATH' : os.environ['PATH'], + 'EDITOR' : os.environ.get('EDITOR', 'ed') }, BUILDERS={'Cat':Builder(action=cat)}) env.Prepend(CVSFLAGS='-Q') env.Cat('aaa.out', 'foo/aaa.in') @@ -161,7 +162,8 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(ENV = { 'PATH' : os.environ['PATH'] }, +env = Environment(ENV = { 'PATH' : os.environ['PATH'], + 'EDITOR' : os.environ.get('EDITOR', 'ed') }, BUILDERS={'Cat':Builder(action=cat)}) env.Prepend(CVSFLAGS='-q') env.Cat('aaa.out', 'aaa.in') @@ -232,7 +234,8 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(ENV = { 'PATH' : os.environ['PATH'] }, +env = Environment(ENV = { 'PATH' : os.environ['PATH'], + 'EDITOR' : os.environ.get('EDITOR', 'ed') }, BUILDERS={'Cat':Builder(action=cat)}, CVSROOT=r'%s') env.Prepend(CVSFLAGS='-q') diff --git a/test/CVSCOM.py b/test/CVSCOM.py index f8eaa6a..cbb2f3f 100644 --- a/test/CVSCOM.py +++ b/test/CVSCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'CVS'], BUILDERS={'Cat':Builder(action=cat)}, - CVSCOM='%(python)s my-cvs-co-.py $TARGET') + CVSCOM='%(_python_)s my-cvs-co-.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['CVS', 'sub', 'fff.in'], "CVS/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-cvs-co-.py %(sub_SConscript)s +%(_python_)s my-cvs-co-.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-cvs-co-.py aaa.in +%(_python_)s my-cvs-co-.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-cvs-co-.py ccc.in +%(_python_)s my-cvs-co-.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-cvs-co-.py %(sub_ddd_in)s +%(_python_)s my-cvs-co-.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-cvs-co-.py %(sub_fff_in)s +%(_python_)s my-cvs-co-.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/CVSCOMSTR.py b/test/CVSCOMSTR.py index 78c40f7..acf0647 100644 --- a/test/CVSCOMSTR.py +++ b/test/CVSCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'CVS'], BUILDERS={'Cat':Builder(action=cat)}, - CVSCOM='%(python)s my-cvs-co.py $TARGET', + CVSCOM='%(_python_)s my-cvs-co.py $TARGET', CVSCOMSTR='Checking out $TARGET from our fake CVS') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py index 70a9b82..a1b4c2a 100644 --- a/test/CXX/CXX.py +++ b/test/CXX/CXX.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -107,16 +107,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CXX = r'%s myc++.py', + CXX = r'%(_python_)s myc++.py', CXXFLAGS = []) env.Program(target = 'test1', source = 'test1.cc') env.Program(target = 'test2', source = 'test2.cpp') env.Program(target = 'test3', source = 'test3.cxx') env.Program(target = 'test4', source = 'test4.c++') env.Program(target = 'test5', source = 'test5.C++') -""" % (python, python)) +""" % locals()) test.write('test1.cc', r"""This is a .cc file. /*c++*/ @@ -158,12 +158,12 @@ test.must_match('test5' + _exe, "This is a .C++ file.\n") if TestSCons.case_sensitive_suffixes('.c', '.C'): test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CXX = r'%s myc++.py', + CXX = r'%(_python_)s myc++.py', CXXFLAGS = []) env.Program(target = 'test6', source = 'test6.C') -""" % (python, python)) +""" % locals()) test.write('test6.C', r"""This is a .C file. /*c++*/ @@ -188,10 +188,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() cxx = foo.Dictionary('CXX') -bar = Environment(CXX = r'%s wrapper.py ' + cxx) +bar = Environment(CXX = r'%(_python_)s wrapper.py ' + cxx) foo.Program(target = 'foo', source = 'foo.cxx') bar.Program(target = 'bar', source = 'bar.cxx') -""" % python) +""" % locals()) test.write('foo.cxx', r""" #include <stdio.h> diff --git a/test/CXX/CXXCOM.py b/test/CXX/CXXCOM.py index c4c419d..c98fb8c 100644 --- a/test/CXX/CXXCOM.py +++ b/test/CXX/CXXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.cpp') env.Object(target = 'test2', source = 'test2.cc') diff --git a/test/CXX/CXXCOMSTR.py b/test/CXX/CXXCOMSTR.py index 82f7ace..23bd3e6 100644 --- a/test/CXX/CXXCOMSTR.py +++ b/test/CXX/CXXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', CXXCOMSTR = 'Building $TARGET from $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.cpp') diff --git a/test/CXX/CXXFILESUFFIX.py b/test/CXX/CXXFILESUFFIX.py index 8f4c4fa..62e8cc1 100644 --- a/test/CXX/CXXFILESUFFIX.py +++ b/test/CXX/CXXFILESUFFIX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,10 +46,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', tools = ['lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) env.CXXFile(target = 'foo', source = 'foo.ll') env.Copy(CXXFILESUFFIX = '.xyz').CXXFile(target = 'bar', source = 'bar.ll') -""" % python) +""" % locals()) input = r""" int diff --git a/test/CXX/SHCXX.py b/test/CXX/SHCXX.py index 5c050d1..c02086b 100644 --- a/test/CXX/SHCXX.py +++ b/test/CXX/SHCXX.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,10 +44,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() shcxx = foo.Dictionary('SHCXX') -bar = Environment(SHCXX = r'%s wrapper.py ' + shcxx) +bar = Environment(SHCXX = r'%(_python_)s wrapper.py ' + shcxx) foo.SharedObject(target = 'foo/foo', source = 'foo.cpp') bar.SharedObject(target = 'bar/bar', source = 'bar.cpp') -""" % python) +""" % locals()) test.write('foo.cpp', r""" #include <stdio.h> diff --git a/test/CXX/SHCXXCOM.py b/test/CXX/SHCXXCOM.py index 54ef0d5..600049e 100644 --- a/test/CXX/SHCXXCOM.py +++ b/test/CXX/SHCXXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(SHCXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.cpp') env.SharedObject(target = 'test2', source = 'test2.cc') diff --git a/test/CXX/SHCXXCOMSTR.py b/test/CXX/SHCXXCOMSTR.py index ad3a907..33beae7 100644 --- a/test/CXX/SHCXXCOMSTR.py +++ b/test/CXX/SHCXXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(SHCXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHCXXCOMSTR = 'Building shared object $TARGET from $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.cpp') diff --git a/test/CXX/SHCXXFLAGS.py b/test/CXX/SHCXXFLAGS.py index 88da443..049835c 100644 --- a/test/CXX/SHCXXFLAGS.py +++ b/test/CXX/SHCXXFLAGS.py @@ -29,15 +29,8 @@ import TestSCons import os import string -if sys.platform == 'win32': - _obj = '.obj' - fooflags = '/nologo -DFOO' - barflags = '/nologo -DBAR' -else: - _obj = '.o' - fooflags = '-DFOO' - barflags = '-DBAR' - +_obj = TestSCons._obj + if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' if string.find(sys.platform, 'irix') > -1: @@ -45,6 +38,10 @@ if string.find(sys.platform, 'irix') > -1: test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCXXFLAGS'] + ' -DFOO' +barflags = e['SHCXXFLAGS'] + ' -DBAR' + test.write('SConstruct', """ foo = Environment(SHCXXFLAGS = '%s', WINDOWS_INSERT_DEF=1) bar = Environment(SHCXXFLAGS = '%s', WINDOWS_INSERT_DEF=1) diff --git a/test/CacheDir.py b/test/CacheDir.py deleted file mode 100644 index 67d3ed4..0000000 --- a/test/CacheDir.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/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 retrieving derived files from a CacheDir. -""" - -import os.path -import shutil - -import TestSCons - -test = TestSCons.TestSCons() - -# cache2 omitted from list in order to test automatic creation of CacheDir -# directory. -test.subdir('cache1', 'cache3', 'src', 'subdir') - -test.write(['src', 'SConstruct'], """\ -CacheDir(r'%s') -SConscript('SConscript') -""" % test.workpath('cache1')) - -test.write(['src', 'SConscript'], """\ -def cat(env, source, target): - target = str(target[0]) - open('cat.out', 'ab').write(target + "\\n") - source = map(str, source) - f = open(target, "wb") - for src in source: - f.write(open(src, "rb").read()) - f.close() -env = Environment(BUILDERS={'Cat':Builder(action=cat)}) -env.Cat('aaa.out', 'aaa.in') -env.Cat('bbb.out', 'bbb.in') -env.Cat('ccc.out', 'ccc.in') -env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) -""") - -test.write(['src', 'aaa.in'], "aaa.in\n") -test.write(['src', 'bbb.in'], "bbb.in\n") -test.write(['src', 'ccc.in'], "ccc.in\n") - -############################################################################# - -# Verify that building with -n and an empty cache reports that proper -# build operations would be taken, but that nothing is actually built -# and that the cache is still empty. -test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ -cat(["aaa.out"], ["aaa.in"]) -cat(["bbb.out"], ["bbb.in"]) -cat(["ccc.out"], ["ccc.in"]) -cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""")) - -test.must_not_exist(test.workpath('src', 'aaa.out')) -test.must_not_exist(test.workpath('src', 'bbb.out')) -test.must_not_exist(test.workpath('src', 'ccc.out')) -test.must_not_exist(test.workpath('src', 'all')) -test.fail_test(len(os.listdir(test.workpath('cache1')))) - -# Verify that a normal build works correctly, and clean up. -# This should populate the cache with our derived files. -test.run(chdir = 'src', arguments = '.') - -test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_match(['src', 'cat.out'], "aaa.out\nbbb.out\nccc.out\nall\n") - -test.up_to_date(chdir = 'src', arguments = '.') - -test.run(chdir = 'src', arguments = '-c .') -test.unlink(['src', 'cat.out']) - -# Verify that we now retrieve the derived files from cache, -# not rebuild them. Then clean up. -test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ -Retrieved `aaa.out' from cache -Retrieved `bbb.out' from cache -Retrieved `ccc.out' from cache -Retrieved `all' from cache -""")) - -test.must_not_exist(test.workpath('src', 'cat.out')) - -test.up_to_date(chdir = 'src', arguments = '.') - -test.run(chdir = 'src', arguments = '-c .') - -# Verify that rebuilding with -n reports that everything was retrieved -# from the cache, but that nothing really was. -test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ -Retrieved `aaa.out' from cache -Retrieved `bbb.out' from cache -Retrieved `ccc.out' from cache -Retrieved `all' from cache -""")) - -test.must_not_exist(test.workpath('src', 'aaa.out')) -test.must_not_exist(test.workpath('src', 'bbb.out')) -test.must_not_exist(test.workpath('src', 'ccc.out')) -test.must_not_exist(test.workpath('src', 'all')) - -# Verify that rebuilding with -s retrieves everything from the cache -# even though it doesn't report anything. -test.run(chdir = 'src', arguments = '-s .', stdout = "") - -test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_not_exist(test.workpath('src', 'cat.out')) - -test.up_to_date(chdir = 'src', arguments = '.') - -test.run(chdir = 'src', arguments = '-c .') - -# Verify that updating one input file builds its derived file and -# dependency but that the other files are retrieved from cache. -test.write(['src', 'bbb.in'], "bbb.in 2\n") - -test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ -Retrieved `aaa.out' from cache -cat(["bbb.out"], ["bbb.in"]) -Retrieved `ccc.out' from cache -cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""")) - -test.must_match(['src', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") -test.must_match(['src', 'cat.out'], "bbb.out\nall\n") - -test.up_to_date(chdir = 'src', arguments = '.') - -############################################################################# -# Now we try out BuildDir() functionality. -# This is largely cut-and-paste of the above, -# with appropriate directory modifications. - -build_aaa_out = os.path.join('build', 'aaa.out') -build_bbb_out = os.path.join('build', 'bbb.out') -build_ccc_out = os.path.join('build', 'ccc.out') -build_all = os.path.join('build', 'all') - -# First, clean up the source directory and start over with fresh files. -test.run(chdir = 'src', arguments = '-c .') - -test.write(['src', 'aaa.in'], "aaa.in\n") -test.write(['src', 'bbb.in'], "bbb.in\n") -test.write(['src', 'ccc.in'], "ccc.in\n") - -# -test.write('SConstruct', """\ -env = Environment(TWO = '2') -env.CacheDir(r'%s') -BuildDir('build', 'src', duplicate=0) -SConscript('build/SConscript') -""" % test.workpath('cache${TWO}')) - -# Verify that a normal build works correctly, and clean up. -# This should populate the cache with our derived files. -test.run() - -test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_match('cat.out', "%s\n%s\n%s\n%s\n" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)) - -test.up_to_date(arguments = '.') - -test.run(arguments = '-c .') -test.unlink('cat.out') - -# Verify that we now retrieve the derived files from cache, -# not rebuild them. Then clean up. -test.run(stdout = test.wrap_stdout("""\ -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) - -test.must_not_exist(test.workpath('cat.out')) - -test.up_to_date(arguments = '.') - -test.run(arguments = '-c .') - -# Verify that rebuilding with -n reports that everything was retrieved -# from the cache, but that nothing really was. -test.run(arguments = '-n .', stdout = test.wrap_stdout("""\ -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) - -test.must_not_exist(test.workpath('build', 'aaa.out')) -test.must_not_exist(test.workpath('build', 'bbb.out')) -test.must_not_exist(test.workpath('build', 'ccc.out')) -test.must_not_exist(test.workpath('build', 'all')) - -# Verify that rebuilding with -s retrieves everything from the cache -# even though it doesn't report anything. -test.run(arguments = '-s .', stdout = "") - -test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_not_exist(test.workpath('cat.out')) - -test.up_to_date(arguments = '.') - -test.run(arguments = '-c .') - -# Verify that updating one input file builds its derived file and -# dependency but that the other files are retrieved from cache. -test.write(['src', 'bbb.in'], "bbb.in 2\n") - -test.run(stdout = test.wrap_stdout("""\ -Retrieved `%s' from cache -cat(["%s"], ["%s"]) -Retrieved `%s' from cache -cat(["%s"], ["%s", "%s", "%s"]) -""" % (build_aaa_out, - build_bbb_out, os.path.join('src', 'bbb.in'), - build_ccc_out, - build_all, build_aaa_out, build_bbb_out, build_ccc_out))) - -test.must_match(['build', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") -test.must_match('cat.out', "%s\n%s\n" % (build_bbb_out, build_all)) - -test.up_to_date(arguments = '.') - -############################################################################# -# Test the case (reported by Jeff Petkau, bug #694744) where a target -# is source for another target with a scanner, which used to cause us -# to push the file to the CacheDir after the build signature had already -# been cleared (as a sign that the built file should now be rescanned). - -test.write(['subdir', 'SConstruct'], """\ -import SCons - -CacheDir(r'%s') - -def docopy(target,source,env): - data = source[0].get_contents() - f = open(target[0].rfile().get_abspath(), "wb") - f.write(data) - f.close() - -def sillyScanner(node, env, dirs): - print 'This is never called (unless we build file.out)' - return [] - -SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res']) - -env = Environment(tools=[], - SCANNERS = [SillyScanner], - BUILDERS = {}) - -r = env.Command('file.res', 'file.ma', docopy) - -env.Command('file.out', r, docopy) - -# make r the default. Note that we don't even try to build file.out, -# and so SillyScanner never runs. The bug is the same if we build -# file.out, though. -Default(r) -""" % test.workpath('cache3')) - -test.write(['subdir', 'file.ma'], "subdir/file.ma\n") - -test.run(chdir = 'subdir') - -test.must_not_exist(test.workpath('cache3', 'N', 'None')) - -############################################################################# -# Test that multiple target files get retrieved from cache correctly. - -test.subdir('multiple', 'cache4') - -test.write(['multiple', 'SConstruct'], """\ -def touch(env, source, target): - open('foo', 'w').write("") - open('bar', 'w').write("") -CacheDir(r'%s') -env = Environment() -env.Command(['foo', 'bar'], ['input'], touch) -""" % (test.workpath('cache4'))) - -test.write(['multiple', 'input'], "multiple/input\n") - -test.run(chdir = 'multiple') - -test.must_exist(test.workpath('multiple', 'foo')) -test.must_exist(test.workpath('multiple', 'bar')) - -test.run(chdir = 'multiple', arguments = '-c') - -test.must_not_exist(test.workpath('multiple', 'foo')) -test.must_not_exist(test.workpath('multiple', 'bar')) - -test.run(chdir = 'multiple') - -test.must_exist(test.workpath('multiple', 'foo')) -test.must_exist(test.workpath('multiple', 'bar')) - -# All done. -test.pass_test() diff --git a/test/CacheDir/BuildDir.py b/test/CacheDir/BuildDir.py new file mode 100644 index 0000000..d03bfa6 --- /dev/null +++ b/test/CacheDir/BuildDir.py @@ -0,0 +1,153 @@ +#!/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 retrieving derived files from a CacheDir when a BuildDir is used. +""" + +import os.path + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('cache', 'src') + +cache = test.workpath('cache') +cat_out = test.workpath('cat.out') + +test.write(['src', 'SConstruct'], """\ +CacheDir(r'%(cache)s') +SConscript('SConscript') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +def cat(env, source, target): + target = str(target[0]) + open('cat.out', 'ab').write(target + "\\n") + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +build_aaa_out = os.path.join('build', 'aaa.out') +build_bbb_out = os.path.join('build', 'bbb.out') +build_ccc_out = os.path.join('build', 'ccc.out') +build_all = os.path.join('build', 'all') + +test.write(['src', 'aaa.in'], "aaa.in\n") +test.write(['src', 'bbb.in'], "bbb.in\n") +test.write(['src', 'ccc.in'], "ccc.in\n") + +# +test.write('SConstruct', """\ +env = Environment(TWO = '2') +env.CacheDir(r'%s') +BuildDir('build', 'src', duplicate=0) +SConscript('build/SConscript') +""" % test.workpath('cache${TWO}')) + +# Verify that a normal build works correctly, and clean up. +# This should populate the cache with our derived files. +test.run() + +test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_match('cat.out', "%s\n%s\n%s\n%s\n" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)) + +test.up_to_date(arguments = '.') + +test.run(arguments = '-c .') +test.unlink('cat.out') + +# Verify that we now retrieve the derived files from cache, +# not rebuild them. Then clean up. +test.run(stdout = test.wrap_stdout("""\ +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) + +test.must_not_exist(cat_out) + +test.up_to_date(arguments = '.') + +test.run(arguments = '-c .') + +# Verify that rebuilding with -n reports that everything was retrieved +# from the cache, but that nothing really was. +test.run(arguments = '-n .', stdout = test.wrap_stdout("""\ +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) + +test.must_not_exist(test.workpath('build', 'aaa.out')) +test.must_not_exist(test.workpath('build', 'bbb.out')) +test.must_not_exist(test.workpath('build', 'ccc.out')) +test.must_not_exist(test.workpath('build', 'all')) + +# Verify that rebuilding with -s retrieves everything from the cache +# even though it doesn't report anything. +test.run(arguments = '-s .', stdout = "") + +test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_not_exist(cat_out) + +test.up_to_date(arguments = '.') + +test.run(arguments = '-c .') + +# Verify that updating one input file builds its derived file and +# dependency but that the other files are retrieved from cache. +test.write(['src', 'bbb.in'], "bbb.in 2\n") + +test.run(stdout = test.wrap_stdout("""\ +Retrieved `%s' from cache +cat(["%s"], ["%s"]) +Retrieved `%s' from cache +cat(["%s"], ["%s", "%s", "%s"]) +""" % (build_aaa_out, + build_bbb_out, os.path.join('src', 'bbb.in'), + build_ccc_out, + build_all, build_aaa_out, build_bbb_out, build_ccc_out))) + +test.must_match(['build', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") +test.must_match('cat.out', "%s\n%s\n" % (build_bbb_out, build_all)) + +test.up_to_date(arguments = '.') + + + +test.pass_test() diff --git a/test/CacheDir/CacheDir.py b/test/CacheDir/CacheDir.py new file mode 100644 index 0000000..f918707 --- /dev/null +++ b/test/CacheDir/CacheDir.py @@ -0,0 +1,157 @@ +#!/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 retrieving derived files from a CacheDir. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +cache = test.workpath('cache') + +src_aaa_out = test.workpath('src', 'aaa.out') +src_bbb_out = test.workpath('src', 'bbb.out') +src_ccc_out = test.workpath('src', 'ccc.out') +src_cat_out = test.workpath('src', 'cat.out') +src_all = test.workpath('src', 'all') + +test.subdir('cache', 'src') + +test.write(['src', 'SConstruct'], """\ +CacheDir(r'%(cache)s') +SConscript('SConscript') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +def cat(env, source, target): + target = str(target[0]) + open('cat.out', 'ab').write(target + "\\n") + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +test.write(['src', 'aaa.in'], "aaa.in\n") +test.write(['src', 'bbb.in'], "bbb.in\n") +test.write(['src', 'ccc.in'], "ccc.in\n") + +# Verify that building with -n and an empty cache reports that proper +# build operations would be taken, but that nothing is actually built +# and that the cache is still empty. +test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ +cat(["aaa.out"], ["aaa.in"]) +cat(["bbb.out"], ["bbb.in"]) +cat(["ccc.out"], ["ccc.in"]) +cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) +""")) + +test.must_not_exist(src_aaa_out) +test.must_not_exist(src_bbb_out) +test.must_not_exist(src_ccc_out) +test.must_not_exist(src_all) +test.fail_test(len(os.listdir(cache))) + +# Verify that a normal build works correctly, and clean up. +# This should populate the cache with our derived files. +test.run(chdir = 'src', arguments = '.') + +test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_match(['src', 'cat.out'], "aaa.out\nbbb.out\nccc.out\nall\n") + +test.up_to_date(chdir = 'src', arguments = '.') + +test.run(chdir = 'src', arguments = '-c .') +test.unlink(['src', 'cat.out']) + +# Verify that we now retrieve the derived files from cache, +# not rebuild them. Then clean up. +test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ +Retrieved `aaa.out' from cache +Retrieved `bbb.out' from cache +Retrieved `ccc.out' from cache +Retrieved `all' from cache +""")) + +test.must_not_exist(src_cat_out) + +test.up_to_date(chdir = 'src', arguments = '.') + +test.run(chdir = 'src', arguments = '-c .') + +# Verify that rebuilding with -n reports that everything was retrieved +# from the cache, but that nothing really was. +test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ +Retrieved `aaa.out' from cache +Retrieved `bbb.out' from cache +Retrieved `ccc.out' from cache +Retrieved `all' from cache +""")) + +test.must_not_exist(src_aaa_out) +test.must_not_exist(src_bbb_out) +test.must_not_exist(src_ccc_out) +test.must_not_exist(src_all) + +# Verify that rebuilding with -s retrieves everything from the cache +# even though it doesn't report anything. +test.run(chdir = 'src', arguments = '-s .', stdout = "") + +test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_not_exist(src_cat_out) + +test.up_to_date(chdir = 'src', arguments = '.') + +test.run(chdir = 'src', arguments = '-c .') + +# Verify that updating one input file builds its derived file and +# dependency but that the other files are retrieved from cache. +test.write(['src', 'bbb.in'], "bbb.in 2\n") + +test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ +Retrieved `aaa.out' from cache +cat(["bbb.out"], ["bbb.in"]) +Retrieved `ccc.out' from cache +cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) +""")) + +test.must_match(['src', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") +test.must_match(['src', 'cat.out'], "bbb.out\nall\n") + +test.up_to_date(chdir = 'src', arguments = '.') + + +test.pass_test() diff --git a/test/CacheDir/SideEffect.py b/test/CacheDir/SideEffect.py new file mode 100644 index 0000000..814a5e3 --- /dev/null +++ b/test/CacheDir/SideEffect.py @@ -0,0 +1,107 @@ +#!/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 that use of SideEffect() doesn't interfere with CacheDir. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('cache', 'work') + +cache = test.workpath('cache') + +test.write(['work', 'SConstruct'], """\ +def copy(source, target): + open(target, "wb").write(open(source, "rb").read()) + +def build(env, source, target): + s = str(source[0]) + t = str(target[0]) + copy(s, t) + if target[0].side_effects: + side_effect = open(str(target[0].side_effects[0]), "ab") + side_effect.write(s + ' -> ' + t + '\\n') + +CacheDir(r'%(cache)s') + +Build = Builder(action=build) +env = Environment(BUILDERS={'Build':Build}, SUBDIR='subdir') +env.Build('f1.out', 'f1.in') +env.Build('f2.out', 'f2.in') +env.Build('f3.out', 'f3.in') +SideEffect('log.txt', ['f1.out', 'f2.out', 'f3.out']) +""" % locals()) + +test.write(['work', 'f1.in'], 'f1.in\n') +test.write(['work', 'f2.in'], 'f2.in\n') +test.write(['work', 'f3.in'], 'f3.in\n') + +test.run(chdir='work', arguments='f1.out f2.out') + +expect = """\ +f1.in -> f1.out +f2.in -> f2.out +""" + +test.must_match(['work', 'log.txt'], expect) + + + +test.write(['work', 'f2.in'], 'f2.in 2 \n') + +test.run(chdir='work', arguments='log.txt') + +expect = """\ +f1.in -> f1.out +f2.in -> f2.out +f2.in -> f2.out +f3.in -> f3.out +""" + +test.must_match(['work', 'log.txt'], expect) + + + +test.write(['work', 'f1.in'], 'f1.in 2 \n') + +test.run(chdir='work', arguments=".") + +expect = """\ +f1.in -> f1.out +f2.in -> f2.out +f2.in -> f2.out +f3.in -> f3.out +f1.in -> f1.out +""" + +test.must_match(['work', 'log.txt'], expect) + + + +test.pass_test() diff --git a/test/CacheDir/debug.py b/test/CacheDir/debug.py new file mode 100644 index 0000000..ebf67f7 --- /dev/null +++ b/test/CacheDir/debug.py @@ -0,0 +1,177 @@ +#!/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 the --cache-debug option to see if it prints the expected messages. + +Note that we don't check for the "race condition" message when someone +else's build populates the CacheDir with a file in between the time we +to build it because it doesn't exist in the CacheDir, and the time our +build of the file completes and we push it out. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons(match=TestSCons.match_re) + +test.subdir('cache', 'src') + +cache = test.workpath('cache') +debug_out = test.workpath('cache-debug.out') + + + +test.write(['src', 'SConstruct'], """\ +CacheDir(r'%(cache)s') +SConscript('SConscript') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +def cat(env, source, target): + target = str(target[0]) + open('cat.out', 'ab').write(target + "\\n") + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +test.write(['src', 'aaa.in'], "aaa.in\n") +test.write(['src', 'bbb.in'], "bbb.in\n") +test.write(['src', 'ccc.in'], "ccc.in\n") + + + +# Test for messages about files not being in CacheDir, with -n (don't +# actually build or push) and sendinig the message to a file. + +expect = \ +r"""cat\(\["aaa.out"\], \["aaa.in"\]\) +cat\(\["bbb.out"\], \["bbb.in"\]\) +cat\(\["ccc.out"\], \["ccc.in"\]\) +cat\(\["all"\], \["aaa.out", "bbb.out", "ccc.out"\]\) +""" + +test.run(chdir='src', + arguments='-n -Q --cache-debug=%s .' % debug_out, + stdout=expect) + +expect = \ +r"""CacheRetrieve\(aaa.out\): [0-9a-fA-F]+ not in cache +CacheRetrieve\(bbb.out\): [0-9a-fA-F]+ not in cache +CacheRetrieve\(ccc.out\): [0-9a-fA-F]+ not in cache +CacheRetrieve\(all\): [0-9a-fA-F]+ not in cache +""" + +test.must_match(debug_out, expect, mode='r') + + + +# Test for messages about actually pushing to the cache, without -n +# and to standard ouput. + +expect = \ +r"""CacheRetrieve\(aaa.out\): [0-9a-fA-F]+ not in cache +cat\(\["aaa.out"\], \["aaa.in"\]\) +CachePush\(aaa.out\): pushing to [0-9a-fA-F]+ +CacheRetrieve\(bbb.out\): [0-9a-fA-F]+ not in cache +cat\(\["bbb.out"\], \["bbb.in"\]\) +CachePush\(bbb.out\): pushing to [0-9a-fA-F]+ +CacheRetrieve\(ccc.out\): [0-9a-fA-F]+ not in cache +cat\(\["ccc.out"\], \["ccc.in"\]\) +CachePush\(ccc.out\): pushing to [0-9a-fA-F]+ +CacheRetrieve\(all\): [0-9a-fA-F]+ not in cache +cat\(\["all"\], \["aaa.out", "bbb.out", "ccc.out"\]\) +CachePush\(all\): pushing to [0-9a-fA-F]+ +""" + +test.run(chdir='src', + arguments='-Q --cache-debug=- .', + stdout=expect) + + + +# Clean up the local targets. + +test.run(chdir='src', arguments='-c --cache-debug=%s .' % debug_out) +test.unlink(['src', 'cat.out']) + + + +# Test for messages about retrieving files from CacheDir, with -n +# and sending the messages to standard output. + +expect = \ +r"""Retrieved `aaa.out' from cache +CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+ +Retrieved `bbb.out' from cache +CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+ +Retrieved `ccc.out' from cache +CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+ +Retrieved `all' from cache +CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+ +""" + +test.run(chdir='src', + arguments='-n -Q --cache-debug=- .', + stdout=expect) + + + +# And finally test for message about retrieving file from CacheDir +# *without* -n and sending the message to a file. + +expect = \ +r"""Retrieved `aaa.out' from cache +Retrieved `bbb.out' from cache +Retrieved `ccc.out' from cache +Retrieved `all' from cache +""" + +test.run(chdir='src', + arguments='-Q --cache-debug=%s .' % debug_out, + stdout=expect) + +expect = \ +r"""CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+ +CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+ +CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+ +CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+ +""" + +test.must_match(debug_out, expect, mode='r') + + + +test.pass_test() diff --git a/test/CacheDir/multi-targets.py b/test/CacheDir/multi-targets.py new file mode 100644 index 0000000..0de0331 --- /dev/null +++ b/test/CacheDir/multi-targets.py @@ -0,0 +1,70 @@ +#!/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 that multiple target files get retrieved from a CacheDir correctly. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('cache', 'multiple') + +cache = test.workpath('cache') + +multiple_bar = test.workpath('multiple', 'bar') +multiple_foo = test.workpath('multiple', 'foo') + +test.write(['multiple', 'SConstruct'], """\ +def touch(env, source, target): + open('foo', 'w').write("") + open('bar', 'w').write("") +CacheDir(r'%(cache)s') +env = Environment() +env.Command(['foo', 'bar'], ['input'], touch) +""" % locals()) + +test.write(['multiple', 'input'], "multiple/input\n") + +test.run(chdir = 'multiple') + +test.must_exist(multiple_foo) +test.must_exist(multiple_bar) + +test.run(chdir = 'multiple', arguments = '-c') + +test.must_not_exist(multiple_foo) +test.must_not_exist(multiple_bar) + +test.run(chdir = 'multiple') + +test.must_exist(multiple_foo) +test.must_exist(multiple_bar) + + + +test.pass_test() diff --git a/test/CacheDir/source-scanner.py b/test/CacheDir/source-scanner.py new file mode 100644 index 0000000..119a959 --- /dev/null +++ b/test/CacheDir/source-scanner.py @@ -0,0 +1,84 @@ +#!/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 retrieving derived files from a CacheDir. + +This tests the case reported by Jeff Petkau (SourceForge bug #694744) +where a target is source for another target with a scanner, which used +to cause us to push the file to the CacheDir after the build signature +had already been cleared (as a sign that the built file should now +be rescanned). +""" + +import TestSCons + +test = TestSCons.TestSCons() + +cache = test.workpath('cache') + +test.subdir('cache', 'subdir') + +test.write(['subdir', 'SConstruct'], """\ +import SCons + +CacheDir(r'%(cache)s') + +def docopy(target,source,env): + data = source[0].get_contents() + f = open(target[0].rfile().get_abspath(), "wb") + f.write(data) + f.close() + +def sillyScanner(node, env, dirs): + print 'This is never called (unless we build file.out)' + return [] + +SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res']) + +env = Environment(tools=[], + SCANNERS = [SillyScanner], + BUILDERS = {}) + +r = env.Command('file.res', 'file.ma', docopy) + +env.Command('file.out', r, docopy) + +# make r the default. Note that we don't even try to build file.out, +# and so SillyScanner never runs. The bug is the same if we build +# file.out, though. +Default(r) +""" % locals()) + +test.write(['subdir', 'file.ma'], "subdir/file.ma\n") + +test.run(chdir = 'subdir') + +test.must_not_exist(test.workpath(cache, 'N', 'None')) + + + +test.pass_test() diff --git a/test/Case.py b/test/Case.py index 18fb60a..9b6bb94 100644 --- a/test/Case.py +++ b/test/Case.py @@ -40,6 +40,8 @@ Program('main', [ """) test.write('main.c', """\ +#include <stdlib.h> + void foo(); void bar(); int main() { diff --git a/test/Command.py b/test/Command.py index 6563bd9..09c51ab 100644 --- a/test/Command.py +++ b/test/Command.py @@ -28,6 +28,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,30 +66,30 @@ def sub(env, target, source): t.close() return 0 -env = Environment(COPY_THROUGH_TEMP = "%(python)s build.py .tmp $SOURCE\\n%(python)s build.py $TARGET .tmp", - EXPAND = "$COPY_THROUGH_TEMP") +env = Environment(COPY_THROUGH_TEMP = '%(_python_)s build.py .tmp $SOURCE\\n%(_python_)s build.py $TARGET .tmp', + EXPAND = '$COPY_THROUGH_TEMP') env.Command(target = 'f1.out', source = 'f1.in', action = buildIt) env.Command(target = 'f2.out', source = 'f2.in', - action = r"%(python)s build.py temp2 $SOURCES" + '\\n' + r"%(python)s build.py $TARGET temp2") + action = r'%(_python_)s build.py temp2 $SOURCES' + '\\n' + r'%(_python_)s build.py $TARGET temp2') env.Command(target = 'f3.out', source = 'f3.in', action = [ [ r'%(python)s', 'build.py', 'temp3', '$SOURCES' ], [ r'%(python)s', 'build.py', '$TARGET', 'temp3'] ]) Command(target = 'f4.out', source = 'sub', action = sub) env.Command(target = 'f5.out', source = 'f5.in', action = buildIt, - XYZZY="XYZZY is set") + XYZZY='XYZZY is set') Command(target = 'f6.out', source = 'f6.in', - action = r"%(python)s build.py f6.out f6.in") + action = r'%(_python_)s build.py f6.out f6.in') env.Command(target = 'f7.out', source = 'f7.in', - action = r"%(python)s build.py $TARGET $SOURCE") + action = r'%(_python_)s build.py $TARGET $SOURCE') Command(target = 'f8.out', source = 'f8.in', - action = r"%(python)s build.py $TARGET $SOURCE") + action = r'%(_python_)s build.py $TARGET $SOURCE') env.Command(target = 'f9.out', source = 'f9.in', - action = r"$EXPAND") + action = r'$EXPAND') env.Command(target = '${F10}.out', source = '${F10}.in', - action = r"%(python)s build.py $TARGET $SOURCE", + action = r'%(_python_)s build.py $TARGET $SOURCE', F10 = 'f10') -""" % {'python': python}) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") diff --git a/test/CommandGenerator.py b/test/CommandGenerator.py index 4a99be8..947ad42 100644 --- a/test/CommandGenerator.py +++ b/test/CommandGenerator.py @@ -44,7 +44,7 @@ sys.exit(0) test.write('SConstruct', """ def g(source, target, for_signature, env): import sys - python = r"%s" + python = r'%(python)s' return [[python, "build.py", "$TEMPFILE"] + source, [python, "build.py"] + target + ["$TEMPFILE"]] @@ -54,7 +54,7 @@ env = Environment(BUILDERS = { 'b' : b }, env.b(target = 'foo1.out', source = 'foo1.in') env.b(target = 'foo2.out', source = 'foo2.in') env.b(target = 'foo3.out', source = 'foo3.in') -""" % python) +""" % locals()) test.write('foo1.in', "foo1.in\n") diff --git a/test/Configure/CONFIGUREDIR.py b/test/Configure/CONFIGUREDIR.py index 2064886..ae1ea2b 100644 --- a/test/Configure/CONFIGUREDIR.py +++ b/test/Configure/CONFIGUREDIR.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation +# __COPYRIGHT__ # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -22,7 +22,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "test/Configure.py 0.96.D308 2005/09/25 12:59:35 knight" +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test that the configure context directory can be specified by diff --git a/test/Configure/CONFIGURELOG.py b/test/Configure/CONFIGURELOG.py index 456fcc9..4b63440 100644 --- a/test/Configure/CONFIGURELOG.py +++ b/test/Configure/CONFIGURELOG.py @@ -33,7 +33,9 @@ import TestSCons test = TestSCons.TestSCons() -test.write("SConstruct", """\ +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """\ def CustomTest(context): context.Message('Executing Custom Test ...') context.Result(1) @@ -47,13 +49,13 @@ env = conf.Finish() test.run() expect = """\ -file SConstruct,line 6: +file %(SConstruct_path)s,line 6: \tConfigure(confdir = .sconf_temp) scons: Configure: Executing Custom Test ... scons: Configure: (cached) yes -""" +""" % locals() test.must_match('custom.logfile', expect, mode='r') diff --git a/test/Configure/Configure.py b/test/Configure/Configure.py index 41c858b..4063699 100644 --- a/test/Configure/Configure.py +++ b/test/Configure/Configure.py @@ -55,6 +55,7 @@ else: work_cnt = 0 work_dir = None python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _obj = TestSCons._obj _exe = TestSCons._exe @@ -123,7 +124,7 @@ def checkLogAndStdout(checks, results, cached, sconf_dir = sconf_dir sconstruct = sconstruct - log = re.escape("file " + sconstruct + ",line ") + r"\d+:" + ls + log = r'file\ \S*%s\,line \d+:' % re.escape(sconstruct) + ls if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) log = "\t" + re.escape("Configure(confdir = %s)" % sconf_dir) + ls if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) @@ -615,9 +616,9 @@ def CustomTest(*args): return 0 conf = env.Configure(custom_tests = {'MyTest' : CustomTest}) if not conf.MyTest(): - env.Command("hello", [], "%s cmd.py $TARGET") + env.Command("hello", [], '%(_python_)s cmd.py $TARGET') env = conf.Finish() -""" % python) +""" % locals()) test.run(chdir=work_dir, stderr="Hello World on stderr\n") # 4.2 test that calling Configure from a builder results in a @@ -673,7 +674,10 @@ conf.Finish() # 5.1 test the ConfigureDryRunError reset(EXACT) # exact match - test.write([work_dir, 'SConstruct'], """ + + SConstruct_path = test.workpath(work_dir, 'SConstruct') + + test.write(SConstruct_path, """ env = Environment() import os env.AppendENVPath('PATH', os.environ['PATH']) @@ -687,15 +691,17 @@ if not (r1 and not r2): test.run(chdir=work_dir, arguments='-n', status=2, stderr=""" scons: *** Cannot create configure directory ".sconf_temp" within a dry-run. -File "SConstruct", line 5, in ? -""") +File "%(SConstruct_path)s", line 5, in ? +""" % locals()) test.must_not_exist([work_dir, 'config.log']) test.subdir([work_dir, '.sconf_temp']) + + conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") test.run(chdir=work_dir, arguments='-n', status=2, stderr=""" -scons: *** Cannot update configure test "%s" within a dry-run. -File "SConstruct", line 6, in ? -""" % os.path.join(".sconf_temp", "conftest_0.c")) +scons: *** Cannot update configure test "%(conftest_0_c)s" within a dry-run. +File "%(SConstruct_path)s", line 6, in ? +""" % locals()) test.run(chdir=work_dir) checkLogAndStdout( ["Checking for C library %s... " % lib, @@ -722,7 +728,9 @@ File "SConstruct", line 6, in ? # 5.2 test the --config=<auto|force|cache> option reset(EXACT) # exact match - test.write([work_dir, 'SConstruct'], """ + SConstruct_path = test.workpath(work_dir, 'SConstruct') + + test.write(SConstruct_path, """ env = Environment(CPPPATH='#/include') import os env.AppendENVPath('PATH', os.environ['PATH']) @@ -736,10 +744,12 @@ env = conf.Finish() /* A header */ """) + conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") + test.run(chdir=work_dir, arguments='--config=cache', status=2, stderr=""" -scons: *** "%s" is not yet built and cache is forced. -File "SConstruct", line 6, in ? -""" % os.path.join(".sconf_temp", "conftest_0.c")) +scons: *** "%(conftest_0_c)s" is not yet built and cache is forced. +File "%(SConstruct_path)s", line 6, in ? +""" % locals()) test.run(chdir=work_dir, arguments='--config=auto') checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", diff --git a/test/DSUFFIXES.py b/test/DSUFFIXES.py index 9a5a55a..a344112 100644 --- a/test/DSUFFIXES.py +++ b/test/DSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $DSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,7 +57,7 @@ env = Environment() Tool('dmd')(env) # Now replace those suffixes with our fake-D things. env.Replace(DPATH = ['.'], - DC = r'%s mydc.py', + DC = r'%(_python_)s mydc.py', DFLAGS = [], DCOM = '$DC $TARGET $SOURCES', OBJSUFFIX = '.o') @@ -66,7 +66,7 @@ env.Object(target = 'test1', source = 'test1.d') env.InstallAs('test1_d', 'test1.d') env.InstallAs('test2_d', 'test2.d') env.InstallAs('test3_d', 'test3.d') -""" % (python,)) +""" % locals()) test.write('test1.d', """\ test1.d 1 @@ -86,12 +86,14 @@ import foo; test.write('foo.d', "foo.d 1\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d Install file: "test1.d" as "test1_d" Install file: "test2.d" as "test2_d" Install file: "test3.d" as "test3_d" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 @@ -105,9 +107,11 @@ test.up_to_date(arguments='.') test.write('foo.d', "foo.d 2\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d -""" % (python,))) +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 @@ -124,10 +128,12 @@ test3.d 2 import foo; """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d Install file: "test3.d" as "test3_d" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 @@ -144,10 +150,12 @@ test2.d 2 import foo; """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d Install file: "test2.d" as "test2_d" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 diff --git a/test/DVIPDF/DVIPDF.py b/test/DVIPDF/DVIPDF.py index 8db5785..8d36e5a 100644 --- a/test/DVIPDF/DVIPDF.py +++ b/test/DVIPDF/DVIPDF.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -72,15 +72,15 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPDF = r'%s mydvipdf.py', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPDF = r'%(_python_)s mydvipdf.py', tools=['latex', 'tex', 'dvipdf']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.DVI(target = 'test2.dvi', source = 'test2.tex') env.PDF(target = 'test1.pdf', source = dvi) env.PDF(target = 'test2.pdf', source = 'test2.dvi') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -118,13 +118,13 @@ import os foo = Environment(ENV = { 'PATH' : os.environ['PATH'] }) dvipdf = foo.Dictionary('DVIPDF') bar = Environment(ENV = { 'PATH' : os.environ['PATH'] }, - DVIPDF = r'%s wrapper.py ' + dvipdf) + DVIPDF = r'%(_python_)s wrapper.py ' + dvipdf) foo.PDF(target = 'foo.pdf', source = foo.DVI(target = 'foo.dvi', source = 'foo.tex')) bar.PDF(target = 'bar.pdf', source = bar.DVI(target = 'bar.dvi', source = 'bar.tex')) foo.PDF(target = 'xxx.pdf', source = 'xxx.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPDF/DVIPDFCOM.py b/test/DVIPDF/DVIPDFCOM.py index 61d5ce7..0d9cd8d 100644 --- a/test/DVIPDF/DVIPDFCOM.py +++ b/test/DVIPDF/DVIPDFCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $DVIPDFCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvipdf'], - DVIPDFCOM = r'%s mypdf.py $TARGET $SOURCES') + DVIPDFCOM = r'%(_python_)s mypdf.py $TARGET $SOURCES') env.PDF(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*pdf*/\n") diff --git a/test/DVIPDF/DVIPDFCOMSTR.py b/test/DVIPDF/DVIPDFCOMSTR.py index 6e57adb..cc0c909 100644 --- a/test/DVIPDF/DVIPDFCOMSTR.py +++ b/test/DVIPDF/DVIPDFCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvipdf'], - DVIPDFCOM = r'%s mypdf.py $TARGET $SOURCES', + DVIPDFCOM = r'%(_python_)s mypdf.py $TARGET $SOURCES', DVIPDFCOMSTR = 'DVIPDFing $TARGET from $SOURCE') env.PDF(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*pdf*/\n") diff --git a/test/DVIPDF/DVIPDFFLAGS.py b/test/DVIPDF/DVIPDFFLAGS.py index e9bd8ba..4268705 100644 --- a/test/DVIPDF/DVIPDFFLAGS.py +++ b/test/DVIPDF/DVIPDFFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -78,15 +78,15 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPDF = r'%s mydvipdf.py', DVIPDFFLAGS = '-x', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPDF = r'%(_python_)s mydvipdf.py', DVIPDFFLAGS = '-x', tools = ['tex', 'latex', 'dvipdf']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.DVI(target = 'test2.dvi', source = 'test2.tex') env.PDF(target = 'test1.pdf', source = dvi) env.PDF(target = 'test2.pdf', source = 'test2.dvi') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -124,13 +124,13 @@ import os ENV = {'PATH' : os.environ['PATH']} foo = Environment(DVIPDFFLAGS = '-N', ENV = ENV) dvipdf = foo.Dictionary('DVIPDF') -bar = Environment(DVIPDF = r'%s wrapper.py ' + dvipdf, ENV = ENV) +bar = Environment(DVIPDF = r'%(_python_)s wrapper.py ' + dvipdf, ENV = ENV) foo.PDF(target = 'foo.pdf', source = foo.DVI(target = 'foo.dvi', source = 'foo.tex')) bar.PDF(target = 'bar.pdf', source = bar.DVI(target = 'bar.dvi', source = 'bar.tex')) foo.PDF(target = 'xxx.pdf', source = 'xxx.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPS/DVIPS.py b/test/DVIPS/DVIPS.py index 2ae856a..490ac95 100644 --- a/test/DVIPS/DVIPS.py +++ b/test/DVIPS/DVIPS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -72,16 +72,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPS = r'%s mydvips.py', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPS = r'%(_python_)s mydvips.py', tools=['tex', 'latex', 'dvips']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.PostScript(target = 'test1.ps', source = dvi) env.PostScript(target = 'test2.ps', source = 'test2.tex') env.PostScript(target = 'test3.ps', source = 'test3.ltx') env.PostScript(target = 'test4.ps', source = 'test4.latex') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -132,12 +132,12 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) dvips = foo.Dictionary('DVIPS') -bar = Environment(ENV = ENV, DVIPS = r'%s wrapper.py ' + dvips) +bar = Environment(ENV = ENV, DVIPS = r'%(_python_)s wrapper.py ' + dvips) foo.PostScript(target = 'foo.ps', source = 'foo.tex') bar.PostScript(target = 'bar1', source = 'bar1.tex') bar.PostScript(target = 'bar2', source = 'bar2.ltx') bar.PostScript(target = 'bar3', source = 'bar3.latex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPS/DVIPSFLAGS.py b/test/DVIPS/DVIPSFLAGS.py index 82e57c5..635acb0 100644 --- a/test/DVIPS/DVIPSFLAGS.py +++ b/test/DVIPS/DVIPSFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -79,16 +79,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPS = r'%s mydvips.py', DVIPSFLAGS = '-x', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPS = r'%(_python_)s mydvips.py', DVIPSFLAGS = '-x', tools=['tex', 'latex', 'dvips']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.PostScript(target = 'test1.ps', source = dvi) env.PostScript(target = 'test2.ps', source = 'test2.tex') env.PostScript(target = 'test3.ps', source = 'test3.ltx') env.PostScript(target = 'test4.ps', source = 'test4.latex') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -139,12 +139,12 @@ import os ENV = {'PATH' : os.environ['PATH']} foo = Environment(ENV = ENV, DVIPSFLAGS = '-N') dvips = foo.Dictionary('DVIPS') -bar = Environment(ENV = ENV,DVIPS = r'%s wrapper.py ' + dvips) +bar = Environment(ENV = ENV,DVIPS = r'%(_python_)s wrapper.py ' + dvips) foo.PostScript(target = 'foo.ps', source = 'foo.tex') bar.PostScript(target = 'bar1', source = 'bar1.tex') bar.PostScript(target = 'bar2', source = 'bar2.ltx') bar.PostScript(target = 'bar3', source = 'bar3.latex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPS/PSCOM.py b/test/DVIPS/PSCOM.py index 65e66a2..0d8408e 100644 --- a/test/DVIPS/PSCOM.py +++ b/test/DVIPS/PSCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $PSCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvips'], - PSCOM = r'%s myps.py $TARGET $SOURCES') + PSCOM = r'%(_python_)s myps.py $TARGET $SOURCES') env.PostScript(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*ps*/\n") diff --git a/test/DVIPS/PSCOMSTR.py b/test/DVIPS/PSCOMSTR.py index 9a565a4..67f960e 100644 --- a/test/DVIPS/PSCOMSTR.py +++ b/test/DVIPS/PSCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvips'], - PSCOM = r'%s myps.py $TARGET $SOURCES', + PSCOM = r'%(_python_)s myps.py $TARGET $SOURCES', PSCOMSTR = 'PostScripting $TARGET from $SOURCE') env.PostScript(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*ps*/\n") diff --git a/test/Default.py b/test/Default.py index cda34b2..22fd883 100644 --- a/test/Default.py +++ b/test/Default.py @@ -32,7 +32,7 @@ import os import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -54,44 +54,44 @@ file.close() # test.write(['one', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out') -""" % python) +""" % locals()) test.write(['two', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out', 'bar.out') -""" % python) +""" % locals()) test.write(['three', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default(Split('foo.out bar.out')) -""" % python) +""" % locals()) test.write(['four', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo bar'], source = 'foo.in') env.B(target = 'foo', source = 'foo.in') env.B(target = 'bar', source = 'bar.in') Default(['foo bar']) -""" % python) +""" % locals()) test.write(['five', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) Default(env.B(target = 'foo.out', source = 'foo.in')) Default(env.B(target = 'bar.out', source = 'bar.in')) -""" % python) +""" % locals()) for dir in ['one', 'two', 'three', 'four', 'five']: @@ -118,34 +118,34 @@ test.fail_test(test.read(test.workpath('five', 'bar.out')) != "five/bar.in\n") # Test how a None Default() argument works to disable/reset default targets. test.write(['six', 'SConstruct'], """\ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) foo = env.B(target = 'foo.out', source = 'foo.in') bar = env.B(target = 'bar.out', source = 'bar.in') Default(None) -""" % python) +""" % locals()) test.run(chdir = 'six', status = 2, stderr = "scons: *** No targets specified and no Default() targets found. Stop.\n") test.write(['seven', 'SConstruct'], """\ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) foo = env.B(target = 'foo.out', source = 'foo.in') bar = env.B(target = 'bar.out', source = 'bar.in') Default(foo, bar, None) -""" % python) +""" % locals()) test.run(chdir = 'seven', status = 2, stderr = "scons: *** No targets specified and no Default() targets found. Stop.\n") test.write(['eight', 'SConstruct'], """\ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) foo = env.B(target = 'foo.out', source = 'foo.in') bar = env.B(target = 'bar.out', source = 'bar.in') Default(foo, None, bar) -""" % python) +""" % locals()) test.run(chdir = 'eight') # no arguments, use the Default @@ -158,20 +158,20 @@ test.fail_test(test.read(test.workpath('eight', 'bar.out')) != "eight/bar.in\n") test.subdir('nine', ['nine', 'sub1']) test.write(['nine', 'SConstruct'], """\ -B = Builder(action = r'%s build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') SConscript('sub1/SConscript') -""" % python) +""" % locals()) test.write(['nine', 'xxx.in'], "xxx.in\n") test.write(['nine', 'sub1', 'SConscript'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') Default('xxx.out') -""" % python) +""" % locals()) test.write(['nine', 'sub1', 'xxx.in'], "sub1/xxx.in\n") @@ -186,19 +186,19 @@ test.subdir('ten', ['ten', 'sub2']) test.write(['ten', 'SConstruct'], """\ Default('sub2') -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') SConscript('sub2/SConscript') -""" % python) +""" % locals()) test.write(['ten', 'xxx.in'], "xxx.in\n") test.write(['ten', 'sub2', 'SConscript'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') -""" % python) +""" % locals()) test.write(['ten', 'sub2', 'xxx.in'], "sub2/xxx.in\n") @@ -211,12 +211,12 @@ test.fail_test(test.read(test.workpath('ten', 'sub2', 'xxx.out')) != "sub2/xxx.i test.subdir('eleven') test.write(['eleven', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }, XXX = 'foo.out') env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') env.Default('$XXX') -""" % python) +""" % locals()) test.write(os.path.join('eleven', 'foo.in'), "eleven/foo.in\n"); diff --git a/test/Depends.py b/test/Depends.py index 284d6f7..d0b2199 100644 --- a/test/Depends.py +++ b/test/Depends.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,12 +42,15 @@ file.write(contents) file.close() """) +SUBDIR_foo_dep = os.path.join('$SUBDIR', 'foo.dep') +SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out') + test.write('SConstruct', """ -Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep") -Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep") +Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep') +Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep') env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir') -env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%s') -env.Depends(target = r'%s', dependency = 'subdir/bar.dep') +env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%(SUBDIR_foo_dep)s') +env.Depends(target = r'%(SUBDIR_f3_out)s', dependency = 'subdir/bar.dep') env.Foo(target = 'f1.out', source = 'f1.in') env.Foo(target = 'f2.out', source = 'f2.in') env.Bar(target = 'subdir/f3.out', source = 'f3.in') @@ -55,10 +58,7 @@ SConscript('subdir/SConscript', "env") env.Foo(target = 'f5.out', source = 'f5.in') env.Bar(target = 'sub2/f6.out', source = 'f6.in') env.Depends(target = 'f5.out', dependency = 'sub2') -""" % (python, - python, - os.path.join('$SUBDIR', 'foo.dep'), - os.path.join('$SUBDIR', 'f3.out'))) +""" % locals()) test.write(['subdir', 'SConscript'], """ Import("env") diff --git a/test/ENV.py b/test/ENV.py index 98d04f9..9a39f30 100644 --- a/test/ENV.py +++ b/test/ENV.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -38,14 +38,14 @@ bin2_build_py = test.workpath('bin2', 'build.py') test.write('SConstruct', """ import os -Bld = Builder(action = r"%s build.py $TARGET $SOURCES") +Bld = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env1 = Environment(BUILDERS = { 'Bld' : Bld }) env2 = Environment(BUILDERS = { 'Bld' : Bld }) env1['ENV']['X'] = 'env1' env2['ENV']['X'] = 'env2' env1.Bld(target = 'env1.out', source = 'input') env2.Bld(target = 'env2.out', source = 'input') -""" % python) +""" % locals()) test.write('build.py', r"""#!/usr/bin/env python @@ -65,10 +65,10 @@ test.fail_test(test.read('env2.out') != "build.py env2\ninput file\n") test.write('SConstruct', """ env = Environment() -foo = env.Command('foo', [], r'%s build.py $TARGET') +foo = env.Command('foo', [], r'%(_python_)s build.py $TARGET') env['ENV']['LIST'] = [foo, 'bar'] env['ENV']['FOO'] = foo -"""%python) +""" % locals()) test.write('build.py', r""" diff --git a/test/ESCAPE.py b/test/ESCAPE.py index bee55bc..08f4a1a 100644 --- a/test/ESCAPE.py +++ b/test/ESCAPE.py @@ -30,7 +30,7 @@ Test the ESCAPE construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ def my_escape(s): s = string.replace(s, 'file.in', 'file.xxx') return orig_escape(s) env = Environment(ESCAPE = my_escape) -env.Command('file.out', 'file.in', "%(python)s cat.py $TARGET $SOURCES") +env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES') """ % locals()) test.write('file.in', "file.in\n") diff --git a/test/Environment.py b/test/Environment.py index 9851db7..36c72e1 100644 --- a/test/Environment.py +++ b/test/Environment.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import sys -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -35,7 +35,7 @@ test.write('SConstruct', """ env=Environment(BAR='#bar.in', BLAT='subdir/../blat blat') target = env.Command('foo.out', 'foo.in', - r'%s build.py $SOURCE $TARGET ${File(BAR)} ${Dir(BLAT)}') + r'%(_python_)s build.py $SOURCE $TARGET ${File(BAR)} ${Dir(BLAT)}') target = target[0] assert target == Dir('.').File('foo.out') @@ -45,7 +45,7 @@ assert target == target.File('foo.out') e2 = env.Environment(XXX='$BAR', YYY='$BLAT') print e2['XXX'] print e2['YYY'] -"""%python) +""" % locals()) test.write('build.py', """ import sys diff --git a/test/Execute.py b/test/Execute.py index 2637a6a..44abc73 100644 --- a/test/Execute.py +++ b/test/Execute.py @@ -30,7 +30,7 @@ Test the Execute() function for executing actions directly. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,25 +45,25 @@ sys.exit(exitval) """) test.write('SConstruct', """\ -Execute("%s my_copy.py a.in a.out") -Execute(Action("%s my_copy.py b.in b.out")) +Execute('%(_python_)s my_copy.py a.in a.out') +Execute(Action('%(_python_)s my_copy.py b.in b.out')) env = Environment(COPY = 'my_copy.py') -env.Execute("%s my_copy.py c.in c.out") -env.Execute(Action("%s my_copy.py d.in d.out")) -v = env.Execute("%s $COPY e.in e.out") +env.Execute('%(_python_)s my_copy.py c.in c.out') +env.Execute(Action('%(_python_)s my_copy.py d.in d.out')) +v = env.Execute('%(_python_)s $COPY e.in e.out') assert v == 0, v -v = env.Execute(Action("%s $COPY f.in f.out")) +v = env.Execute(Action('%(_python_)s $COPY f.in f.out')) assert v == 0, v -v = env.Execute("%s $COPY g.in g.out 1") +v = env.Execute('%(_python_)s $COPY g.in g.out 1') assert v == 1, v -v = env.Execute(Action("%s $COPY h.in h.out 2")) +v = env.Execute(Action('%(_python_)s $COPY h.in h.out 2')) assert v == 2, v import shutil Execute(lambda target, source, env: shutil.copy('i.in', 'i.out')) Execute(Action(lambda target, source, env: shutil.copy('j.in', 'j.out'))) env.Execute(lambda target, source, env: shutil.copy('k.in', 'k.out')) env.Execute(Action(lambda target, source, env: shutil.copy('l.in', 'l.out'))) -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('a.in', "a.in\n") test.write('b.in', "b.in\n") diff --git a/test/Fortran/F77.py b/test/Fortran/F77.py index 1c27def..682cfb0 100644 --- a/test/Fortran/F77.py +++ b/test/Fortran/F77.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -88,10 +88,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77 = r'%s myfortran.py g77', - FORTRAN = r'%s myfortran.py fortran') + F77 = r'%(_python_)s myfortran.py g77', + FORTRAN = r'%(_python_)s myfortran.py fortran') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -106,9 +106,9 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77 = r'%s myfortran.py g77') + F77 = r'%(_python_)s myfortran.py g77') env2.Program(target = 'test21', source = 'test21.f') env2.Program(target = 'test22', source = 'test22.F') env2.Program(target = 'test23', source = 'test23.for') @@ -119,7 +119,7 @@ env2.Program(target = 'test27', source = 'test27.fpp') env2.Program(target = 'test28', source = 'test28.FPP') env2.Program(target = 'test29', source = 'test29.f77') env2.Program(target = 'test30', source = 'test30.F77') -""" % (python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -191,12 +191,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f77 = foo.Dictionary('F77') -bar = foo.Copy(F77 = r'%s wrapper.py ' + f77) +bar = foo.Copy(F77 = r'%(_python_)s wrapper.py ' + f77) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F77COM.py b/test/Fortran/F77COM.py index 9de4d17..c566d88 100644 --- a/test/Fortran/F77COM.py +++ b/test/Fortran/F77COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - F77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES', - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + F77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + F77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,10 +104,10 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - F77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES') + F77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + F77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES') env2.Program(target = 'test21', source = 'test21.f') env2.Program(target = 'test22', source = 'test22.F') env2.Program(target = 'test23', source = 'test23.for') @@ -118,7 +118,7 @@ env2.Program(target = 'test27', source = 'test27.fpp') env2.Program(target = 'test28', source = 'test28.FPP') env2.Program(target = 'test29', source = 'test29.f77') env2.Program(target = 'test30', source = 'test30.F77') -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/F77COMSTR.py b/test/Fortran/F77COMSTR.py index 721551d..7f6f1a1 100644 --- a/test/Fortran/F77COMSTR.py +++ b/test/Fortran/F77COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(F77COM = r'%(python)s myfc.py f77 $TARGET $SOURCES', +env = Environment(F77COM = r'%(_python_)s myfc.py f77 $TARGET $SOURCES', F77COMSTR = 'Building f77 $TARGET from $SOURCES', - F77PPCOM = r'%(python)s myfc.py f77pp $TARGET $SOURCES', + F77PPCOM = r'%(_python_)s myfc.py f77pp $TARGET $SOURCES', F77PPCOMSTR = 'Building f77pp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f') diff --git a/test/Fortran/F77FLAGS.py b/test/Fortran/F77FLAGS.py index d50eeb9..b1d9142 100644 --- a/test/Fortran/F77FLAGS.py +++ b/test/Fortran/F77FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -90,9 +90,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77 = r'%s myg77.py', + F77 = r'%(_python_)s myg77.py', F77FLAGS = '-x') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -104,7 +104,7 @@ env.Program(target = 'test07', source = 'test07.fpp') env.Program(target = 'test08', source = 'test08.FPP') env.Program(target = 'test09', source = 'test09.f77') env.Program(target = 'test10', source = 'test10.F77') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#g77\n") test.write('test02.F', "This is a .F file.\n#link\n#g77\n") @@ -146,12 +146,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %FTN_LIBs) f77 = foo.Dictionary('F77') -bar = foo.Copy(F77 = r'%s wrapper.py ' + f77, F77FLAGS = '-Ix') +bar = foo.Copy(F77 = r'%(_python_)s wrapper.py ' + f77, F77FLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F90.py b/test/Fortran/F90.py index 8f8bc45..6b38e8e 100644 --- a/test/Fortran/F90.py +++ b/test/Fortran/F90.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -89,10 +89,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90 = r'%s myfortran.py f90', - FORTRAN = r'%s myfortran.py fortran') + F90 = r'%(_python_)s myfortran.py f90', + FORTRAN = r'%(_python_)s myfortran.py fortran') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -107,7 +107,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -157,12 +157,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f90 = foo.Dictionary('F90') -bar = foo.Copy(F90 = r'%s wrapper.py ' + f90) +bar = foo.Copy(F90 = r'%(_python_)s wrapper.py ' + f90) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F90COM.py b/test/Fortran/F90COM.py index bb52340..7a206da 100644 --- a/test/Fortran/F90COM.py +++ b/test/Fortran/F90COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - F90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES', - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + F90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + F90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,13 +104,13 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - F90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES') + F90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + F90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES') env2.Program(target = 'test21', source = 'test21.f90') env2.Program(target = 'test22', source = 'test22.F90') -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/F90COMSTR.py b/test/Fortran/F90COMSTR.py index bf7451c..e2e3cf5 100644 --- a/test/Fortran/F90COMSTR.py +++ b/test/Fortran/F90COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(F90COM = r'%(python)s myfc.py f90 $TARGET $SOURCES', +env = Environment(F90COM = r'%(_python_)s myfc.py f90 $TARGET $SOURCES', F90COMSTR = 'Building f90 $TARGET from $SOURCES', - F90PPCOM = r'%(python)s myfc.py f90pp $TARGET $SOURCES', + F90PPCOM = r'%(_python_)s myfc.py f90pp $TARGET $SOURCES', F90PPCOMSTR = 'Building f90pp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f90') diff --git a/test/Fortran/F90FLAGS.py b/test/Fortran/F90FLAGS.py index 69f1dfa..9a57eae 100644 --- a/test/Fortran/F90FLAGS.py +++ b/test/Fortran/F90FLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -91,11 +91,11 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90 = r'%s myfortran.py g90', + F90 = r'%(_python_)s myfortran.py g90', F90FLAGS = '-x', - FORTRAN = r'%s myfortran.py fortran', + FORTRAN = r'%(_python_)s myfortran.py fortran', FORTRANFLAGS = '-y') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -111,7 +111,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -161,12 +161,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f90 = foo.Dictionary('F90') -bar = foo.Copy(F90 = r'%s wrapper.py ' + f90, F90FLAGS = '-Ix') +bar = foo.Copy(F90 = r'%(_python_)s wrapper.py ' + f90, F90FLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F95.py b/test/Fortran/F95.py index a19c904..1b5fc41 100644 --- a/test/Fortran/F95.py +++ b/test/Fortran/F95.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -89,10 +89,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95 = r'%s myfortran.py f95', - FORTRAN = r'%s myfortran.py fortran') + F95 = r'%(_python_)s myfortran.py f95', + FORTRAN = r'%(_python_)s myfortran.py fortran') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -107,7 +107,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -157,12 +157,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f95 = foo.Dictionary('F95') -bar = foo.Copy(F95 = r'%s wrapper.py ' + f95) +bar = foo.Copy(F95 = r'%(_python_)s wrapper.py ' + f95) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F95COM.py b/test/Fortran/F95COM.py index 26423f8..016230a 100644 --- a/test/Fortran/F95COM.py +++ b/test/Fortran/F95COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - F95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES', - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + F95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + F95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,13 +104,13 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - F95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES') + F95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + F95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES') env2.Program(target = 'test21', source = 'test21.f95') env2.Program(target = 'test22', source = 'test22.F95') -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/F95COMSTR.py b/test/Fortran/F95COMSTR.py index 823ade6..ed7d1e8 100644 --- a/test/Fortran/F95COMSTR.py +++ b/test/Fortran/F95COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(F95COM = r'%(python)s myfc.py f95 $TARGET $SOURCES', +env = Environment(F95COM = r'%(_python_)s myfc.py f95 $TARGET $SOURCES', F95COMSTR = 'Building f95 $TARGET from $SOURCES', - F95PPCOM = r'%(python)s myfc.py f95pp $TARGET $SOURCES', + F95PPCOM = r'%(_python_)s myfc.py f95pp $TARGET $SOURCES', F95PPCOMSTR = 'Building f95pp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f95') diff --git a/test/Fortran/F95FLAGS.py b/test/Fortran/F95FLAGS.py index 883d9a3..7ccffed 100644 --- a/test/Fortran/F95FLAGS.py +++ b/test/Fortran/F95FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -91,11 +91,11 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95 = r'%s myfortran.py g95', + F95 = r'%(_python_)s myfortran.py g95', F95FLAGS = '-x', - FORTRAN = r'%s myfortran.py fortran', + FORTRAN = r'%(_python_)s myfortran.py fortran', FORTRANFLAGS = '-y') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -111,7 +111,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -161,12 +161,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f95 = foo.Dictionary('F95') -bar = foo.Copy(F95 = r'%s wrapper.py ' + f95, F95FLAGS = '-Ix') +bar = foo.Copy(F95 = r'%(_python_)s wrapper.py ' + f95, F95FLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/FORTRAN.py b/test/Fortran/FORTRAN.py index 47a0a89..1bd4407 100644 --- a/test/Fortran/FORTRAN.py +++ b/test/Fortran/FORTRAN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -87,9 +87,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - FORTRAN = r'%s myg77.py') + FORTRAN = r'%(_python_)s myg77.py') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,7 +104,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#g77\n") test.write('test02.F', "This is a .F file.\n#link\n#g77\n") @@ -154,12 +154,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f77 = foo.Dictionary('FORTRAN') -bar = foo.Copy(FORTRAN = r'%s wrapper.py ' + f77) +bar = foo.Copy(FORTRAN = r'%(_python_)s wrapper.py ' + f77) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/FORTRANCOM.py b/test/Fortran/FORTRANCOM.py index f79ad6d..3e3fcb2 100644 --- a/test/Fortran/FORTRANCOM.py +++ b/test/Fortran/FORTRANCOM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,10 +84,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -102,7 +102,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/FORTRANCOMSTR.py b/test/Fortran/FORTRANCOMSTR.py index db75d43..fd318c3 100644 --- a/test/Fortran/FORTRANCOMSTR.py +++ b/test/Fortran/FORTRANCOMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(FORTRANCOM = r'%(python)s myfc.py fortran $TARGET $SOURCES', +env = Environment(FORTRANCOM = r'%(_python_)s myfc.py fortran $TARGET $SOURCES', FORTRANCOMSTR = 'Building fortran $TARGET from $SOURCES', - FORTRANPPCOM = r'%(python)s myfc.py fortranpp $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfc.py fortranpp $TARGET $SOURCES', FORTRANPPCOMSTR = 'Building fortranpp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f') diff --git a/test/Fortran/FORTRANFLAGS.py b/test/Fortran/FORTRANFLAGS.py index 8d77d63..6dd27d7 100644 --- a/test/Fortran/FORTRANFLAGS.py +++ b/test/Fortran/FORTRANFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -90,9 +90,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - FORTRAN = r'%s myfortran.py', + FORTRAN = r'%(_python_)s myfortran.py', FORTRANFLAGS = '-x') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -108,7 +108,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -158,12 +158,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f77 = foo.Dictionary('FORTRAN') -bar = foo.Copy(FORTRAN = r'%s wrapper.py ' + f77, FORTRANFLAGS = '-Ix') +bar = foo.Copy(FORTRAN = r'%(_python_)s wrapper.py ' + f77, FORTRANFLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/FORTRANMODDIR.py b/test/Fortran/FORTRANMODDIR.py index 4d594a1..f0c500c 100644 --- a/test/Fortran/FORTRANMODDIR.py +++ b/test/Fortran/FORTRANMODDIR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(FORTRANCOM = r'%(python)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET', +env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET', FORTRANMODDIR = 'modules') env.Object(target = 'test1.obj', source = 'test1.f') """ % locals()) diff --git a/test/Fortran/FORTRANSUFFIXES.py b/test/Fortran/FORTRANSUFFIXES.py index c172f7a..3011fac 100644 --- a/test/Fortran/FORTRANSUFFIXES.py +++ b/test/Fortran/FORTRANSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $FORTRANSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(FORTRANPATH = ['.'], - FORTRAN = r'%s myfc.py', + FORTRAN = r'%(_python_)s myfc.py', FORTRANCOM = '$FORTRAN $TARGET $SOURCES', OBJSUFFIX = '.o') env.Append(FORTRANSUFFIXES = ['.x']) @@ -59,7 +59,7 @@ env.Object(target = 'test1', source = 'test1.f') env.InstallAs('test1_f', 'test1.f') env.InstallAs('test1_h', 'test1.h') env.InstallAs('test1_x', 'test1.x') -""" % (python,)) +""" % locals()) test.write('test1.f', """\ test1.f 1 @@ -81,12 +81,14 @@ test.write('foo.h', """\ foo.h 1 """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f Install file: "test1.f" as "test1_f" Install file: "test1.h" as "test1_h" Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 @@ -102,9 +104,11 @@ test.write('foo.h', """\ foo.h 2 """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f -""" % (python,))) +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 @@ -121,10 +125,12 @@ test.write('test1.x', """\ INCLUDE 'foo.h' """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 @@ -141,10 +147,12 @@ test.write('test1.h', """\ INCLUDE 'foo.h' """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f Install file: "test1.h" as "test1_h" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 diff --git a/test/Fortran/SHF77.py b/test/Fortran/SHF77.py index 233921b..c9569c9 100644 --- a/test/Fortran/SHF77.py +++ b/test/Fortran/SHF77.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF77 = r'%s myfortran.py g77', - SHFORTRAN = r'%s myfortran.py fortran') +env = Environment(SHF77 = r'%(_python_)s myfortran.py g77', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF77 = r'%s myfortran.py g77') +env2 = Environment(SHF77 = r'%(_python_)s myfortran.py g77') env2.SharedObject(target = 'test21', source = 'test21.f') env2.SharedObject(target = 'test22', source = 'test22.F') env2.SharedObject(target = 'test23', source = 'test23.for') @@ -79,7 +79,7 @@ env2.SharedObject(target = 'test25', source = 'test25.ftn') env2.SharedObject(target = 'test26', source = 'test26.FTN') env2.SharedObject(target = 'test27', source = 'test27.fpp') env2.SharedObject(target = 'test28', source = 'test28.FPP') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -148,10 +148,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shf77 = foo.Dictionary('SHF77') -bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77) +bar = foo.Copy(SHF77 = r'%(_python_)s wrapper.py ' + shf77) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF77COM.py b/test/Fortran/SHF77COM.py index fa02487..75192df 100644 --- a/test/Fortran/SHF77COM.py +++ b/test/Fortran/SHF77COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - SHF77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES', - SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHF77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + SHF77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES', + SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,8 +68,8 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - SHF77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES') +env2 = Environment(SHF77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + SHF77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES') env2.SharedObject(target = 'test21', source = 'test21.f') env2.SharedObject(target = 'test22', source = 'test22.F') env2.SharedObject(target = 'test23', source = 'test23.for') @@ -80,7 +80,7 @@ env2.SharedObject(target = 'test27', source = 'test27.fpp') env2.SharedObject(target = 'test28', source = 'test28.FPP') env2.SharedObject(target = 'test29', source = 'test29.f77') env2.SharedObject(target = 'test30', source = 'test30.F77') -""" % (python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHF77COMSTR.py b/test/Fortran/SHF77COMSTR.py index fdb81c1..9085570 100644 --- a/test/Fortran/SHF77COMSTR.py +++ b/test/Fortran/SHF77COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHF77COM = r'%(python)s myfc.py f77 $TARGET $SOURCES', +env = Environment(SHF77COM = r'%(_python_)s myfc.py f77 $TARGET $SOURCES', SHF77COMSTR = 'Building f77 $TARGET from $SOURCES', - SHF77PPCOM = r'%(python)s myfc.py f77pp $TARGET $SOURCES', + SHF77PPCOM = r'%(_python_)s myfc.py f77pp $TARGET $SOURCES', SHF77PPCOMSTR = 'Building f77pp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f') diff --git a/test/Fortran/SHF77FLAGS.py b/test/Fortran/SHF77FLAGS.py index 85c1168..5354a57 100644 --- a/test/Fortran/SHF77FLAGS.py +++ b/test/Fortran/SHF77FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -63,7 +63,7 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF77 = r'%s myg77.py', +env = Environment(SHF77 = r'%(_python_)s myg77.py', SHF77FLAGS = '-x') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -75,7 +75,7 @@ env.SharedObject(target = 'test07', source = 'test07.fpp') env.SharedObject(target = 'test08', source = 'test08.FPP') env.SharedObject(target = 'test09', source = 'test09.f77') env.SharedObject(target = 'test10', source = 'test10.F77') -""" % (python,)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#g77\n") test.write('test02.F', "This is a .F file.\n#g77\n") @@ -117,12 +117,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shf77 = foo.Dictionary('SHF77') -bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77, SHF77FLAGS = '-Ix') +bar = foo.Copy(SHF77 = r'%(_python_)s wrapper.py ' + shf77, SHF77FLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF90.py b/test/Fortran/SHF90.py index 66bd68d..1696b4a 100644 --- a/test/Fortran/SHF90.py +++ b/test/Fortran/SHF90.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF90 = r'%s myfortran.py g90', - SHFORTRAN = r'%s myfortran.py fortran') +env = Environment(SHF90 = r'%(_python_)s myfortran.py g90', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -121,10 +121,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shf90 = foo.Dictionary('SHF90') -bar = foo.Copy(SHF90 = r'%s wrapper.py ' + shf90) +bar = foo.Copy(SHF90 = r'%(_python_)s wrapper.py ' + shf90) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF90COM.py b/test/Fortran/SHF90COM.py index ffc9878..13d9978 100644 --- a/test/Fortran/SHF90COM.py +++ b/test/Fortran/SHF90COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - SHF90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES', - SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHF90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + SHF90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES', + SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,11 +68,11 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - SHF90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES') +env2 = Environment(SHF90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + SHF90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES') env2.SharedObject(target = 'test21', source = 'test21.f90') env2.SharedObject(target = 'test22', source = 'test22.F90') -""" % (python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHF90COMSTR.py b/test/Fortran/SHF90COMSTR.py index f0e44d3..9633d45 100644 --- a/test/Fortran/SHF90COMSTR.py +++ b/test/Fortran/SHF90COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHF90COM = r'%(python)s myfc.py f90 $TARGET $SOURCES', +env = Environment(SHF90COM = r'%(_python_)s myfc.py f90 $TARGET $SOURCES', SHF90COMSTR = 'Building f90 $TARGET from $SOURCES', - SHF90PPCOM = r'%(python)s myfc.py f90pp $TARGET $SOURCES', + SHF90PPCOM = r'%(_python_)s myfc.py f90pp $TARGET $SOURCES', SHF90PPCOMSTR = 'Building f90pp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f90') diff --git a/test/Fortran/SHF90FLAGS.py b/test/Fortran/SHF90FLAGS.py index 3997cbb..62bb7d0 100644 --- a/test/Fortran/SHF90FLAGS.py +++ b/test/Fortran/SHF90FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -64,9 +64,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF90 = r'%s myfortran.py g90', +env = Environment(SHF90 = r'%(_python_)s myfortran.py g90', SHF90FLAGS = '-x', - SHFORTRAN = r'%s myfortran.py fortran', + SHFORTRAN = r'%(_python_)s myfortran.py fortran', SHFORTRANFLAGS = '-y') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -82,7 +82,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -132,12 +132,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shf90 = foo.Dictionary('SHF90') -bar = foo.Copy(SHF90 = r'%s wrapper.py ' + shf90, SHF90FLAGS = '-Ix') +bar = foo.Copy(SHF90 = r'%(_python_)s wrapper.py ' + shf90, SHF90FLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF95.py b/test/Fortran/SHF95.py index d2d92a9..85702df 100644 --- a/test/Fortran/SHF95.py +++ b/test/Fortran/SHF95.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF95 = r'%s myfortran.py g95', - SHFORTRAN = r'%s myfortran.py fortran') +env = Environment(SHF95 = r'%(_python_)s myfortran.py g95', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -121,10 +121,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shf95 = foo.Dictionary('SHF95') -bar = foo.Copy(SHF95 = r'%s wrapper.py ' + shf95) +bar = foo.Copy(SHF95 = r'%(_python_)s wrapper.py ' + shf95) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF95COM.py b/test/Fortran/SHF95COM.py index e28f863..b11933a 100644 --- a/test/Fortran/SHF95COM.py +++ b/test/Fortran/SHF95COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - SHF95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES', - SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHF95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + SHF95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES', + SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,11 +68,11 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - SHF95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES') +env2 = Environment(SHF95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + SHF95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES') env2.SharedObject(target = 'test21', source = 'test21.f95') env2.SharedObject(target = 'test22', source = 'test22.F95') -""" % (python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHF95COMSTR.py b/test/Fortran/SHF95COMSTR.py index 461d7ff..eaa24ae 100644 --- a/test/Fortran/SHF95COMSTR.py +++ b/test/Fortran/SHF95COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHF95COM = r'%(python)s myfc.py f95 $TARGET $SOURCES', +env = Environment(SHF95COM = r'%(_python_)s myfc.py f95 $TARGET $SOURCES', SHF95COMSTR = 'Building f95 $TARGET from $SOURCES', - SHF95PPCOM = r'%(python)s myfc.py f95pp $TARGET $SOURCES', + SHF95PPCOM = r'%(_python_)s myfc.py f95pp $TARGET $SOURCES', SHF95PPCOMSTR = 'Building f95pp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f95') diff --git a/test/Fortran/SHF95FLAGS.py b/test/Fortran/SHF95FLAGS.py index 782a495..2288a4a 100644 --- a/test/Fortran/SHF95FLAGS.py +++ b/test/Fortran/SHF95FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -64,9 +64,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF95 = r'%s myfortran.py g95', +env = Environment(SHF95 = r'%(_python_)s myfortran.py g95', SHF95FLAGS = '-x', - SHFORTRAN = r'%s myfortran.py fortran', + SHFORTRAN = r'%(_python_)s myfortran.py fortran', SHFORTRANFLAGS = '-y') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -82,7 +82,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -132,12 +132,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shf95 = foo.Dictionary('SHF95') -bar = foo.Copy(SHF95 = r'%s wrapper.py ' + shf95, SHF95FLAGS = '-Ix') +bar = foo.Copy(SHF95 = r'%(_python_)s wrapper.py ' + shf95, SHF95FLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHFORTRAN.py b/test/Fortran/SHFORTRAN.py index 17a58f5..586b54e 100644 --- a/test/Fortran/SHFORTRAN.py +++ b/test/Fortran/SHFORTRAN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHFORTRAN = r'%s myfortran.py') +env = Environment(SHFORTRAN = r'%(_python_)s myfortran.py') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,7 +68,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % python) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -119,10 +119,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shfortran = foo.Dictionary('SHFORTRAN') -bar = foo.Copy(SHFORTRAN = r'%s wrapper.py ' + shfortran) +bar = foo.Copy(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHFORTRANCOM.py b/test/Fortran/SHFORTRANCOM.py index f4d44dc..21942cf 100644 --- a/test/Fortran/SHFORTRANCOM.py +++ b/test/Fortran/SHFORTRANCOM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,8 +50,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -66,7 +66,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHFORTRANCOMSTR.py b/test/Fortran/SHFORTRANCOMSTR.py index 8ad3b14..69a1eba 100644 --- a/test/Fortran/SHFORTRANCOMSTR.py +++ b/test/Fortran/SHFORTRANCOMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHFORTRANCOM = r'%(python)s myfc.py fortran $TARGET $SOURCES', +env = Environment(SHFORTRANCOM = r'%(_python_)s myfc.py fortran $TARGET $SOURCES', SHFORTRANCOMSTR = 'Building fortran $TARGET from $SOURCES', - SHFORTRANPPCOM = r'%(python)s myfc.py fortranpp $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfc.py fortranpp $TARGET $SOURCES', SHFORTRANPPCOMSTR = 'Building fortranpp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f') diff --git a/test/Fortran/SHFORTRANFLAGS.py b/test/Fortran/SHFORTRANFLAGS.py index e96ade9..d09a283 100644 --- a/test/Fortran/SHFORTRANFLAGS.py +++ b/test/Fortran/SHFORTRANFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -63,7 +63,7 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHFORTRAN = r'%s myfortran.py', +env = Environment(SHFORTRAN = r'%(_python_)s myfortran.py', SHFORTRANFLAGS = '-x') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -79,7 +79,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python,)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -129,13 +129,13 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shfortran = foo.Dictionary('SHFORTRAN') -bar = foo.Copy(SHFORTRAN = r'%s wrapper.py ' + shfortran, +bar = foo.Copy(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran, SHFORTRANFLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/USE-MODULE.py b/test/Fortran/USE-MODULE.py index 541c457..23d0a89 100644 --- a/test/Fortran/USE-MODULE.py +++ b/test/Fortran/USE-MODULE.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(FORTRANCOM = r'%(python)s myfortran.py $SOURCE $TARGET') +env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $SOURCE $TARGET') env.Object(target = 'test1.obj', source = 'test1.f') """ % locals()) diff --git a/test/Fortran/module-subdir.py b/test/Fortran/module-subdir.py new file mode 100644 index 0000000..88d0888 --- /dev/null +++ b/test/Fortran/module-subdir.py @@ -0,0 +1,115 @@ +#!/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__" + +""" +Validate that $FORTRANMODDIR values get expanded correctly on Fortran +command lines relative to the appropriate subdirectory. +""" + +import os.path + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.subdir('subdir', + ['subdir', 'src'], + ['subdir', 'build']) + +test.write('myfortran.py', r""" +import getopt +import os +import sys +comment = '#' + sys.argv[1] +length = len(comment) +opts, args = getopt.getopt(sys.argv[2:], 'cM:o:') +for opt, arg in opts: + if opt == '-o': out = arg + elif opt == '-M': modsubdir = arg +import os +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:7] == 'module ': + module = modsubdir + os.sep + l[7:-1] + '.mod' + open(module, 'wb').write('myfortran.py wrote %s\n' % module) + if l[:length] != comment: + outfile.write(l) +sys.exit(0) +""") + +test.write('myar.py', """\ +import sys +t = open(sys.argv[1], 'wb') +for s in sys.argv[2:]: + t.write(open(s, 'rb').read()) +t.close +sys.exit(0) +""") + +test.write('SConstruct', """\ +env = Environment(FORTRANMODDIRPREFIX = '-M', + FORTRANMODDIR = 'modules', + F90 = r'%(_python_)s myfortran.py f90', + FORTRAN = r'%(_python_)s myfortran.py fortran', + AR = 'myar.py', + ARCOM = r'%(_python_)s $AR $TARGET $SOURCES', + RANLIBCOM = '') +Export('env') +objs = SConscript('subdir/SConscript') +env.Library('bidule', objs) +""" % locals()) + +test.write(['subdir', 'SConscript'], """\ +Import('env') + +env['FORTRANMODDIR'] = 'build' +sources = ['src/modfile.f90'] +objs = env.Object(sources) +Return("objs") +""") + +test.write(['subdir', 'src', 'modfile.f90'], """\ +#f90 comment +module somemodule + +integer :: nothing + +end module +""") + + +test.run(arguments = '.') + +somemodule = os.path.join('subdir', 'build', 'somemodule.mod') + +expect = "myfortran.py wrote %s\n" % somemodule + +test.must_match(['subdir', 'build', 'somemodule.mod'], expect) + +test.pass_test() diff --git a/test/Ghostscript/GS.py b/test/Ghostscript/GS.py index a836cf6..6089d60 100644 --- a/test/Ghostscript/GS.py +++ b/test/Ghostscript/GS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,11 +48,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(GS = r'%s mygs.py', +env = Environment(GS = r'%(_python_)s mygs.py', GSCOM = r'$GS $TARGET $SOURCE', tools=['gs']) env.PDF(target = 'test1.pdf', source = 'test1.ps') -""" % (python)) +""" % locals()) test.write('test1.ps', r"""This is a .ps test. #ps @@ -88,10 +88,10 @@ import os foo = Environment(ENV = { 'PATH' : os.environ['PATH'] }) gs = foo.Dictionary('GS') bar = Environment(ENV = { 'PATH' : os.environ['PATH'] }, - GS = r'%s wrapper.py ' + gs) + GS = r'%(_python_)s wrapper.py ' + gs) foo.PDF(target = 'foo.pdf', source = 'foo.ps') bar.PDF(target = 'bar.pdf', source = 'bar.ps') -""" % python) +""" % locals()) input = """\ %!PS-Adobe diff --git a/test/Ghostscript/GSCOM.py b/test/Ghostscript/GSCOM.py index acd46f2..a41c800 100644 --- a/test/Ghostscript/GSCOM.py +++ b/test/Ghostscript/GSCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $GSCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'gs'], - GSCOM = r'%s mygs.py $TARGET $SOURCES') + GSCOM = r'%(_python_)s mygs.py $TARGET $SOURCES') env.PDF(target = 'aaa', source = 'aaa.ps') -""" % python) +""" % locals()) test.write('aaa.ps', "aaa.ps\n/*gs*/\n") diff --git a/test/Ghostscript/GSCOMSTR.py b/test/Ghostscript/GSCOMSTR.py index 9f7aee8..923aee3 100644 --- a/test/Ghostscript/GSCOMSTR.py +++ b/test/Ghostscript/GSCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when Ghostscript is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'gs'], - GSCOM = r'%s mygs.py $TARGET $SOURCES', + GSCOM = r'%(_python_)s mygs.py $TARGET $SOURCES', GSCOMSTR = 'GSing $TARGET from $SOURCE') env.PDF(target = 'aaa', source = 'aaa.ps') -""" % python) +""" % locals()) test.write('aaa.ps', "aaa.ps\n/*gs*/\n") diff --git a/test/Ghostscript/GSFLAGS.py b/test/Ghostscript/GSFLAGS.py index 14ce769..7acb89e 100644 --- a/test/Ghostscript/GSFLAGS.py +++ b/test/Ghostscript/GSFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,10 +57,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(GS = r'%s mygs.py', GSFLAGS = '-x', +env = Environment(GS = r'%(_python_)s mygs.py', GSFLAGS = '-x', tools = ['gs']) env.PDF(target = 'test1.pdf', source = 'test1.ps') -""" % (python)) +""" % locals()) test.write('test1.ps', """\ This is a .ps test. diff --git a/test/IDL/MIDLCOM.py b/test/IDL/MIDLCOM.py index d3f6420..79857d0 100644 --- a/test/IDL/MIDLCOM.py +++ b/test/IDL/MIDLCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $MIDLCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'midl'], - MIDLCOM = r'%s mymidl.py $TARGET $SOURCES') + MIDLCOM = r'%(_python_)s mymidl.py $TARGET $SOURCES') env.TypeLibrary(target = 'aaa', source = 'aaa.idl') -""" % python) +""" % locals()) test.write('aaa.idl', "aaa.idl\n/*midl*/\n") diff --git a/test/IDL/MIDLCOMSTR.py b/test/IDL/MIDLCOMSTR.py index 89a6e25..8c3a15a 100644 --- a/test/IDL/MIDLCOMSTR.py +++ b/test/IDL/MIDLCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when midl is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'midl'], - MIDLCOM = r'%s mymidl.py $TARGET $SOURCES', + MIDLCOM = r'%(_python_)s mymidl.py $TARGET $SOURCES', MIDLCOMSTR = 'MIDLing $TARGET from $SOURCE') env.TypeLibrary(target = 'aaa', source = 'aaa.idl') -""" % python) +""" % locals()) test.write('aaa.idl', "aaa.idl\n/*midl*/\n") diff --git a/test/Ignore.py b/test/Ignore.py index 1652f60..15cf4f3 100644 --- a/test/Ignore.py +++ b/test/Ignore.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -43,19 +43,19 @@ for arg in sys.argv[2:]: file.close() """) +SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out') +SUBDIR_f3b_in = os.path.join('$SUBDIR', 'f3b.in') + test.write('SConstruct', """\ -Foo = Builder(action = r"%s build.py $TARGET $SOURCES") -Bar = Builder(action = r"%s build.py $TARGET $SOURCES") +Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') +Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir') env.Foo(target = 'f1.out', source = ['f1a.in', 'f1b.in']) Ignore(target = 'f1.out', dependency = 'f1b.in') SConscript('subdir/SConscript', "env") env.Foo(target = 'subdir/f3.out', source = ['subdir/f3a.in', 'subdir/f3b.in']) -env.Ignore(target = r'%s', dependency = r'%s') -""" % (python, - python, - os.path.join('$SUBDIR', 'f3.out'), - os.path.join('$SUBDIR', 'f3b.in'))) +env.Ignore(target = r'%(SUBDIR_f3_out)s', dependency = r'%(SUBDIR_f3b_in)s') +""" % locals()) test.write(['subdir', 'SConscript'], """ Import("env") diff --git a/test/Install/Install.py b/test/Install/Install.py index 7018466..e24641b 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -46,6 +46,8 @@ f5_txt = test.workpath('outside', 'f5.txt') f6_txt = test.workpath('outside', 'f6.txt') f6_sep = string.replace(f6_txt, os.sep, '/') +_SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out') + test.write(['work', 'SConstruct'], """\ def cat(env, source, target): target = str(target[0]) @@ -74,15 +76,13 @@ env3.Install(dir='export', source=t) env4 = env1.Copy(EXPORT='export', SUBDIR='sub') t = env4.Cat(target='sub/f4.out', source='sub/f4.in') -env4.Install(dir='$EXPORT', source=r'%s') - -env1.Install('.', r'%s') -env1.Install('export', r'%s') -env1.Install('.', r'%s') -env1.Install('export', r'%s') -""" % (os.path.join('$SUBDIR', 'f4.out'), - f5_txt, f5_txt, - f6_sep, f6_sep)) +env4.Install(dir='$EXPORT', source=r'%(_SUBDIR_f4_out)s') + +env1.Install('.', r'%(f5_txt)s') +env1.Install('export', r'%(f5_txt)s') +env1.Install('.', r'%(f6_sep)s') +env1.Install('export', r'%(f6_sep)s') +""" % locals()) test.write(['work', 'f1.in'], "f1.in\n") test.write(['work', 'f2.in'], "f2.in\n") diff --git a/test/Install/InstallAs.py b/test/Install/InstallAs.py index 4fe4bd0..7a6c9f6 100644 --- a/test/Install/InstallAs.py +++ b/test/Install/InstallAs.py @@ -41,16 +41,16 @@ install_file1_out = test.workpath('install', 'file1.out') install_file2_out = test.workpath('install', 'file2.out') install_file3_out = test.workpath('install', 'file3.out') +_INSTALLDIR_file2_out = os.path.join('$INSTALLDIR', 'file2.out') +_SUBDIR_file3_in = os.path.join('$SUBDIR', 'file3.in') + # test.write('SConstruct', r""" -env = Environment(INSTALLDIR=r'%s', SUBDIR='subdir') -InstallAs(r'%s', 'file1.in') -env.InstallAs([r'%s', r'%s'], ['file2.in', r'%s']) -""" % (install, - install_file1_out, - os.path.join('$INSTALLDIR', 'file2.out'), - install_file3_out, - os.path.join('$SUBDIR', 'file3.in'))) +env = Environment(INSTALLDIR=r'%(install)s', SUBDIR='subdir') +InstallAs(r'%(install_file1_out)s', 'file1.in') +env.InstallAs([r'%(_INSTALLDIR_file2_out)s', r'%(install_file3_out)s'], + ['file2.in', r'%(_SUBDIR_file3_in)s']) +""" % locals()) test.write('file1.in', "file1.in\n") test.write('file2.in', "file2.in\n") diff --git a/test/Install/directories.py b/test/Install/directories.py new file mode 100644 index 0000000..300ed4d --- /dev/null +++ b/test/Install/directories.py @@ -0,0 +1,95 @@ +#!/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 using Install() on directories. +""" + +import os.path +import string +import sys +import time +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('outside', + 'work', + ['work', 'dir1'], + ['work', 'dir1', 'sub'], + ['work', 'dir2'], + ['work', 'dir2', 'sub'], + ['work', 'dir3'], + ['work', 'dir3', 'sub'], + ['work', 'dir4'], + ['work', 'dir4', 'sub']) + +test.write(['work', 'SConstruct'], """\ +Install('../outside', 'dir1') +InstallAs('../outside/d2', 'dir2') + +env = Environment() +env.Install('../outside', 'dir3') +env.InstallAs('../outside/d4', 'dir4') +""") + +test.write(['work', 'f1'], "work/f1\n") +test.write(['work', 'dir1', 'f2'], "work/dir1/f2\n") +test.write(['work', 'dir1', 'sub', 'f3'], "work/dir1/sub/f3\n") +test.write(['work', 'dir2', 'f4'], "work/dir2/f4\n") +test.write(['work', 'dir2', 'sub', 'f5'], "work/dir2/sub/f5\n") +test.write(['work', 'dir3', 'f6'], "work/dir3/f6\n") +test.write(['work', 'dir3', 'sub', 'f7'], "work/dir3/sub/f7\n") +test.write(['work', 'dir4', 'f8'], "work/dir4/f8\n") +test.write(['work', 'dir4', 'sub', 'f9'], "work/dir4/sub/f9\n") + + +arguments = [ + test.workpath('outside', 'dir1'), + test.workpath('outside', 'd2'), + test.workpath('outside', 'dir3'), + test.workpath('outside', 'd4'), +] + +expect = test.wrap_stdout(""" +Install directory: "dir1" as "%s" +Install directory: "dir2" as "%s" +Install directory: "dir3" as "%s" +Install directory: "dir4" as "%s" +""" % tuple(arguments)) + +test.run(chdir = 'work', arguments = arguments) + +test.must_match(test.workpath('outside', 'dir1', 'f2'), "work/dir1/f2\n") +test.must_match(test.workpath('outside', 'dir1', 'sub', 'f3'), "work/dir1/sub/f3\n") +test.must_match(test.workpath('outside', 'd2', 'f4'), "work/dir2/f4\n") +test.must_match(test.workpath('outside', 'd2', 'sub', 'f5'), "work/dir2/sub/f5\n") +test.must_match(test.workpath('outside', 'dir3', 'f6'), "work/dir3/f6\n") +test.must_match(test.workpath('outside', 'dir3', 'sub', 'f7'), "work/dir3/sub/f7\n") +test.must_match(test.workpath('outside', 'd4', 'f8'), "work/dir4/f8\n") +test.must_match(test.workpath('outside', 'd4', 'sub', 'f9'), "work/dir4/sub/f9\n") + +test.pass_test() diff --git a/test/Java/JAR.py b/test/Java/JAR.py index 1344fb1..5342a48 100644 --- a/test/Java/JAR.py +++ b/test/Java/JAR.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -56,9 +56,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['jar'], - JAR = r'%s myjar.py') + JAR = r'%(_python_)s myjar.py') env.Jar(target = 'test1.jar', source = 'test1.class') -""" % (python)) +""" % locals()) test.write('test1.class', """\ test1.class @@ -74,9 +74,9 @@ if os.path.normcase('.class') == os.path.normcase('.CLASS'): test.write('SConstruct', """ env = Environment(tools = ['jar'], - JAR = r'%s myjar.py') + JAR = r'%(_python_)s myjar.py') env.Jar(target = 'test2.jar', source = 'test2.CLASS') -""" % (python)) +""" % locals()) test.write('test2.CLASS', """\ test2.CLASS @@ -100,13 +100,13 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['jar'], - JAR = r'%s myjar2.py', + JAR = r'%(_python_)s myjar2.py', JARFLAGS='cvf') env.Jar(target = 'classes.jar', source = [ 'testdir/bar.class', 'foo.mf' ], TESTDIR='testdir', JARCHDIR='$TESTDIR') -""" % (python)) +""" % locals()) test.subdir('testdir') test.write([ 'testdir', 'bar.class' ], 'foo') @@ -150,7 +150,7 @@ foo = Environment(tools = ['javac', 'jar'], JAVAC = r'%(where_javac)s', JAR = r'%(where_jar)s') jar = foo.Dictionary('JAR') -bar = foo.Copy(JAR = r'%(python)s wrapper.py ' + jar) +bar = foo.Copy(JAR = r'%(_python_)s wrapper.py ' + jar) foo.Java(target = 'classes', source = 'com/sub/foo') bar.Java(target = 'classes', source = 'com/sub/bar') foo.Jar(target = 'foo', source = 'classes/com/sub/foo') diff --git a/test/Java/JARCOM.py b/test/Java/JARCOM.py index 0d7ebba..f03cd9f 100644 --- a/test/Java/JARCOM.py +++ b/test/Java/JARCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JARCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,7 +48,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'jar'], - JARCOM = r'%(python)s myjar.py $TARGET $SOURCES') + JARCOM = r'%(_python_)s myjar.py $TARGET $SOURCES') env.Jar(target = 'test1', source = ['file1.in', 'file2.in', 'file3.in']) """ % locals()) diff --git a/test/Java/JARCOMSTR.py b/test/Java/JARCOMSTR.py index aa8a6ad..35404ce 100644 --- a/test/Java/JARCOMSTR.py +++ b/test/Java/JARCOMSTR.py @@ -31,7 +31,7 @@ the jar output. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'jar'], - JARCOM = r'%(python)s myjar.py $TARGET $SOURCES', + JARCOM = r'%(_python_)s myjar.py $TARGET $SOURCES', JARCOMSTR = "Jar'ing up $TARGET from $SOURCES") env.Jar(target = 'test1', source = ['file1.in', 'file2.in', 'file3.in']) """ % locals()) diff --git a/test/Java/JAVAC.py b/test/Java/JAVAC.py index 93f0e7b..b5fb3f8 100644 --- a/test/Java/JAVAC.py +++ b/test/Java/JAVAC.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['javac'], - JAVAC = r'%s myjavac.py') + JAVAC = r'%(_python_)s myjavac.py') env.Java(target = '.', source = '.') -""" % (python)) +""" % locals()) test.write('test1.java', """\ test1.java @@ -77,9 +77,9 @@ if os.path.normcase('.java') == os.path.normcase('.JAVA'): test.write('SConstruct', """\ env = Environment(tools = ['javac'], - JAVAC = r'%s myjavac.py') + JAVAC = r'%(_python_)s myjavac.py') env.Java(target = '.', source = '.') -""" % python) +""" % locals()) test.write('test2.JAVA', """\ test2.JAVA @@ -114,13 +114,13 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(tools = ['javac'], - JAVAC = r'%s') + JAVAC = r'%(where_javac)s') javac = foo.Dictionary('JAVAC') -bar = foo.Copy(JAVAC = r'%s wrapper.py ' + javac) +bar = foo.Copy(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']) -""" % (where_javac, python)) +""" % locals()) test.subdir('com', ['com', 'sub'], diff --git a/test/Java/JAVACCOM.py b/test/Java/JAVACCOM.py index 171649c..7086a2a 100644 --- a/test/Java/JAVACCOM.py +++ b/test/Java/JAVACCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JAVACCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javac'], - JAVACCOM = r'%(python)s myjavac.py $TARGET $SOURCES') + JAVACCOM = r'%(_python_)s myjavac.py $TARGET $SOURCES') env.Java(target = 'classes', source = 'src') """ % locals()) diff --git a/test/Java/JAVACCOMSTR.py b/test/Java/JAVACCOMSTR.py index 7f59e90..44b1449 100644 --- a/test/Java/JAVACCOMSTR.py +++ b/test/Java/JAVACCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javac'], - JAVACCOM = r'%(python)s myjavac.py $TARGET $SOURCES', + JAVACCOM = r'%(_python_)s myjavac.py $TARGET $SOURCES', JAVACCOMSTR = "Compiling class(es) $TARGET from $SOURCES") env.Java(target = 'classes', source = 'src') """ % locals()) diff --git a/test/Java/JAVAH.py b/test/Java/JAVAH.py index eb70ac8..9901764 100644 --- a/test/Java/JAVAH.py +++ b/test/Java/JAVAH.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,9 +61,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['javah'], - JAVAH = r'%s myjavah.py') + JAVAH = r'%(_python_)s myjavah.py') env.JavaH(target = File('test1.h'), source = 'test1.java') -""" % (python)) +""" % locals()) test.write('test1.java', """\ test1.java @@ -79,9 +79,9 @@ if os.path.normcase('.java') == os.path.normcase('.JAVA'): test.write('SConstruct', """\ env = Environment(tools = ['javah'], - JAVAH = r'%s myjavah.py') + JAVAH = r'%(_python_)s myjavah.py') env.JavaH(target = File('test2.h'), source = 'test2.JAVA') -""" % python) +""" % locals()) test.write('test2.JAVA', """\ test2.JAVA @@ -126,7 +126,7 @@ foo = Environment(tools = ['javac', 'javah'], JAVAC = r'%(where_javac)s', JAVAH = r'%(where_javah)s') javah = foo.Dictionary('JAVAH') -bar = foo.Copy(JAVAH = r'%(python)s wrapper.py ' + javah) +bar = foo.Copy(JAVAH = r'%(_python_)s wrapper.py ' + javah) foo.Java(target = 'class1', source = 'com/sub/foo') bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar') foo_classes = foo.Java(target = 'class3', source = 'src') diff --git a/test/Java/JAVAHCOM.py b/test/Java/JAVAHCOM.py index 1cc4208..73067c6 100644 --- a/test/Java/JAVAHCOM.py +++ b/test/Java/JAVAHCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JAVAHCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,7 +48,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javah'], - JAVAHCOM = r'%(python)s myjavah.py $TARGET $SOURCES') + JAVAHCOM = r'%(_python_)s myjavah.py $TARGET $SOURCES') env.JavaH(target = 'out', source = 'file1.class') env.JavaH(target = 'out', source = 'file2.class') env.JavaH(target = 'out', source = 'file3.class') diff --git a/test/Java/JAVAHCOMSTR.py b/test/Java/JAVAHCOMSTR.py index 2a14e1c..8ee5767 100644 --- a/test/Java/JAVAHCOMSTR.py +++ b/test/Java/JAVAHCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,7 +59,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javah'], - JAVAHCOM = r'%(python)s myjavah.py $TARGET $SOURCES', + JAVAHCOM = r'%(_python_)s myjavah.py $TARGET $SOURCES', JAVAHCOMSTR = 'Building javah $TARGET from $SOURCES') env.JavaH(target = 'out', source = 'file1.class') env.JavaH(target = 'out', source = 'file2.class') diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py index 7ef1359..bb098e7 100644 --- a/test/Java/RMIC.py +++ b/test/Java/RMIC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,9 +60,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['rmic'], - RMIC = r'%s myrmic.py') + RMIC = r'%(_python_)s myrmic.py') env.RMIC(target = 'outdir', source = 'test1.java') -""" % (python)) +""" % locals()) test.write('test1.java', """\ test1.java @@ -78,9 +78,9 @@ if os.path.normcase('.java') == os.path.normcase('.JAVA'): test.write('SConstruct', """\ env = Environment(tools = ['rmic'], - RMIC = r'%s myrmic.py') + RMIC = r'%(_python_)s myrmic.py') env.RMIC(target = 'outdir', source = 'test2.JAVA') -""" % python) +""" % locals()) test.write('test2.JAVA', """\ test2.JAVA @@ -128,7 +128,7 @@ foo.RMIC(target = 'outdir1', JAVACLASSDIR = 'class1') rmic = foo.Dictionary('RMIC') -bar = foo.Copy(RMIC = r'%(python)s wrapper.py ' + rmic) +bar = foo.Copy(RMIC = r'%(_python_)s wrapper.py ' + rmic) bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar') # XXX This is kind of a Python brute-force way to do what Ant # does with its "excludes" attribute. We should probably find diff --git a/test/Java/RMICCOM.py b/test/Java/RMICCOM.py index 109c22e..ed5e0d6 100644 --- a/test/Java/RMICCOM.py +++ b/test/Java/RMICCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,7 +58,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'rmic'], - RMICCOM = r'%(python)s myrmic.py $TARGET $SOURCES') + RMICCOM = r'%(_python_)s myrmic.py $TARGET $SOURCES') env.RMIC(target = 'out', source = 'file1.class') env.RMIC(target = 'out', source = 'file2.class') env.RMIC(target = 'out', source = 'file3.class') diff --git a/test/Java/RMICCOMSTR.py b/test/Java/RMICCOMSTR.py index 1bcf300..5a451eb 100644 --- a/test/Java/RMICCOMSTR.py +++ b/test/Java/RMICCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,7 +59,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'rmic'], - RMICCOM = r'%(python)s myrmic.py $TARGET $SOURCES', + RMICCOM = r'%(_python_)s myrmic.py $TARGET $SOURCES', RMICCOMSTR = 'Building rmic $TARGET from $SOURCES') env.RMIC(target = 'out', source = 'file1.class') env.RMIC(target = 'out', source = 'file2.class') diff --git a/test/LEX/LEX.py b/test/LEX/LEX.py index 5515a3e..3fd4db3 100644 --- a/test/LEX/LEX.py +++ b/test/LEX/LEX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', tools=['default', 'lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', tools=['default', 'lex']) env.Program(target = 'aaa', source = 'aaa.l') env.Program(target = 'bbb', source = 'bbb.lex') -""" % python) +""" % locals()) test.write('aaa.l', r""" int @@ -97,10 +97,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() lex = foo.Dictionary('LEX') -bar = Environment(LEX = r'%s wrapper.py ' + lex) +bar = Environment(LEX = r'%(_python_)s wrapper.py ' + lex) foo.Program(target = 'foo', source = 'foo.l') bar.Program(target = 'bar', source = 'bar.l') -""" % python) +""" % locals()) lex = r""" %%%% diff --git a/test/LEX/LEXCOM.py b/test/LEX/LEXCOM.py index ea4626d..7ce8a15 100644 --- a/test/LEX/LEXCOM.py +++ b/test/LEX/LEXCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $LEXCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'lex'], - LEXCOM = r'%s mylex.py $TARGET $SOURCES') + LEXCOM = r'%(_python_)s mylex.py $TARGET $SOURCES') env.CFile(target = 'aaa', source = 'aaa.l') env.CFile(target = 'bbb', source = 'bbb.lex') -""" % python) +""" % locals()) test.write('aaa.l', "aaa.l\n/*lex*/\n") test.write('bbb.lex', "bbb.lex\n/*lex*/\n") diff --git a/test/LEX/LEXCOMSTR.py b/test/LEX/LEXCOMSTR.py index 5b01df7..a06c20c 100644 --- a/test/LEX/LEXCOMSTR.py +++ b/test/LEX/LEXCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when lex is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'lex'], - LEXCOM = r'%s mylex.py $TARGET $SOURCES', + LEXCOM = r'%(_python_)s mylex.py $TARGET $SOURCES', LEXCOMSTR = 'Lexing $TARGET from $SOURCE') env.CFile(target = 'aaa', source = 'aaa.l') env.CFile(target = 'bbb', source = 'bbb.lex') -""" % python) +""" % locals()) test.write('aaa.l', "aaa.l\n/*lex*/\n") test.write('bbb.lex', "bbb.lex\n/*lex*/\n") diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py index 87a869f..5923934 100644 --- a/test/LEX/LEXFLAGS.py +++ b/test/LEX/LEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,9 +52,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', LEXFLAGS = '-x', tools=['default', 'lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', + LEXFLAGS = '-x', + tools=['default', 'lex']) env.Program(target = 'aaa', source = 'aaa.l') -""" % python) +""" % locals()) test.write('aaa.l', r""" int diff --git a/test/LIBPATH.py b/test/LIBPATH.py index c54d2ac..1ea7ed8 100644 --- a/test/LIBPATH.py +++ b/test/LIBPATH.py @@ -57,6 +57,8 @@ env2.Library(target = 'foo2', source = f1) """) test.write('f1.c', r""" +#include <stdio.h> + void f1(void) { @@ -75,6 +77,8 @@ test() """) test.write('prog.c', r""" +#include <stdio.h> + void f1(void); int main(int argc, char *argv[]) @@ -102,6 +106,8 @@ test.fail_test(oldtime1 != os.path.getmtime(prog1)) test.fail_test(oldtime2 != os.path.getmtime(prog2)) test.write('f1.c', r""" +#include <stdio.h> + void f1(void) { @@ -135,6 +141,8 @@ env2.Library(target = 'foo2', source = f1) test.up_to_date(arguments = '.', stderr=None) test.write('f1.c', r""" +#include <stdio.h> + void f1(void) { diff --git a/test/LIBPREFIXES.py b/test/LIBPREFIXES.py index 753b9b3..1e5d6c2 100644 --- a/test/LIBPREFIXES.py +++ b/test/LIBPREFIXES.py @@ -43,6 +43,8 @@ env.Program(target = 'prog', source = ['prog.c', lib]) """) test.write('foo.c', r""" +#include <stdio.h> + void foo(void) { @@ -51,6 +53,8 @@ foo(void) """) test.write('prog.c', r""" +#include <stdio.h> + void foo(void); int main(int argc, char *argv[]) diff --git a/test/LIBS.py b/test/LIBS.py index 3ff26e0..708ce63 100644 --- a/test/LIBS.py +++ b/test/LIBS.py @@ -93,6 +93,7 @@ test.write('foo4.c', foo_contents) test.write('foo5.c', foo_contents) test.write('sl.c', """\ +#include <stdio.h> void sl(void) { @@ -101,6 +102,7 @@ sl(void) """) test.write('slprog.c', """\ +#include <stdio.h> int main(int argc, char *argv[]) { @@ -223,7 +225,7 @@ Program (source='main.c', target='blender', LIBS=libraries, LIBPREFIX='lib', LIB """) test.write('main.c', """\ -#include <stdio.h> +#include <stdlib.h> #include "message2.h" int main (void) diff --git a/test/LIBSUFFIXES.py b/test/LIBSUFFIXES.py index c776ce0..29cbb18 100644 --- a/test/LIBSUFFIXES.py +++ b/test/LIBSUFFIXES.py @@ -43,6 +43,8 @@ env.Program(target = 'prog', source = ['prog.c', lib]) """) test.write('foo.c', r""" +#include <stdio.h> + void foo(void) { @@ -51,6 +53,8 @@ foo(void) """) test.write('prog.c', r""" +#include <stdio.h> + void foo(void); int main(int argc, char *argv[]) diff --git a/test/LINK/LINK.py b/test/LINK/LINK.py index 2d89352..ede03f5 100644 --- a/test/LINK/LINK.py +++ b/test/LINK/LINK.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,12 +45,14 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() link = foo.subst("$LINK") -bar = Environment(LINK = r'%s wrapper.py ' + link) +bar = Environment(LINK = r'%(_python_)s wrapper.py ' + link) foo.Program(target = 'foo', source = 'foo.c') bar.Program(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -61,6 +63,8 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/LINK/LINKCOM.py b/test/LINK/LINKCOM.py index c94d5e3..d914049 100644 --- a/test/LINK/LINKCOM.py +++ b/test/LINK/LINKCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(LINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', OBJSUFFIX = '.obj', PROGSUFFIX = '.exe') env.Program(target = 'test1', source = ['test1.obj', 'test2.obj']) diff --git a/test/LINK/LINKCOMSTR.py b/test/LINK/LINKCOMSTR.py index 70b5c0c..1a7efbe 100644 --- a/test/LINK/LINKCOMSTR.py +++ b/test/LINK/LINKCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(LINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', LINKCOMSTR = 'Linking $TARGET from $SOURCES', OBJSUFFIX = '.obj', PROGSUFFIX = '.exe') diff --git a/test/LINK/LINKFLAGS.py b/test/LINK/LINKFLAGS.py index ca1cd1a..d80960d 100644 --- a/test/LINK/LINKFLAGS.py +++ b/test/LINK/LINKFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,13 +45,15 @@ os.system(string.join(args, " ")) test.write('SConstruct', """ foo = Environment() -bar = Environment(LINK = foo.subst(r'%s wrapper.py $LINK'), +bar = Environment(LINK = foo.subst(r'%(_python_)s wrapper.py $LINK'), LINKFLAGS = foo.subst('$LINKFLAGS fake_link_flag')) foo.Program(target = 'foo', source = 'foo.c') bar.Program(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/LINK/SHLINK.py b/test/LINK/SHLINK.py index 8b9097d..296845c 100644 --- a/test/LINK/SHLINK.py +++ b/test/LINK/SHLINK.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ dll_ = TestSCons.dll_ _shlib = TestSCons._dll @@ -46,10 +46,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() shlink = foo.Dictionary('SHLINK') -bar = Environment(SHLINK = r'%s wrapper.py ' + shlink) +bar = Environment(SHLINK = r'%(_python_)s wrapper.py ' + shlink) foo.SharedLibrary(target = 'foo', source = 'foo.c') bar.SharedLibrary(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" #include <stdio.h> diff --git a/test/LINK/SHLINKCOM.py b/test/LINK/SHLINKCOM.py index d97c4ed..2d2f718 100644 --- a/test/LINK/SHLINKCOM.py +++ b/test/LINK/SHLINKCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,8 +60,8 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCES', - SHLINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCES', + SHLINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', SHOBJSUFFIX = '.obj', SHLIBPREFIX = '', SHLIBSUFFIX = '.dll') diff --git a/test/LINK/SHLINKCOMSTR.py b/test/LINK/SHLINKCOMSTR.py index 1ea29b2..cf31813 100644 --- a/test/LINK/SHLINKCOMSTR.py +++ b/test/LINK/SHLINKCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,8 +61,8 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCES', - SHLINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCES', + SHLINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', SHLINKCOMSTR = 'Linking shared $TARGET from $SOURCES', SHOBJSUFFIX = '.obj', SHLIBPREFIX = '', @@ -85,8 +85,8 @@ test2.c """) test.run(stdout = test.wrap_stdout("""\ -%(python)s mycc.py test1.obj test1.c -%(python)s mycc.py test2.obj test2.c +%(_python_)s mycc.py test1.obj test1.c +%(_python_)s mycc.py test2.obj test2.c Linking shared test3.dll from test1.obj test2.obj """ % locals())) diff --git a/test/LINK/SHLINKFLAGS.py b/test/LINK/SHLINKFLAGS.py index 709ebc6..51a8f7c 100644 --- a/test/LINK/SHLINKFLAGS.py +++ b/test/LINK/SHLINKFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ lib_ = TestSCons.dll_ _shlib = TestSCons._dll @@ -46,11 +46,11 @@ os.system(string.join(args, " ")) test.write('SConstruct', """ foo = Environment() -bar = Environment(SHLINK = foo.subst(r'%s wrapper.py $SHLINK'), +bar = Environment(SHLINK = foo.subst(r'%(_python_)s wrapper.py $SHLINK'), SHLINKFLAGS = foo.subst('$SHLINKFLAGS fake_shlink_flag')) foo.SharedLibrary(target = 'foo', source = 'foo.c') bar.SharedLibrary(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" #include <stdio.h> diff --git a/test/Library.py b/test/Library.py index e4626ab..3a04b9c 100644 --- a/test/Library.py +++ b/test/Library.py @@ -38,6 +38,7 @@ env.Program(target = 'prog', source = [ 'prog.cpp', libtgt ]) """) test.write('f1.c', r""" +#include <stdio.h> void f1(void) { @@ -46,6 +47,7 @@ f1(void) """) test.write('f2a.c', r""" +#include <stdio.h> void f2a(void) { @@ -54,6 +56,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include <stdio.h> void f2b(void) { @@ -62,6 +65,7 @@ f2b(void) """) test.write('f2c.c', r""" +#include <stdio.h> void f2c(void) { @@ -70,6 +74,7 @@ f2c(void) """) test.write('f3a.c', r""" +#include <stdio.h> void f3a(void) { @@ -78,6 +83,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include <stdio.h> void f3b(void) { diff --git a/test/M4/M4.py b/test/M4/M4.py index bf56e74..859c57b 100644 --- a/test/M4/M4.py +++ b/test/M4/M4.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,9 +49,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(M4 = r'%s mym4.py', tools=['default', 'm4']) +env = Environment(M4 = r'%(_python_)s mym4.py', tools=['default', 'm4']) env.M4(target = 'aaa.x', source = 'aaa.x.m4') -""" % python) +""" % locals()) test.write('aaa.x.m4', """\ line 1 @@ -80,7 +80,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(M4=r'%(m4)s', M4FLAGS='-DFFF=fff') m4 = foo.Dictionary('M4') -bar = Environment(M4 = r'%(python)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb') +bar = Environment(M4 = r'%(_python_)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb') foo.M4(target = 'foo.x', source = 'foo.x.m4') bar.M4(target = 'bar', source = 'bar.m4') """ % locals()) diff --git a/test/M4/M4COM.py b/test/M4/M4COM.py index d1c53b4..8c36d86 100644 --- a/test/M4/M4COM.py +++ b/test/M4/M4COM.py @@ -30,7 +30,7 @@ Test the ability to configure the $M4COM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'm4'], - M4COM = r'%s mym4.py $TARGET $SOURCES') + M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES') env.M4(target = 'aaa.out', source = 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*m4*/\n") diff --git a/test/M4/M4COMSTR.py b/test/M4/M4COMSTR.py index 0e14495..a9e91e6 100644 --- a/test/M4/M4COMSTR.py +++ b/test/M4/M4COMSTR.py @@ -31,7 +31,7 @@ the displayed string when m4 is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'm4'], - M4COM = r'%s mym4.py $TARGET $SOURCES', + M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES', M4COMSTR = 'M4ing $TARGET from $SOURCE') env.M4(target = 'aaa.out', source = 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*m4*/\n") diff --git a/test/MSVC/PCHCOM.py b/test/MSVC/PCHCOM.py index 593a1c1..2473391 100644 --- a/test/MSVC/PCHCOM.py +++ b/test/MSVC/PCHCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $MIDLCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - PCHCOM = r'%s mypch.py $TARGET $SOURCES') + PCHCOM = r'%(_python_)s mypch.py $TARGET $SOURCES') env.PCH(target = 'aaa', source = 'aaa.h') -""" % python) +""" % locals()) test.write('aaa.h', "aaa.h\n/*pch*/\n") diff --git a/test/MSVC/PCHCOMSTR.py b/test/MSVC/PCHCOMSTR.py index c5ab9f5..23322d4 100644 --- a/test/MSVC/PCHCOMSTR.py +++ b/test/MSVC/PCHCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when pch is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - PCHCOM = r'%s mypch.py $TARGET $SOURCES', + PCHCOM = r'%(_python_)s mypch.py $TARGET $SOURCES', PCHCOMSTR = 'PCHing $TARGET from $SOURCE') env.PCH(target = 'aaa', source = 'aaa.h') -""" % python) +""" % locals()) test.write('aaa.h', "aaa.h\n/*pch*/\n") diff --git a/test/MSVC/RCCOM.py b/test/MSVC/RCCOM.py index 3262f0c..e881bb5 100644 --- a/test/MSVC/RCCOM.py +++ b/test/MSVC/RCCOM.py @@ -31,7 +31,7 @@ when using MSVC. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES') + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/MSVC/RCCOMSTR.py b/test/MSVC/RCCOMSTR.py index 33e192b..96ccee0 100644 --- a/test/MSVC/RCCOMSTR.py +++ b/test/MSVC/RCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when rc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES', + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES', RCCOMSTR = 'RCing $TARGET from $SOURCE') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/MSVC/generate-rc.py b/test/MSVC/generate-rc.py new file mode 100644 index 0000000..0b3c332 --- /dev/null +++ b/test/MSVC/generate-rc.py @@ -0,0 +1,70 @@ +#!/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 adding a src_builder to the RES builder so that RC files can +be generated. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +fake_rc = test.workpath('fake_rc.py') + +test.write(fake_rc, """\ +import sys +contents = open(sys.argv[2], 'rb').read() +open(sys.argv[1], 'wb').write("fake_rc.py\\n" + contents) +""") + +test.write('SConstruct', """ +def generate_rc(target, source, env): + t = str(target[0]) + s = str(source[0]) + tfp = open(t, 'wb') + tfp.write('generate_rc\\n' + open(s, 'r').read()) + +env = Environment(tools=['msvc'], + RCCOM=r'%(_python_)s %(fake_rc)s $TARGET $SOURCE') +env['BUILDERS']['GenerateRC'] = Builder(action=generate_rc, + suffix='.rc', + src_suffix='.in') +env['BUILDERS']['RES'].src_builder.append('GenerateRC') + +env.RES('my.in') +""" % locals()) + +test.write('my.in', "my.in\n") + +test.run(arguments = '.') + +test.must_match('my.rc', "generate_rc\nmy.in\n") +test.must_match('my.res', "fake_rc.py\ngenerate_rc\nmy.in\n") + +test.pass_test() diff --git a/test/MSVC/msvc.py b/test/MSVC/msvc.py index dd0f5ca..857b6bd 100644 --- a/test/MSVC/msvc.py +++ b/test/MSVC/msvc.py @@ -24,13 +24,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons -import sys -import os.path import os -import TestCmd +import os.path +import re +import sys import time +import TestCmd +import TestSCons + test = TestSCons.TestSCons(match = TestCmd.match_re) if sys.platform != 'win32': @@ -234,30 +236,36 @@ test.must_not_exist(test.workpath('build/StdAfx.obj')) ##### # Test error reporting -test.write('SConstruct',""" -env=Environment() +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """\ +env = Environment() env['PDB'] = File('test.pdb') env['PCH'] = env.PCH('StdAfx.cpp')[0] env.Program('test', 'test.cpp') """) -test.run(status=2, stderr=''' +expect_stderr = r''' scons: \*\*\* The PCHSTOP construction must be defined if PCH is defined. -File "SConstruct", line 5, in \? -''') +File "%s", line 4, in \? +''' % re.escape(SConstruct_path) -test.write('SConstruct',""" -env=Environment() +test.run(status=2, stderr=expect_stderr) + +test.write(SConstruct_path, """\ +env = Environment() env['PDB'] = File('test.pdb') env['PCHSTOP'] = File('StdAfx.h') env['PCH'] = env.PCH('StdAfx.cpp')[0] env.Program('test', 'test.cpp') """) -test.run(status=2, stderr=''' +expect_stderr = r''' scons: \*\*\* The PCHSTOP construction variable must be a string: .+ -File "SConstruct", line 6, in \? -''') +File "%s", line 5, in \? +''' % re.escape(SConstruct_path) + +test.run(status=2, stderr=expect_stderr) test.pass_test() diff --git a/test/MSVS/common-prefix.py b/test/MSVS/common-prefix.py index 6f508c9..d40060c 100644 --- a/test/MSVS/common-prefix.py +++ b/test/MSVS/common-prefix.py @@ -43,7 +43,7 @@ if sys.platform != 'win32': msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform test.skip_test(msg) -expected_vcprojfile = """\ +vcproj_template = """\ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject \tProjectType="Visual C++" @@ -84,21 +84,7 @@ expected_vcprojfile = """\ \t</Configurations> \t<References> \t</References> -\t<Files> -\t\t\t<Filter -\t\t\t\tName="subdir" -\t\t\t\tFilter=""> -\t\t\t<File -\t\t\t\tRelativePath="subdir\\test1.cpp"> -\t\t\t</File> -\t\t\t<File -\t\t\t\tRelativePath="subdir\\test2.cpp"> -\t\t\t</File> -\t\t\t</Filter> -\t\t<File -\t\t\tRelativePath="<SCONSCRIPT>"> -\t\t</File> -\t</Files> +%(sln_files)s \t<Globals> \t</Globals> </VisualStudioProject> @@ -107,9 +93,9 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') -testsrc = ['subdir/test1.cpp', r'subdir\\test2.cpp'] +testsrc = %(testsrc)s env.MSVSProject(target = 'Test.vcproj', slnguid = '{SLNGUID}', @@ -123,16 +109,74 @@ env.MSVSProject(target = 'Test.vcproj', test.subdir('work1') -test.write(['work1', 'SConstruct'], SConscript_contents) +testsrc = repr([ + 'prefix/subdir1/test1.cpp', + r'prefix\subdir1\test2.cpp', + 'prefix/subdir2/test3.cpp', +]) + +sln_files = """\t<Files> +\t\t\t<Filter +\t\t\t\tName="subdir1" +\t\t\t\tFilter=""> +\t\t\t<File +\t\t\t\tRelativePath="prefix\\subdir1\\test1.cpp"> +\t\t\t</File> +\t\t\t<File +\t\t\t\tRelativePath="prefix\\subdir1\\test2.cpp"> +\t\t\t</File> +\t\t\t</Filter> +\t\t\t<Filter +\t\t\t\tName="subdir2" +\t\t\t\tFilter=""> +\t\t\t<File +\t\t\t\tRelativePath="prefix\\subdir2\\test3.cpp"> +\t\t\t</File> +\t\t\t</Filter> +\t\t<File +\t\t\tRelativePath="<SCONSCRIPT>"> +\t\t</File> +\t</Files>""" + +test.write(['work1', 'SConstruct'], SConscript_contents % locals()) test.run(chdir='work1', arguments="Test.vcproj") test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') +expected_vcprojfile = vcproj_template % locals() expect = test.msvs_substitute(expected_vcprojfile, '8.0', 'work1', 'SConstruct') # don't compare the pickled data assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj) +test.subdir('work2') + +testsrc = repr([ + 'prefix/subdir/somefile.cpp', +]) + +sln_files = """\t<Files> +\t\t\t<File +\t\t\t\tRelativePath="prefix\\subdir\\somefile.cpp"> +\t\t\t</File> +\t\t<File +\t\t\tRelativePath="<SCONSCRIPT>"> +\t\t</File> +\t</Files>""" + +test.write(['work2', 'SConstruct'], SConscript_contents % locals()) + +test.run(chdir='work2', arguments="Test.vcproj") + +test.must_exist(test.workpath('work2', 'Test.vcproj')) +vcproj = test.read(['work2', 'Test.vcproj'], 'r') +expected_vcprojfile = vcproj_template % locals() +expect = test.msvs_substitute(expected_vcprojfile, '8.0', 'work2', 'SConstruct') +# don't compare the pickled data +assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj) + + + test.pass_test() diff --git a/test/MSVS/runfile.py b/test/MSVS/runfile.py index 581de64..5638916 100644 --- a/test/MSVS/runfile.py +++ b/test/MSVS/runfile.py @@ -100,7 +100,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') env.MSVSProject(target = 'Test.vcproj', slnguid = '{SLNGUID}', diff --git a/test/MSVS/vs-6.0-files.py b/test/MSVS/vs-6.0-files.py index 135bb7f..ce7ef46 100644 --- a/test/MSVS/vs-6.0-files.py +++ b/test/MSVS/vs-6.0-files.py @@ -184,7 +184,7 @@ Package=<3> SConscript_contents = """\ -env=Environment(MSVS_VERSION = '6.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '6.0') testsrc = ['test.c'] testincs = ['sdk.h'] @@ -278,7 +278,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '6.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '6.0') testsrc = ['test.c'] testincs = ['sdk.h'] diff --git a/test/MSVS/vs-7.0-files.py b/test/MSVS/vs-7.0-files.py index 8c82d1a..8f98166 100644 --- a/test/MSVS/vs-7.0-files.py +++ b/test/MSVS/vs-7.0-files.py @@ -144,7 +144,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '7.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -206,7 +206,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' test.run(chdir='work1', arguments='Test.vcproj') -python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1]) test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') @@ -260,7 +260,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '7.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] diff --git a/test/MSVS/vs-7.1-files.py b/test/MSVS/vs-7.1-files.py index bbe6f1e..3ad2e97 100644 --- a/test/MSVS/vs-7.1-files.py +++ b/test/MSVS/vs-7.1-files.py @@ -146,7 +146,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '7.1') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.1') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -208,7 +208,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' test.run(chdir='work1', arguments='Test.vcproj') -python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1]) test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') @@ -262,7 +262,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '7.1') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.1') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] diff --git a/test/MSVS/vs-8.0-files.py b/test/MSVS/vs-8.0-files.py index 878aa3f..1d3c469 100644 --- a/test/MSVS/vs-8.0-files.py +++ b/test/MSVS/vs-8.0-files.py @@ -153,7 +153,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -215,7 +215,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' test.run(chdir='work1', arguments='Test.vcproj') -python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1]) test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') @@ -273,7 +273,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] diff --git a/test/MinGW/RCCOM.py b/test/MinGW/RCCOM.py index 4ddcd91..2db0563 100644 --- a/test/MinGW/RCCOM.py +++ b/test/MinGW/RCCOM.py @@ -31,7 +31,7 @@ when using MinGW. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES') + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/MinGW/RCCOMSTR.py b/test/MinGW/RCCOMSTR.py index e095847..96565f1 100644 --- a/test/MinGW/RCCOMSTR.py +++ b/test/MinGW/RCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when rc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES', + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES', RCCOMSTR = 'RCing $TARGET from $SOURCE') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/NodeOps.py b/test/NodeOps.py index 9f548c4..ff3e0ca 100644 --- a/test/NodeOps.py +++ b/test/NodeOps.py @@ -47,13 +47,6 @@ _lib = TestSCons._lib _obj = TestSCons._obj dll_ = TestSCons.dll_ _dll = TestSCons._dll - -if sys.platform == 'win32': - fooflags = '/nologo -DFOO' - barflags = '/nologo -DBAR' -else: - fooflags = '-DFOO' - barflags = '-DBAR' if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' @@ -62,6 +55,10 @@ if string.find(sys.platform, 'irix') > -1: test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCXXFLAGS'] + ' -DFOO' +barflags = e['SHCXXFLAGS'] + ' -DBAR' + test.subdir('bld', 'src', ['src', 'subsrcdir']) sconstruct = r""" diff --git a/test/Object.py b/test/Object.py index 8b9c5e0..da945e3 100644 --- a/test/Object.py +++ b/test/Object.py @@ -46,6 +46,7 @@ env.Program(target = 'prog3', source = ['f1%s', f2, 'f3%s', 'prog.cpp']) """ % (_obj, _obj, _obj, _obj, _obj, _obj)) test.write('f1.c', r""" +#include <stdio.h> void f1(void) { @@ -64,6 +65,7 @@ f2(void) """) test.write('f3.c', r""" +#include <stdio.h> void f3(void) { @@ -72,6 +74,7 @@ f3(void) """) test.write('f4.c', r""" +#include <stdio.h> void f4(void) { @@ -80,6 +83,7 @@ f4(void) """) test.write('f5.c', r""" +#include <stdio.h> void f5(void) { diff --git a/test/Options/BoolOption.py b/test/Options/BoolOption.py index ef6491d..7af9bfd 100644 --- a/test/Options/BoolOption.py +++ b/test/Options/BoolOption.py @@ -35,13 +35,15 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import BoolOption opts = Options(args=ARGUMENTS) @@ -59,18 +61,21 @@ print env['profile'] Default(env.Alias('dummy', None)) """) + + test.run() check(['1', '0']) test.run(arguments='warnings=0 profile=no profile=true') check(['0', '1']) -test.run(arguments='warnings=irgendwas', - stderr = """ +expect_stderr = """ scons: *** Error converting option: warnings Invalid value for boolean option: irgendwas -File "SConstruct", line 10, in ? -""", status=2) +File "%(SConstruct_path)s", line 9, in ? +""" % locals() + +test.run(arguments='warnings=irgendwas', stderr = expect_stderr, status=2) diff --git a/test/Options/EnumOption.py b/test/Options/EnumOption.py index c47f7d5..5e29477 100644 --- a/test/Options/EnumOption.py +++ b/test/Options/EnumOption.py @@ -35,13 +35,15 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import EnumOption list_of_libs = Split('x11 gl qt ical') @@ -71,28 +73,33 @@ Default(env.Alias('dummy', None)) test.run(); check(['no', 'gtk', 'xaver']) + test.run(arguments='debug=yes guilib=Motif some=xAVER') check(['yes', 'Motif', 'xaver']) + test.run(arguments='debug=full guilib=KdE some=EiNs') check(['full', 'KdE', 'eins']) -test.run(arguments='debug=FULL', - stderr = """ +expect_stderr = """ scons: *** Invalid value for option debug: FULL -File "SConstruct", line 19, in ? -""", status=2) +File "%(SConstruct_path)s", line 18, in ? +""" % locals() -test.run(arguments='guilib=IrGeNdwas', - stderr = """ +test.run(arguments='debug=FULL', stderr=expect_stderr, status=2) + +expect_stderr = """ scons: *** Invalid value for option guilib: irgendwas -File "SConstruct", line 19, in ? -""", status=2) +File "%(SConstruct_path)s", line 18, in ? +""" % locals() + +test.run(arguments='guilib=IrGeNdwas', stderr=expect_stderr, status=2) -test.run(arguments='some=IrGeNdwas', - stderr = """ +expect_stderr = """ scons: *** Invalid value for option some: irgendwas -File "SConstruct", line 19, in ? -""", status=2) +File "%(SConstruct_path)s", line 18, in ? +""" % locals() + +test.run(arguments='some=IrGeNdwas', stderr=expect_stderr, status=2) test.pass_test() diff --git a/test/Options/ListOption.py b/test/Options/ListOption.py index 5dbe0c3..fddfc5f 100644 --- a/test/Options/ListOption.py +++ b/test/Options/ListOption.py @@ -35,13 +35,16 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') - assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) + r = result[1:len(expect)+1] + assert r == expect, (r, expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import ListOption list_of_libs = Split('x11 gl qt ical') @@ -70,56 +73,69 @@ Default(env.Alias('dummy', None)) test.run() check(['all', '1', 'gl ical qt x11', 'gl ical qt x11']) + test.run(arguments='shared=none') check(['none', '0', '', '']) + test.run(arguments='shared=') check(['none', '0', '', '']) + test.run(arguments='shared=x11,ical') check(['ical,x11', '1', 'ical x11', 'ical x11']) + test.run(arguments='shared=x11,,ical,,') check(['ical,x11', '1', 'ical x11', 'ical x11']) + test.run(arguments='shared=GL') check(['gl', '0', 'gl', 'gl']) + test.run(arguments='shared=QT,GL') check(['gl,qt', '0', 'gl qt', 'gl qt']) -test.run(arguments='shared=foo', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=foo', stderr=expect_stderr, status=2) # be paranoid in testing some more combinations -test.run(arguments='shared=foo,ical', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=foo,ical', stderr=expect_stderr, status=2) -test.run(arguments='shared=ical,foo', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() -test.run(arguments='shared=ical,foo,x11', - stderr = """ +test.run(arguments='shared=ical,foo', stderr=expect_stderr, status=2) + +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=ical,foo,x11', stderr=expect_stderr, status=2) -test.run(arguments='shared=foo,x11,,,bar', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo,bar -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=foo,x11,,,bar', stderr=expect_stderr, status=2) + + test.write('SConstruct', """ from SCons.Options import ListOption diff --git a/test/Options/PackageOption.py b/test/Options/PackageOption.py index cc520f7..81f7003 100644 --- a/test/Options/PackageOption.py +++ b/test/Options/PackageOption.py @@ -35,13 +35,15 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import PackageOption opts = Options(args=ARGUMENTS) @@ -64,11 +66,12 @@ test.run(arguments='x11=no'); check(['0']) test.run(arguments='x11=0'); check(['0']) test.run(arguments=['x11=%s' % test.workpath()]); check([test.workpath()]) -test.run(arguments='x11=/non/existing/path/', - stderr = """ +expect_stderr = """ scons: *** Path does not exist for option x11: /non/existing/path/ -File "SConstruct", line 11, in ? -""", status=2) +File "%(SConstruct_path)s", line 10, in ? +""" % locals() + +test.run(arguments='x11=/non/existing/path/', stderr=expect_stderr, status=2) diff --git a/test/Options/PathOption.py b/test/Options/PathOption.py index d15f39b..d22071e 100644 --- a/test/Options/PathOption.py +++ b/test/Options/PathOption.py @@ -36,6 +36,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) @@ -46,7 +48,7 @@ test.subdir('lib', 'qt', ['qt', 'lib'], 'nolib' ) workpath = test.workpath() libpath = os.path.join(workpath, 'lib') -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import PathOption qtdir = r'%s' @@ -88,17 +90,20 @@ test.run(arguments=['qtdir=%s' % qtpath, 'qt_libraries=%s' % libpath]) check([qtpath, libpath, libpath]) qtpath = os.path.join(workpath, 'non', 'existing', 'path') -test.run(arguments=['qtdir=%s' % qtpath], - stderr = """ -scons: *** Path for option qtdir does not exist: %s -File "SConstruct", line 12, in ? -""" % qtpath, status=2) -test.run(arguments=['qt_libraries=%s' % qtpath], - stderr = """ -scons: *** Path for option qt_libraries does not exist: %s -File "SConstruct", line 12, in ? -""" % qtpath, status=2) +expect_stderr = """ +scons: *** Path for option qtdir does not exist: %(qtpath)s +File "%(SConstruct_path)s", line 11, in ? +""" % locals() + +test.run(arguments=['qtdir=%s' % qtpath], stderr=expect_stderr, status=2) + +expect_stderr = """ +scons: *** Path for option qt_libraries does not exist: %(qtpath)s +File "%(SConstruct_path)s", line 11, in ? +""" % locals() + +test.run(arguments=['qt_libraries=%s' % qtpath], stderr=expect_stderr, status=2) @@ -149,7 +154,7 @@ test.must_not_exist(non_existing_subdir) -test.write('SConstruct', """\ +test.write(SConstruct_path, """\ opts = Options(args=ARGUMENTS) opts.AddOptions( PathOption('X', 'X variable', r'%s', validator=PathOption.PathIsFile), @@ -162,33 +167,34 @@ print env['X'] Default(env.Alias('dummy', None)) """ % default_file) -test.run(status=2, - stderr=""" -scons: *** File path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % default_file) +expect_stderr = """ +scons: *** File path for option X does not exist: %(default_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(status=2, stderr=expect_stderr) test.write(default_file, "default_file\n") test.run() check([default_file]) -test.run(arguments=['X=%s' % existing_subdir], - status=2, - stderr=""" -scons: *** File path for option X is a directory: %s -File "SConstruct", line 6, in ? -""" % existing_subdir) +expect_stderr = """ +scons: *** File path for option X is a directory: %(existing_subdir)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(arguments=['X=%s' % existing_subdir], status=2, stderr=expect_stderr) test.run(arguments=['X=%s' % existing_file]) check([existing_file]) -test.run(arguments=['X=%s' % non_existing_file], - status=2, - stderr=""" -scons: *** File path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % non_existing_file) +expect_stderr = """ +scons: *** File path for option X does not exist: %(non_existing_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(arguments=['X=%s' % non_existing_file], status=2, stderr=expect_stderr) @@ -205,33 +211,38 @@ print env['X'] Default(env.Alias('dummy', None)) """ % default_subdir) -test.run(status=2, - stderr=""" -scons: *** Directory path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % default_subdir) +expect_stderr = """ +scons: *** Directory path for option X does not exist: %(default_subdir)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(status=2, stderr=expect_stderr) test.subdir(default_subdir) test.run() check([default_subdir]) +expect_stderr = """ +scons: *** Directory path for option X is a file: %(existing_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + test.run(arguments=['X=%s' % existing_file], status=2, - stderr=""" -scons: *** Directory path for option X is a file: %s -File "SConstruct", line 6, in ? -""" % existing_file) + stderr=expect_stderr) test.run(arguments=['X=%s' % existing_subdir]) check([existing_subdir]) +expect_stderr = """ +scons: *** Directory path for option X does not exist: %(non_existing_subdir)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + test.run(arguments=['X=%s' % non_existing_subdir], status=2, - stderr=""" -scons: *** Directory path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % non_existing_subdir) + stderr=expect_stderr) @@ -251,12 +262,12 @@ Default(env.Alias('dummy', None)) test.run() check([default_subdir]) -test.run(arguments=['X=%s' % existing_file], - status=2, - stderr=""" -scons: *** Path for option X is a file, not a directory: %s -File "SConstruct", line 6, in ? -""" % existing_file) +expect_stderr = """ +scons: *** Path for option X is a file, not a directory: %(existing_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(arguments=['X=%s' % existing_file], status=2, stderr=expect_stderr) test.run(arguments=['X=%s' % existing_subdir]) check([existing_subdir]) diff --git a/test/ParseConfig.py b/test/ParseConfig.py index 55678fe..668d08a 100644 --- a/test/ParseConfig.py +++ b/test/ParseConfig.py @@ -30,7 +30,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,8 +57,8 @@ print "-L foo -L lib_dir -isysroot /tmp -arch ppc -arch i386" test.write('SConstruct', """ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '') -env.ParseConfig([r"%(python)s", r"%(test_config1)s", "--libs --cflags"]) -env.ParseConfig([r"%(python)s", r"%(test_config2)s", "--libs --cflags"]) +env.ParseConfig([r'%(_python_)s', r"%(test_config1)s", "--libs --cflags"]) +env.ParseConfig([r'%(_python_)s', r"%(test_config2)s", "--libs --cflags"]) print env['CPPPATH'] print env['LIBPATH'] print map(lambda x: str(x), env['LIBS']) @@ -67,7 +67,7 @@ print env['CCFLAGS'] test.write('SConstruct2', """ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '', - PYTHON = '%(python)s') + PYTHON = '%(_python_)s') env.ParseConfig(r"$PYTHON %(test_config1)s --libs --cflags") env.ParseConfig(r"$PYTHON %(test_config2)s --libs --cflags") print env['CPPPATH'] @@ -78,7 +78,7 @@ print env['CCFLAGS'] test.write('SConstruct3', """ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '', - PYTHON = '%(python)s') + PYTHON = '%(_python_)s') env.ParseConfig(r"$PYTHON %(test_config3)s --libs --cflags") print env['CPPPATH'] print env['LIBPATH'] diff --git a/test/ParseDepends.py b/test/ParseDepends.py index 9a9910a..e979b91 100644 --- a/test/ParseDepends.py +++ b/test/ParseDepends.py @@ -29,7 +29,7 @@ import string import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,8 +44,8 @@ file.close() """) test.write('SConstruct', """ -Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep") -Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep") +Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep') +Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep') env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir') env.ParseDepends('foo.d') env.ParseDepends('bar.d') @@ -55,7 +55,7 @@ env.Bar(target = 'subdir/f3.out', source = 'f3.in') SConscript('subdir/SConscript', "env") env.Foo(target = 'f5.out', source = 'f5.in') env.Bar(target = 'sub2/f6.out', source = 'f6.in') -""" % (python, python)) +""" % locals()) test.write('foo.d', "f1.out f2.out: %s\n" % os.path.join('subdir', 'foo.dep')) test.write('bar.d', "%s: %s\nf5.out: sub2" % (os.path.join('subdir', 'f3.out'), diff --git a/test/Perforce/P4COM.py b/test/Perforce/P4COM.py index c33254a..11b28e3 100644 --- a/test/Perforce/P4COM.py +++ b/test/Perforce/P4COM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'Perforce'], BUILDERS={'Cat':Builder(action=cat)}, - P4COM='%(python)s my-p4.py $TARGET') + P4COM='%(_python_)s my-p4.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['Perforce', 'sub', 'fff.in'], "Perforce/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-p4.py %(sub_SConscript)s +%(_python_)s my-p4.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-p4.py aaa.in +%(_python_)s my-p4.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-p4.py ccc.in +%(_python_)s my-p4.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-p4.py %(sub_ddd_in)s +%(_python_)s my-p4.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-p4.py %(sub_fff_in)s +%(_python_)s my-p4.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/Perforce/P4COMSTR.py b/test/Perforce/P4COMSTR.py index d9a3bc0..72f05b8 100644 --- a/test/Perforce/P4COMSTR.py +++ b/test/Perforce/P4COMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'Perforce'], BUILDERS={'Cat':Builder(action=cat)}, - P4COM='%(python)s my-p4.py $TARGET', + P4COM='%(_python_)s my-p4.py $TARGET', P4COMSTR='Checking out $TARGET from our fake Perforce') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/Perforce/Perforce.py b/test/Perforce/Perforce.py index f813f10..0133ced 100644 --- a/test/Perforce/Perforce.py +++ b/test/Perforce/Perforce.py @@ -32,7 +32,6 @@ on port 1666, as well as that of course a client must be present. """ import os -import socket import string import TestSCons @@ -41,11 +40,13 @@ class TestPerforce(TestSCons.TestSCons): def __init__(self, *args, **kw): apply(TestSCons.TestSCons.__init__, (self,)+args, kw) - self._p4prog = self.where_is('p4') - if not self._p4prog: + self.p4path = self.where_is('p4') + if not self.p4path: self.skip_test("Could not find 'p4'; skipping test(s).\n") - self.host = socket.gethostname() + #import socket + #self.host = socket.gethostname() + self.host = '127.0.0.1' self.user = os.environ.get('USER') if not self.user: @@ -98,7 +99,7 @@ class TestPerforce(TestSCons.TestSCons): arguments = args[0] args = args[1:] kw['arguments'] = string.join(self.p4portflags + [arguments]) - kw['program'] = self._p4prog + kw['program'] = self.p4path return apply(self.run, args, kw) def substitute(self, s, **kw): @@ -145,8 +146,6 @@ Client: %(client)s Owner: %(user)s -Host: %(host)s - Description: Created by %(user)s. @@ -234,7 +233,9 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(BUILDERS={'Cat':Builder(action=cat)}, +env = Environment(tools = ['default', 'Perforce'], + BUILDERS={'Cat':Builder(action=cat)}, + P4=r'%(p4path)s', P4FLAGS='%(portflag)s -c testclient2') env.Cat('aaa.out', 'foo/aaa.in') env.Cat('bbb.out', 'foo/bbb.in') diff --git a/test/Precious.py b/test/Precious.py index 940fab7..76aa2a4 100644 --- a/test/Precious.py +++ b/test/Precious.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -39,17 +39,18 @@ import sys sys.exit(0) """) +SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out') + test.write('SConstruct', """\ -B = Builder(action = r"%s build.py $TARGET $SOURCES") +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }, SUBDIR = 'subdir') f1 = env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') env.B(target = 'subdir/f4.out', source = 'f4.in') -env.Precious(f1, 'f2.out', r'%s') +env.Precious(f1, 'f2.out', r'%(SUBDIR_f4_out)s') SConscript('subdir/SConscript', "env") -""" % (python, - os.path.join('$SUBDIR', 'f4.out'))) +""" % locals()) test.write(['subdir', 'SConscript'], """ Import("env") diff --git a/test/Program-j.py b/test/Program-j.py index fe778b3..d8180bb 100644 --- a/test/Program-j.py +++ b/test/Program-j.py @@ -45,6 +45,8 @@ env.Program(target = 'f4', source = 'f4.c') """) test.write('f1.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -55,6 +57,9 @@ main(int argc, char *argv[]) """) test.write('f2.c', r""" +#include <stdio.h> +#include <stdlib.h> + int main(int argc, char *argv[]) { @@ -66,6 +71,8 @@ main(int argc, char *argv[]) test.write('f3.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -76,6 +83,8 @@ main(int argc, char *argv[]) """) test.write('f4.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/Program.py b/test/Program.py index 5b785a3..cf98148 100644 --- a/test/Program.py +++ b/test/Program.py @@ -52,6 +52,8 @@ env.Program('foo5.c') """) test.write('f1.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('f2a.c', r""" +#include <stdio.h> +#include <stdlib.h> void f2a(void) { @@ -70,6 +74,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include <stdio.h> void f2b(void) { @@ -78,6 +83,8 @@ f2b(void) """) test.write('f2c.c', r""" +#include <stdio.h> +#include <stdlib.h> extern void f2a(void); extern void f2b(void); int @@ -92,6 +99,7 @@ main(int argc, char *argv[]) """) test.write('f3a.c', r""" +#include <stdio.h> void f3a(void) { @@ -100,6 +108,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include <stdio.h> void f3b(void) { @@ -108,6 +117,8 @@ f3b(void) """) test.write('f3c.c', r""" +#include <stdio.h> +#include <stdlib.h> extern void f3a(void); extern void f3b(void); int @@ -122,6 +133,8 @@ main(int argc, char *argv[]) """) test.write('f4.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -132,6 +145,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -152,6 +167,8 @@ test.run(program = foo5, stdout = "foo5.c\n") test.up_to_date(arguments = '.') test.write('f1.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -162,6 +179,7 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include <stdio.h> void f3b(void) { @@ -170,6 +188,8 @@ f3b(void) """) test.write('f4.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -180,6 +200,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -217,6 +239,8 @@ test.fail_test(oldtime4 != os.path.getmtime(foo4)) test.fail_test(oldtime5 != os.path.getmtime(foo5)) test.write('f1.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -227,6 +251,8 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include <stdio.h> +#include <stdlib.h> void f3b(void) { @@ -235,6 +261,8 @@ f3b(void) """) test.write('f4.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -245,6 +273,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -265,6 +295,8 @@ test.run(program = foo5, stdout = "foo5.c Y\n") test.up_to_date(arguments = foo_args) test.write('f1.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -275,6 +307,8 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include <stdio.h> +#include <stdlib.h> void f3b(void) { @@ -283,6 +317,8 @@ f3b(void) """) test.write('f4.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -293,6 +329,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py index f9cb917..ba08739 100644 --- a/test/QT/QTFLAGS.py +++ b/test/QT/QTFLAGS.py @@ -31,7 +31,7 @@ Testing the configuration mechanisms of the 'qt' tool. import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -123,8 +123,8 @@ test.run(chdir=test.workpath('qt','lib'), arguments = '.', QT = test.workpath('qt') QT_LIB = 'myqt' -QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py')) -QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py')) +QT_MOC = '%s %s' % (_python_, test.workpath('qt','bin','mymoc.py')) +QT_UIC = '%s %s' % (_python_, test.workpath('qt','bin','myuic.py')) def createSConstruct(test,place,overrides): test.write(place, """ diff --git a/test/QT/moc-from-header.py b/test/QT/moc-from-header.py index 0bf6873..1dbcd0f 100644 --- a/test/QT/moc-from-header.py +++ b/test/QT/moc-from-header.py @@ -28,6 +28,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Create a moc file from a header file. """ +import os + import TestSCons test = TestSCons.TestSCons() @@ -38,6 +40,10 @@ env = Environment() test.Qt_dummy_installation() +# We'll run some test programs later that need to find our dummy +# Qt library. +os.environ['LD_LIBRARY_PATH'] = test.QT_LIB_DIR + ############################################################################## aaa_exe = 'aaa' + TestSCons._exe diff --git a/test/QT/warnings.py b/test/QT/warnings.py index 7b41360..0fd3f66 100644 --- a/test/QT/warnings.py +++ b/test/QT/warnings.py @@ -29,15 +29,18 @@ Test the Qt tool warnings. """ import os +import re import string import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + test.Qt_dummy_installation() -test.Qt_create_SConstruct('SConstruct') +test.Qt_create_SConstruct(SConstruct_path) test.write('aaa.cpp', r""" #include "my_qobject.h" @@ -77,15 +80,19 @@ test.run(stderr=None, arguments='-n noqtdir=1') moc = test.where_is('moc') if moc: import os.path + qtdir = os.path.dirname(os.path.dirname(moc)) + qtdir = string.replace(qtdir, '\\', '\\\\' ) + expect = """ scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\) -File "SConstruct", line \d+, in \? -""" % string.replace( os.path.dirname(os.path.dirname(moc)), '\\', '\\\\' ) +File "%s", line \d+, in \? +""" % (qtdir, re.escape(SConstruct_path)) else: + expect = """ scons: warning: Could not detect qt, using empty QTDIR -File "SConstruct", line \d+, in \? -""" +File "%s", line \d+, in \? +""" % re.escape(SConstruct_path) test.fail_test(not test.match_re(test.stderr(), expect)) diff --git a/test/RANLIB/RANLIB.py b/test/RANLIB/RANLIB.py index 5002b20..75e860a 100644 --- a/test/RANLIB/RANLIB.py +++ b/test/RANLIB/RANLIB.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe @@ -53,7 +53,7 @@ test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) ranlib = foo.Dictionary('RANLIB') bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], - RANLIB = r'%s wrapper.py ' + ranlib) + RANLIB = r'%(_python_)s wrapper.py ' + ranlib) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -61,9 +61,10 @@ main = foo.Object('main', 'main.c') foo.Program(target = 'f', source = main) bar.Program(target = 'b', source = main) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdio.h> void library_function(void) { @@ -72,6 +73,8 @@ library_function(void) """) test.write('bar.c', r""" +#include <stdio.h> + void library_function(void) { @@ -80,6 +83,7 @@ library_function(void) """) test.write('main.c', r""" +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/RANLIB/RANLIBCOM.py b/test/RANLIB/RANLIBCOM.py index d60a14e..312216b 100644 --- a/test/RANLIB/RANLIBCOM.py +++ b/test/RANLIB/RANLIBCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $RANLIBCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -62,12 +62,12 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n/*ranlib*/\n") test.write('file.2', "file.2\n/*ar*/\n/*ranlib*/\n") diff --git a/test/RANLIB/RANLIBCOMSTR.py b/test/RANLIB/RANLIBCOMSTR.py index 4e03675..6929ac6 100644 --- a/test/RANLIB/RANLIBCOMSTR.py +++ b/test/RANLIB/RANLIBCOMSTR.py @@ -31,7 +31,7 @@ customize the displayed archive indexer string. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -63,21 +63,23 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', RANLIBCOMSTR = 'Indexing $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n/*ranlib*/\n") test.write('file.2', "file.2\n/*ar*/\n/*ranlib*/\n") -test.run(stdout = test.wrap_stdout("""\ -%s myar.py output.lib file.1 file.2 +expect = test.wrap_stdout("""\ +%(_python_)s myar.py output.lib file.1 file.2 Indexing output.lib -""" % python)) +""" % locals()) + +test.run(stdout = expect) test.must_match('output.lib', "file.1\nfile.2\n") diff --git a/test/RANLIB/RANLIBFLAGS.py b/test/RANLIB/RANLIBFLAGS.py index 80618ba..08ee967 100644 --- a/test/RANLIB/RANLIBFLAGS.py +++ b/test/RANLIB/RANLIBFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], RANLIB = '', - RANLIBFLAGS = foo.subst(r'%s wrapper.py $RANLIB $RANLIBFLAGS')) + RANLIBFLAGS = foo.subst(r'%(_python_)s wrapper.py $RANLIB $RANLIBFLAGS')) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -58,9 +58,12 @@ main = foo.Object('main', 'main.c') foo.Program(target = 'f', source = main) bar.Program(target = 'b', source = main) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include <stdlib.h> +#include <stdio.h> + void library_function(void) { @@ -69,6 +72,8 @@ library_function(void) """) test.write('bar.c', r""" +#include <stdlib.h> +#include <stdio.h> void library_function(void) { @@ -77,6 +82,8 @@ library_function(void) """) test.write('main.c', r""" +#include <stdlib.h> + int main(int argc, char *argv[]) { diff --git a/test/RCS/RCS_COCOM.py b/test/RCS/RCS_COCOM.py index a151d69..319a851 100644 --- a/test/RCS/RCS_COCOM.py +++ b/test/RCS/RCS_COCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'RCS'], BUILDERS={'Cat':Builder(action=cat)}, - RCS_COCOM='%(python)s my-rcs-co.py $TARGET') + RCS_COCOM='%(_python_)s my-rcs-co.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['RCS', 'sub', 'fff.in'], "RCS/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-rcs-co.py %(sub_SConscript)s +%(_python_)s my-rcs-co.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-rcs-co.py aaa.in +%(_python_)s my-rcs-co.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-rcs-co.py ccc.in +%(_python_)s my-rcs-co.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-rcs-co.py %(sub_ddd_in)s +%(_python_)s my-rcs-co.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-rcs-co.py %(sub_fff_in)s +%(_python_)s my-rcs-co.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/RCS/RCS_COCOMSTR.py b/test/RCS/RCS_COCOMSTR.py index 9e17418..30a3a57 100644 --- a/test/RCS/RCS_COCOMSTR.py +++ b/test/RCS/RCS_COCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'RCS'], BUILDERS={'Cat':Builder(action=cat)}, - RCS_COCOM='%(python)s my-rcs-co.py $TARGET', + RCS_COCOM='%(_python_)s my-rcs-co.py $TARGET', RCS_COCOMSTR='Checking out $TARGET from our fake RCS') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/RCS/diskcheck.py b/test/RCS/diskcheck.py index 8af2545..78120f6 100644 --- a/test/RCS/diskcheck.py +++ b/test/RCS/diskcheck.py @@ -115,12 +115,13 @@ test.write('bbb.in', "checked-out bbb.in\n") test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") + expect = """\ scons: warning: Ignoring missing SConscript '%s' -File "SConstruct", line 23, in ? +File "%s", line 23, in ? scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop. -""" % os.path.join('sub', 'SConscript') +""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct')) test.run(status=2, stderr=expect) diff --git a/test/RCS/implicit.py b/test/RCS/implicit.py index 362f15a..3223901 100644 --- a/test/RCS/implicit.py +++ b/test/RCS/implicit.py @@ -49,6 +49,8 @@ if not co: test.subdir('RCS') test.write('foo.c', """\ +#include <stdio.h> + #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/RPATH.py b/test/RPATH.py index 6ab6eb2..a0ae8c7 100644 --- a/test/RPATH.py +++ b/test/RPATH.py @@ -45,6 +45,7 @@ Program('foo', 'foo.c', LIBS='bar', LIBPATH='bar', RPATH='bar') """) test.write('foo.c', """\ +#include <stdlib.h> int main() { void bar(); bar(); diff --git a/test/Repository/CPPPATH.py b/test/Repository/CPPPATH.py index 6ec21f3..9db613e 100644 --- a/test/Repository/CPPPATH.py +++ b/test/Repository/CPPPATH.py @@ -53,6 +53,8 @@ test.write(['repository', 'include2', 'foo.h'], r""" """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <foo.h> int main(int argc, char *argv[]) diff --git a/test/Repository/LIBPATH.py b/test/Repository/LIBPATH.py index c4470d2..9216a8b 100644 --- a/test/Repository/LIBPATH.py +++ b/test/Repository/LIBPATH.py @@ -62,6 +62,8 @@ env_yyy.Command('yyy.out', bbb_exe, write_LIBDIRFLAGS) """) test.write(['work', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -72,6 +74,8 @@ main(int argc, char *argv[]) """) test.write(['work', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/Repository/M4.py b/test/Repository/M4.py index 75fa0de..15d8abb 100644 --- a/test/Repository/M4.py +++ b/test/Repository/M4.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,16 +48,17 @@ sys.stdout.write(string.replace(contents, 'M4', 'mym4.py')) sys.exit(0) """) +mym4_py = test.workpath('mym4.py') opts = "-Y " + test.workpath('repository') test.write(['repository', 'SConstruct'], """\ -env = Environment(M4 = r'%s %s', tools=['default', 'm4']) +env = Environment(M4 = r'%(_python_)s %(mym4_py)s', tools=['default', 'm4']) env.M4(target = 'aaa.x', source = 'aaa.x.m4') SConscript('src/SConscript', "env", build_dir="build") -""" % (python, test.workpath('mym4.py'))) +""" % locals()) test.write(['repository', 'aaa.x.m4'], """\ line 1 diff --git a/test/Repository/Program.py b/test/Repository/Program.py index 93bcb85..eda1202 100644 --- a/test/Repository/Program.py +++ b/test/Repository/Program.py @@ -51,6 +51,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """ % repository) test.write(['repository', 'aaa.c'], r""" +#include <stdio.h> void aaa(void) { @@ -59,6 +60,7 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include <stdio.h> void bbb(void) { @@ -67,6 +69,9 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> + extern void aaa(void); extern void bbb(void); int @@ -95,6 +100,7 @@ test.up_to_date(chdir = 'work1', arguments = '.') # test.write(['work1', 'bbb.c'], r""" +#include <stdio.h> void bbb(void) { @@ -113,6 +119,7 @@ test.up_to_date(chdir = 'work1', arguments = '.') # test.write(['work1', 'aaa.c'], r""" +#include <stdio.h> void aaa(void) { @@ -121,6 +128,8 @@ aaa(void) """) test.write(['work1', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -185,6 +194,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """ % (repository_new, repository_old)) test.write(['repository.old', 'aaa.c'], r""" +#include <stdio.h> void aaa(void) { @@ -193,6 +203,7 @@ aaa(void) """) test.write(['repository.old', 'bbb.c'], r""" +#include <stdio.h> void bbb(void) { @@ -201,6 +212,8 @@ bbb(void) """) test.write(['repository.old', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -232,6 +245,8 @@ test.up_to_date(chdir = 'work2', arguments = '.') test.writable('repository.new', 1) test.write(['repository.new', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -240,6 +255,8 @@ aaa(void) """) test.write(['work2', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -261,6 +278,8 @@ test.up_to_date(chdir = 'work2', arguments = '.') # test.write(['work2', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -269,6 +288,8 @@ aaa(void) """) test.write(['work2', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/StaticLibrary.py b/test/Repository/StaticLibrary.py index 087fa7e..1cf20c3 100644 --- a/test/Repository/StaticLibrary.py +++ b/test/Repository/StaticLibrary.py @@ -66,6 +66,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['repository', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -74,6 +76,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -82,6 +86,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -118,6 +124,8 @@ test.fail_test(os.path.exists(repository_foo)) test.up_to_date(chdir = 'work1', options = opts, arguments = ".") test.write(['work1', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -168,6 +176,8 @@ test.writable('repository', 0) test.up_to_date(chdir = 'work2', options = opts, arguments = ".") test.write(['work2', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -194,6 +204,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = ".") test.up_to_date(chdir = 'work3', options = opts, arguments = ".") test.write(['work3', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/absolute-path.py b/test/Repository/absolute-path.py index ed360c7..378e321 100644 --- a/test/Repository/absolute-path.py +++ b/test/Repository/absolute-path.py @@ -57,6 +57,8 @@ env.Program('foo', ['aaa.c', r'%s', 'foo.c']) """ % subdir_aaa_c) test.write(['repository', 'src', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void src_aaa(void) { @@ -65,6 +67,8 @@ src_aaa(void) """) test.write(['subdir', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void subdir_aaa(void) { @@ -73,6 +77,8 @@ subdir_aaa(void) """) test.write(['repository', 'src', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void src_aaa(void); extern void subdir_aaa(void); int diff --git a/test/Repository/include.py b/test/Repository/include.py index 577442a..4575d99 100644 --- a/test/Repository/include.py +++ b/test/Repository/include.py @@ -56,6 +56,8 @@ test.write(['repository', 'bar.h'], r""" """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <foo.h> int main(int argc, char *argv[]) @@ -100,6 +102,8 @@ test.up_to_date(chdir = 'work', arguments = '.') # test.write(['work', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <foo.h> int main(int argc, char *argv[]) diff --git a/test/Repository/link-object.py b/test/Repository/link-object.py index 63c274e..679fa7e 100644 --- a/test/Repository/link-object.py +++ b/test/Repository/link-object.py @@ -52,6 +52,8 @@ env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c']) """ % workpath_repository) test.write(['repository', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -60,6 +62,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -68,6 +72,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -107,6 +113,8 @@ test.up_to_date(chdir = 'work', arguments = ".") # test.write(['work', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { diff --git a/test/Repository/multi-dir.py b/test/Repository/multi-dir.py index 4532cc3..ab67c9d 100644 --- a/test/Repository/multi-dir.py +++ b/test/Repository/multi-dir.py @@ -73,6 +73,8 @@ test.write(['repository', 'src', 'include.h'], r""" """) test.write(['repository', 'src', 'main.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <include.h> int main(int argc, char *argv[]) diff --git a/test/Repository/no-SConsignFile.py b/test/Repository/no-SConsignFile.py index d838605..95b1749 100644 --- a/test/Repository/no-SConsignFile.py +++ b/test/Repository/no-SConsignFile.py @@ -45,6 +45,7 @@ env.Program('foo', 'src/foo.c') test.write(['src', 'foo.c'], """\ #include <stdio.h> +#include <stdlib.h> #include "foo.h" int main(int argc, char *argv[]) diff --git a/test/Repository/no-repository.py b/test/Repository/no-repository.py index 6dc9add..f9b245e 100644 --- a/test/Repository/no-repository.py +++ b/test/Repository/no-repository.py @@ -50,6 +50,8 @@ env.Program(target = 'foo', source = Split('aaa.c bbb.c foo.c')) """ % no_repository) test.write(['work', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -58,6 +60,8 @@ aaa(void) """) test.write(['work', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -66,6 +70,8 @@ bbb(void) """) test.write(['work', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/signature-order.py b/test/Repository/signature-order.py index 8069b60..99bc56a 100644 --- a/test/Repository/signature-order.py +++ b/test/Repository/signature-order.py @@ -62,6 +62,8 @@ test.write(['repository', 'foo.h'], foo_h_contents) test.write(['repository', 'bar.h'], bar_h_contents) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <foo.h> #include <bar.h> int diff --git a/test/Repository/top-level-path.py b/test/Repository/top-level-path.py index 2d4164a..4dccfd5 100644 --- a/test/Repository/top-level-path.py +++ b/test/Repository/top-level-path.py @@ -56,6 +56,8 @@ env.Program('foo', ['aaa.c', '#subdir/aaa.c', 'foo.c']) """) test.write(['repository', 'src', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void src_aaa(void) { @@ -64,6 +66,8 @@ src_aaa(void) """) test.write(['repository', 'subdir', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void subdir_aaa(void) { @@ -72,6 +76,8 @@ subdir_aaa(void) """) test.write(['repository', 'src', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void src_aaa(void); extern void subdir_aaa(void); int diff --git a/test/Repository/variants.py b/test/Repository/variants.py index f855636..cd4c24a 100644 --- a/test/Repository/variants.py +++ b/test/Repository/variants.py @@ -133,6 +133,8 @@ test.write(['repository', 'src1', 'iii.h'], r""" """) test.write(['repository', 'src1', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <iii.h> void aaa(void) @@ -142,6 +144,8 @@ aaa(void) """) test.write(['repository', 'src1', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <iii.h> void bbb(void) @@ -151,6 +155,8 @@ bbb(void) """) test.write(['repository', 'src1', 'main.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <iii.h> extern void aaa(void); extern void bbb(void); @@ -189,6 +195,8 @@ test.write(['repository', 'src2', 'xxx', 'include.h'], r""" """) test.write(['repository', 'src2', 'xxx', 'main.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <include.h> #ifdef FOO #define MAIN_OS "FOO" diff --git a/test/Repository/within-repository.py b/test/Repository/within-repository.py index 1cffe81..0b7e844 100644 --- a/test/Repository/within-repository.py +++ b/test/Repository/within-repository.py @@ -53,6 +53,8 @@ env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c']) """ % workpath_repository) test.write(['repository', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -61,6 +63,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -69,6 +73,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -88,6 +94,8 @@ env.Program(target = 'bar', source = ['aaa.c', 'bbb.c', 'bar.c']) """) test.write(['repository', 'src', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -96,6 +104,8 @@ aaa(void) """) test.write(['repository', 'src', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -104,6 +114,8 @@ bbb(void) """) test.write(['repository', 'src', 'bar.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int diff --git a/test/Rpcgen/RPCGEN.py b/test/Rpcgen/RPCGEN.py index 162615b..ea22438 100644 --- a/test/Rpcgen/RPCGEN.py +++ b/test/Rpcgen/RPCGEN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,12 +52,13 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', tools=['default', 'rpcgen']) +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', + tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENCLIENTFLAGS.py b/test/Rpcgen/RPCGENCLIENTFLAGS.py index d8ce226..66ea6df 100644 --- a/test/Rpcgen/RPCGENCLIENTFLAGS.py +++ b/test/Rpcgen/RPCGENCLIENTFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENCLIENTFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENFLAGS.py b/test/Rpcgen/RPCGENFLAGS.py index 951254f..8f6cfff 100644 --- a/test/Rpcgen/RPCGENFLAGS.py +++ b/test/Rpcgen/RPCGENFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENHEADERFLAGS.py b/test/Rpcgen/RPCGENHEADERFLAGS.py index e8d3cb0..411838d 100644 --- a/test/Rpcgen/RPCGENHEADERFLAGS.py +++ b/test/Rpcgen/RPCGENHEADERFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENHEADERFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENSERVICEFLAGS.py b/test/Rpcgen/RPCGENSERVICEFLAGS.py index fbc5c7f..af638ce 100644 --- a/test/Rpcgen/RPCGENSERVICEFLAGS.py +++ b/test/Rpcgen/RPCGENSERVICEFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENSERVICEFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENXDRFLAGS.py b/test/Rpcgen/RPCGENXDRFLAGS.py index dc428a0..6ce0609 100644 --- a/test/Rpcgen/RPCGENXDRFLAGS.py +++ b/test/Rpcgen/RPCGENXDRFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENXDRFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/SCCS/SCCSCOM.py b/test/SCCS/SCCSCOM.py index 1ba5782..f7a210c 100644 --- a/test/SCCS/SCCSCOM.py +++ b/test/SCCS/SCCSCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'SCCS'], BUILDERS={'Cat':Builder(action=cat)}, - SCCSCOM='%(python)s my-sccs-get.py $TARGET') + SCCSCOM='%(_python_)s my-sccs-get.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['SCCS', 'sub', 'fff.in'], "SCCS/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-sccs-get.py %(sub_SConscript)s +%(_python_)s my-sccs-get.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-sccs-get.py aaa.in +%(_python_)s my-sccs-get.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-sccs-get.py ccc.in +%(_python_)s my-sccs-get.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-sccs-get.py %(sub_ddd_in)s +%(_python_)s my-sccs-get.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-sccs-get.py %(sub_fff_in)s +%(_python_)s my-sccs-get.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/SCCS/SCCSCOMSTR.py b/test/SCCS/SCCSCOMSTR.py index 858e17b..be5d807 100644 --- a/test/SCCS/SCCSCOMSTR.py +++ b/test/SCCS/SCCSCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'SCCS'], BUILDERS={'Cat':Builder(action=cat)}, - SCCSCOM='%(python)s my-sccs-get.py $TARGET', + SCCSCOM='%(_python_)s my-sccs-get.py $TARGET', SCCSCOMSTR='Checking out $TARGET from our fake SCCS') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/SCCS/diskcheck.py b/test/SCCS/diskcheck.py index 532ad9c..66566fa 100644 --- a/test/SCCS/diskcheck.py +++ b/test/SCCS/diskcheck.py @@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test transparent checkouts from SCCS files in an SCCS subdirectory. """ +import os.path import string import TestSCons @@ -94,10 +95,10 @@ test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") expect = """\ -scons: warning: Ignoring missing SConscript 'sub/SConscript' -File "SConstruct", line 17, in ? +scons: warning: Ignoring missing SConscript '%s' +File "%s", line 17, in ? scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop. -""" +""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct')) test.run(status=2, stderr=expect) diff --git a/test/SConscript.py b/test/SConscript/SConscript.py index 08e41a6..268c48e 100644 --- a/test/SConscript.py +++ b/test/SConscript/SConscript.py @@ -216,207 +216,4 @@ test.run(arguments = ".", stdout = test.wrap_stdout(read_str = 'SConstruct %s\nSConscript %s\n' % (wpath, wpath), build_str = "scons: `.' is up to date.\n")) -# Test exporting all global variables as a list of keys: -test.write("SConstruct", """ -x = 'x' -y = 'zoom' -Export(globals().keys()) -SConscript('SConscript') -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test exporting all global variables as a list of keys in SConscript call: -test.write("SConstruct", """ -x = 'x' -y = 'zoom' -SConscript('SConscript', globals().keys()) -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test exporting all global variables as a dictionary: -test.write("SConstruct", """ -x = 'x' -y = 'zoom' -Export(globals()) -SConscript('SConscript') -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test exporting all global variables as dictionary in SConscript call: -test.write("SConstruct", """ -x = 'x' -y = 'zoom' -SConscript('SConscript', globals()) -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test export of local variables: -test.write("SConstruct", """ -def f(): - x = 'x' - y = 'zoom' - Export('x', 'y') - -f() -SConscript('SConscript') -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test export of local variables in SConscript call: -test.write("SConstruct", """ -def f(): - x = 'x' - y = 'zoom' - SConscript('SConscript', ['x', 'y']) -f() -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test export of local variables as a dictionary: -test.write("SConstruct", """ -def f(): - x = 'x' - y = 'zoom' - Export(locals()) - -f() -SConscript('SConscript') -""") - -test.write("SConscript", """ -Import(['x', 'y']) -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test importing all variables: -test.write("SConstruct", """ -x = 'x' -y = 'zoom' -Export('x') -SConscript('SConscript', 'y') -""") - -test.write("SConscript", """ -Import('*') -assert x == 'x' -assert y == 'zoom' -""") - -test.run(arguments = ".") - -# Test white space -test.subdir('white space') -test.write("SConstruct", """\ -SConscript('white space/SConscript') -""") - -test.write(['white space', 'SConscript'], """\ -print "`white space/SConscript'" -""") - -test.run(arguments = ".", - stdout = test.wrap_stdout(read_str = "`white space/SConscript'\n", - build_str = "scons: `.' is up to date.\n")) - -# Test calling SConscript through a construction environment. -test.subdir('sub1', 'sub2') - -test.write("SConstruct", """\ -env = Environment(SUB1='sub1', SUB2='sub2') -print "SConstruct" -x = 'xxx' -y = 'yyy' -env.Export(["x", "y"]) -env.SConscript('$SUB1/SConscript') -env.SConscript(dirs=['$SUB2']) -SConscript(['s1', 's2']) -env.SConscript(['s3', 's4']) -""") - -test.write(['sub1', 'SConscript'], """\ -env = Environment() -env.Import("x") -print "sub1/SConscript" -print "x =", x -""") - -test.write(['sub2', 'SConscript'], """\ -env = Environment() -env.Import("y") -print "sub2/SConscript" -print "y =", y -""") - -test.write('s1', "\n") -test.write('s2', "\n") -test.write('s3', "\n") -test.write('s4', "\n") - -expect = """\ -SConstruct -sub1/SConscript -x = xxx -sub2/SConscript -y = yyy -""" - -test.run(arguments = ".", - stdout = test.wrap_stdout(read_str = expect, - build_str = "scons: `.' is up to date.\n")) - -test.write("SConstruct", """\ -def builder(target, source, env): - import SCons.Script.SConscript - assert SCons.Script.SConscript.sconscript_reading == 0 -env = Environment(BUILDERS={'builder':Builder(action=builder)}) -env.builder('test',[]) -import SCons.Script.SConscript -assert SCons.Script.SConscript.sconscript_reading == 1 -""") - test.pass_test() diff --git a/test/SConscript/SConscriptChdir.py b/test/SConscript/SConscriptChdir.py new file mode 100644 index 0000000..3763378 --- /dev/null +++ b/test/SConscript/SConscriptChdir.py @@ -0,0 +1,85 @@ +#!/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 sys +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('dir1', 'dir2', 'dir3', 'dir4', 'dir5') + +test.write('SConstruct', """ +env = Environment() +SConscript('dir1/SConscript') +SConscriptChdir(1) +SConscript('dir2/SConscript') +SConscriptChdir(0) +SConscript('dir3/SConscript') +env.SConscriptChdir(1) +SConscript('dir4/SConscript') +env.SConscriptChdir(0) +SConscript('dir5/SConscript') +""") + +test.write(['dir1', 'SConscript'], """ +execfile("create_test.py") +""") + +test.write(['dir2', 'SConscript'], """ +execfile("create_test.py") +""") + +test.write(['dir3', 'SConscript'], """ +import os.path +name = os.path.join('dir3', 'create_test.py') +execfile(name) +""") + +test.write(['dir4', 'SConscript'], """ +execfile("create_test.py") +""") + +test.write(['dir5', 'SConscript'], """ +import os.path +name = os.path.join('dir5', 'create_test.py') +execfile(name) +""") + +for dir in ['dir1', 'dir2', 'dir3','dir4', 'dir5']: + test.write([dir, 'create_test.py'], r""" +f = open("test.txt", "ab") +f.write("This is the %s test.\n") +f.close() +""" % dir) + +test.run(arguments=".", stderr=None) + +test.fail_test(test.read(['dir1', 'test.txt']) != "This is the dir1 test.\n") +test.fail_test(test.read(['dir2', 'test.txt']) != "This is the dir2 test.\n") +test.fail_test(test.read('test.txt') != "This is the dir3 test.\nThis is the dir5 test.\n") +test.fail_test(test.read(['dir4', 'test.txt']) != "This is the dir4 test.\n") + +test.pass_test() diff --git a/test/SConscript/env.py b/test/SConscript/env.py new file mode 100644 index 0000000..0ad0561 --- /dev/null +++ b/test/SConscript/env.py @@ -0,0 +1,90 @@ +#!/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 calling SConscript through a construction environment. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('sub1', 'sub2') + +test.write("SConstruct", """\ +env = Environment(SUB1='sub1', SUB2='sub2') +print "SConstruct" +x = 'xxx' +y = 'yyy' +env.Export(["x", "y"]) +env.SConscript('$SUB1/SConscript') +env.SConscript(dirs=['$SUB2']) +SConscript(['s1', 's2']) +env.SConscript(['s3', 's4']) +""") + +test.write(['sub1', 'SConscript'], """\ +env = Environment() +env.Import("x") +print "sub1/SConscript" +print "x =", x +""") + +test.write(['sub2', 'SConscript'], """\ +env = Environment() +env.Import("y") +print "sub2/SConscript" +print "y =", y +""") + +test.write('s1', "\n") +test.write('s2', "\n") +test.write('s3', "\n") +test.write('s4', "\n") + +expect = """\ +SConstruct +sub1/SConscript +x = xxx +sub2/SConscript +y = yyy +""" + +test.run(arguments = ".", + stdout = test.wrap_stdout(read_str = expect, + build_str = "scons: `.' is up to date.\n")) + +test.write("SConstruct", """\ +def builder(target, source, env): + import SCons.Script.SConscript + assert SCons.Script.SConscript.sconscript_reading == 0 +env = Environment(BUILDERS={'builder':Builder(action=builder)}) +env.builder('test',[]) +import SCons.Script.SConscript +assert SCons.Script.SConscript.sconscript_reading == 1 +""") + +test.pass_test() diff --git a/test/SConscript/src_dir.py b/test/SConscript/src_dir.py new file mode 100644 index 0000000..f18066b --- /dev/null +++ b/test/SConscript/src_dir.py @@ -0,0 +1,97 @@ +#!/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 that the SConscript() src_dir argument. + +Test case contributed by Dobes Vandermeer. +""" + +import TestSCons + +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +test.subdir(['build'], + ['samples'], + ['src']) + +test.write(['SConstruct'], """\ +env = Environment() + +for src_dir in ['src','samples']: + SConscript('build/glob_build.py', + src_dir=src_dir, + build_dir='build/output/'+src_dir, + duplicate=0, + exports=['env']) +""") + +test.write(['build', 'glob_build.py'], """\ +from glob import glob +from os.path import join +from os.path import basename +Import('env') + +sources = map(basename, glob(join(str(env.Dir('.').srcnode()),'*.c'))) + +# Trivial example; really I read the configuration file +# their build system uses to generate the vcproj files +for source in sources: + env.Program(source) +""") + +test.write(['samples', 'goodbye.c'], """\ +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + printf("Goodbye, world!\\n"); + exit(0); +} +""") + +test.write(['src', 'hello.c'], """\ +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + printf("Hello, world!\\n"); + exit(0); +} +""") + +test.run() + +goodbye = test.workpath('build', 'output', 'samples', 'goodbye') +hello = test.workpath('build', 'output', 'src', 'hello') + +test.run(program = goodbye, stdout = "Goodbye, world!\n") + +test.run(program = hello, stdout = "Hello, world!\n") + +test.pass_test() diff --git a/test/SConscript/variables.py b/test/SConscript/variables.py new file mode 100644 index 0000000..34f52a0 --- /dev/null +++ b/test/SConscript/variables.py @@ -0,0 +1,169 @@ +#!/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 importing and exporting variables between SConscript files. +""" + +import TestSCons + +test = TestSCons.TestSCons() + + +# Test exporting all global variables as a list of keys: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +Export(globals().keys()) +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test exporting all global variables as a list of keys in SConscript call: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +SConscript('SConscript', globals().keys()) +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test exporting all global variables as a dictionary: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +Export(globals()) +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test exporting all global variables as dictionary in SConscript call: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +SConscript('SConscript', globals()) +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test export of local variables: +test.write("SConstruct", """ +def f(): + x = 'x' + y = 'zoom' + Export('x', 'y') + +f() +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test export of local variables in SConscript call: +test.write("SConstruct", """ +def f(): + x = 'x' + y = 'zoom' + SConscript('SConscript', ['x', 'y']) +f() +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test export of local variables as a dictionary: +test.write("SConstruct", """ +def f(): + x = 'x' + y = 'zoom' + Export(locals()) + +f() +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test importing all variables: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +Export('x') +SConscript('SConscript', 'y') +""") + +test.write("SConscript", """ +Import('*') +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +test.pass_test() diff --git a/test/SConscript/white-space.py b/test/SConscript/white-space.py new file mode 100644 index 0000000..87eb701 --- /dev/null +++ b/test/SConscript/white-space.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__" + +""" +Test handling of white space in an SConscript path name. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('white space') +test.write("SConstruct", """\ +SConscript('white space/SConscript') +""") + +test.write(['white space', 'SConscript'], """\ +print "`white space/SConscript'" +""") + +expect = test.wrap_stdout(read_str = "`white space/SConscript'\n", + build_str = "scons: `.' is up to date.\n") + +test.run(arguments = ".", stdout = expect) + + +test.pass_test() diff --git a/test/SConsignFile.py b/test/SConsignFile.py index 46d0954..e2b8053 100644 --- a/test/SConsignFile.py +++ b/test/SConsignFile.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,13 +45,13 @@ file.close() # test.write(['work1', 'SConstruct'], """ SConsignFile() -B = Builder(action = "%s ../build.py $TARGETS $SOURCES") +B = Builder(action = '%(_python_)s ../build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'subdir/f3.out', source = 'subdir/f3.in') env.B(target = 'subdir/f4.out', source = 'subdir/f4.in') -""" % python) +""" % locals()) test.write(['work1', 'f1.in'], "work1/f1.in\n") test.write(['work1', 'f2.in'], "work1/f2.in\n") @@ -79,13 +79,13 @@ test.must_not_exist(test.workpath('work1', 'subdir', '.sconsign')) test.write(['work2', 'SConstruct'], """ e = Environment(XXX = 'scons') e.SConsignFile('my_${XXX}ign') -B = Builder(action = "%s ../build.py $TARGETS $SOURCES") +B = Builder(action = '%(_python_)s ../build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f5.out', source = 'f5.in') env.B(target = 'f6.out', source = 'f6.in') env.B(target = 'subdir/f7.out', source = 'subdir/f7.in') env.B(target = 'subdir/f8.out', source = 'subdir/f8.in') -""" % python) +""" % locals()) test.write(['work2', 'f5.in'], "work2/f5.in\n") test.write(['work2', 'f6.in'], "work2/f6.in\n") diff --git a/test/SHELL.py b/test/SHELL.py index 7dda321..915dbce 100644 --- a/test/SHELL.py +++ b/test/SHELL.py @@ -35,6 +35,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -68,7 +69,8 @@ os.chmod(my_shell, 0755) test.write('SConstruct', """\ env = Environment(SHELL = r'%(my_shell)s') -env.Command('file.out', 'file.in', "%(python)s fake_cat_program $TARGET $SOURCES") +env.Command('file.out', 'file.in', + 'r%(_python_)s fake_cat_program $TARGET $SOURCES') """ % locals()) test.write('file.in', "file.in\n") diff --git a/test/SHLIBPREFIX.py b/test/SHLIBPREFIX.py index 352f217..87b92fa 100644 --- a/test/SHLIBPREFIX.py +++ b/test/SHLIBPREFIX.py @@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c') """) test.write('foo.c', r""" +#include <stdio.h> void foo(void) { diff --git a/test/SHLIBSUFFIX.py b/test/SHLIBSUFFIX.py index 94c2984..dc88e3b 100644 --- a/test/SHLIBSUFFIX.py +++ b/test/SHLIBSUFFIX.py @@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c') """) test.write('foo.c', r""" +#include <stdio.h> void foo(void) { diff --git a/test/SPAWN.py b/test/SPAWN.py index e6eb65e..f73ab11 100644 --- a/test/SPAWN.py +++ b/test/SPAWN.py @@ -30,7 +30,7 @@ Test the SPAWN construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,10 +45,14 @@ ofp.close() test.write('SConstruct', """ import os import string +import sys def my_spawn(sh, escape, cmd, args, env): - os.system(string.join(args + ['extra.txt'])) + s = string.join(args + ['extra.txt']) + if sys.platform in ['win32']: + s = '"' + s + '"' + os.system(s) env = Environment(SPAWN = my_spawn) -env.Command('file.out', 'file.in', "%(python)s cat.py $TARGET $SOURCES") +env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES') env = Environment() """ % locals()) diff --git a/test/SWIG/SWIG.py b/test/SWIG/SWIG.py index 65ecf2b..0fb1da4 100644 --- a/test/SWIG/SWIG.py +++ b/test/SWIG/SWIG.py @@ -35,8 +35,10 @@ if sys.platform =='darwin': # so we link to a framework version. However, testing must also # use the same version, or else you get interpreter errors. python = "/System/Library/Frameworks/Python.framework/Versions/Current/bin/python" + _python_ = '"' + python + '"' else: python = TestSCons.python + _python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj @@ -68,11 +70,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(tools=['default', 'swig'], SWIG = r'%s myswig.py') +env = Environment(tools=['default', 'swig'], SWIG = r'%(_python_)s myswig.py') env.Program(target = 'test1', source = 'test1.i') env.CFile(target = 'test2', source = 'test2.i') env.Copy(SWIGFLAGS = '-c++').Program(target = 'test3', source = 'test3.i') -""" % (python)) +""" % locals()) test.write('test1.i', r""" int @@ -143,14 +145,13 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', - SHCCFLAGS='', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', ) swig = foo.Dictionary('SWIG') -bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig) +bar = foo.Copy(SWIG = r'%(_python_)s wrapper.py ' + swig) foo.LoadableModule(target = 'foo', source = ['foo.c', 'foo.i']) bar.LoadableModule(target = 'bar', source = ['bar.c', 'bar.i']) """ % locals()) @@ -226,7 +227,6 @@ This is bar.c! test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', - SHCCFLAGS='', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', @@ -252,14 +252,13 @@ foo.LoadableModule(target = 'modulename', source = ['module.i']) test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', - SHCCFLAGS='', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', ) swig = foo.Dictionary('SWIG') -bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig) +bar = foo.Copy(SWIG = r'%(_python_)s wrapper.py ' + swig) foo.CFile(target = 'dependent', source = ['dependent.i']) """ % locals()) diff --git a/test/SWIG/SWIGCOM.py b/test/SWIG/SWIGCOM.py index 22e217a..20d2d5d 100644 --- a/test/SWIG/SWIGCOM.py +++ b/test/SWIG/SWIGCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $SWIGCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'swig'], - SWIGCOM = r'%s myswig.py $TARGET $SOURCES') + SWIGCOM = r'%(_python_)s myswig.py $TARGET $SOURCES') env.CFile(target = 'aaa', source = 'aaa.i') env.CXXFile(target = 'bbb', source = 'bbb.i', SWIGFLAGS='-c++') -""" % python) +""" % locals()) test.write('aaa.i', "aaa.i\n/*swig*/\n") test.write('bbb.i', "bbb.i\n/*swig*/\n") diff --git a/test/SWIG/SWIGCOMSTR.py b/test/SWIG/SWIGCOMSTR.py index 3ffcdbf..b991d77 100644 --- a/test/SWIG/SWIGCOMSTR.py +++ b/test/SWIG/SWIGCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when swig is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'swig'], - SWIGCOM = r'%s myswig.py $TARGET $SOURCES', + SWIGCOM = r'%(_python_)s myswig.py $TARGET $SOURCES', SWIGCOMSTR = 'Swigging $TARGET from $SOURCE') env.CFile(target = 'aaa', source = 'aaa.i') env.CXXFile(target = 'bbb', source = 'bbb.i', SWIGFLAGS='-c++') -""" % python) +""" % locals()) test.write('aaa.i', "aaa.i\n/*swig*/\n") test.write('bbb.i', "bbb.i\n/*swig*/\n") diff --git a/test/Scanner.py b/test/Scanner/Scanner.py index 6e64c03..09c5680 100644 --- a/test/Scanner.py +++ b/test/Scanner/Scanner.py @@ -24,10 +24,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -93,19 +92,19 @@ k2scan = env.Scanner(name = 'k2', env = Environment() env.Append(SCANNERS = kscan) -env.Command('foo', 'foo.k', r'%(python)s build.py $SOURCES $TARGET') +env.Command('foo', 'foo.k', r'%(_python_)s build.py $SOURCES $TARGET') ########################################################## # Test resetting the environment scanners (and specifying as a list). env2 = env.Copy() env2.Append(SCANNERS = [k2scan]) -env2.Command('junk', 'junk.k2', r'%(python)s build.py $SOURCES $TARGET') +env2.Command('junk', 'junk.k2', r'%(_python_)s build.py $SOURCES $TARGET') ########################################################## # Test specifying a specific source scanner for a target Node -barbld = Builder(action=r'%(python)s build.py $SOURCES $TARGET', +barbld = Builder(action=r'%(_python_)s build.py $SOURCES $TARGET', source_scanner=kscan) env.Append(BUILDERS={'BarBld':barbld}) bar = env.BarBld(target='bar', source='bar.in') @@ -120,7 +119,7 @@ def blork(env, target, source): open(str(target[0]), 'wb').write( string.replace(source[0].get_contents(), 'getfile', 'MISSEDME')) -kbld = Builder(action=r'%(python)s build.py $SOURCES $TARGET', +kbld = Builder(action=r'%(_python_)s build.py $SOURCES $TARGET', src_suffix='.lork', suffix='.blork', source_scanner=kscan) @@ -134,7 +133,7 @@ blork = env.KB('moo.lork') ork = env.BLORK(blork) Alias('make_ork', ork) -""" % {'python': python}) +""" % locals()) test.write('foo.k', """foo.k 1 line 1 @@ -173,14 +172,15 @@ test.write('xxx', "xxx 1\n") test.write('yyy', "yyy 1\n") test.write('zzz', "zzz 1\n") -test.run(arguments = '.', - stdout=test.wrap_stdout("""\ -%(python)s build.py bar.in bar -%(python)s build.py foo.k foo -%(python)s build.py junk.k2 junk -%(python)s build.py moo.lork moo.blork +expect = test.wrap_stdout("""\ +%(_python_)s build.py bar.in bar +%(_python_)s build.py foo.k foo +%(_python_)s build.py junk.k2 junk +%(_python_)s build.py moo.lork moo.blork blork(["moo.ork"], ["moo.blork"]) -""" % {'python':python})) +""" % locals()) + +test.run(arguments = '.', stdout=expect) test.must_match('foo', "foo.k 1 line 1\nxxx 1\nyyy 1\nfoo.k 1 line 4\n") test.must_match('bar', "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n") @@ -191,12 +191,13 @@ test.up_to_date(arguments = '.') test.write('xxx', "xxx 2\n") -test.run(arguments = '.', - stdout=test.wrap_stdout("""\ -%(python)s build.py foo.k foo -%(python)s build.py moo.lork moo.blork +expect = test.wrap_stdout("""\ +%(_python_)s build.py foo.k foo +%(_python_)s build.py moo.lork moo.blork blork(["moo.ork"], ["moo.blork"]) -""" % {'python':python})) +""" % locals()) + +test.run(arguments = '.', stdout=expect) test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 1\nfoo.k 1 line 4\n") test.must_match('bar', "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n") @@ -205,14 +206,15 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\n test.write('yyy', "yyy 2\n") -test.run(arguments = '.', - stdout=test.wrap_stdout("""\ -%(python)s build.py bar.in bar -%(python)s build.py foo.k foo -%(python)s build.py junk.k2 junk -%(python)s build.py moo.lork moo.blork +expect = test.wrap_stdout("""\ +%(_python_)s build.py bar.in bar +%(_python_)s build.py foo.k foo +%(_python_)s build.py junk.k2 junk +%(_python_)s build.py moo.lork moo.blork blork(["moo.ork"], ["moo.blork"]) -""" % {'python':python})) +""" % locals()) + +test.run(arguments = '.', stdout=expect) test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4\n") test.must_match('bar', "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n") @@ -221,11 +223,12 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\n test.write('zzz', "zzz 2\n") -test.run(arguments = '.', - stdout=test.wrap_stdout("""\ -%(python)s build.py bar.in bar -%(python)s build.py junk.k2 junk -""" % {'python':python})) +expect = test.wrap_stdout("""\ +%(_python_)s build.py bar.in bar +%(_python_)s build.py junk.k2 junk +""" % locals()) + +test.run(arguments = '.', stdout=expect) test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4\n") test.must_match('bar', "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 2\n") @@ -234,82 +237,4 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\n test.up_to_date(arguments = 'foo') -# Now make sure that using the same source file in different -# environments will get the proper scanner for the environment being -# used. - -test.write('SConstruct2', """ -import re - -include_re = re.compile(r'^include\s+(\S+)$', re.M) -input_re = re.compile(r'^input\s+(\S+)$', re.M) - -scan1 = Scanner(name = 'Include', - function = lambda N,E,P,A: A.findall(N.get_contents()), - argument = include_re, - skeys = ['.inp']) - -scan2 = Scanner(name = 'Input', - function = lambda N,E,P,A: A.findall(N.get_contents()), - argument = input_re, - skeys = ['.inp']) - -env1 = Environment() -env2 = Environment() - -env1.Append(SCANNERS=scan1) -env2.Append(SCANNERS=scan2) - -env1.Command('frog.1', 'frog.inp', r'%(python)s do_incl.py $TARGET $SOURCES') -env2.Command('frog.2', 'frog.inp', r'%(python)s do_inp.py $TARGET $SOURCES') - -"""%{'python':python}) - -process = r""" -import sys - -def process(infp, outfp): - prefix = '%(command)s ' - l = len(prefix) - for line in infp.readlines(): - if line[:l] == prefix: - process(open(line[l:-1], 'rb'), outfp) - else: - outfp.write(line) - -process(open(sys.argv[2], 'rb'), - open(sys.argv[1], 'wb')) -sys.exit(0) -""" - -test.write('do_incl.py', process % { 'command' : 'include' }) -test.write('do_inp.py', process % { 'command' : 'input' }) - -test.write('frog.inp', """\ -include sound1 -input sound2 -""") - -test.write('sound1', 'croak\n') -test.write('sound2', 'ribbet\n') - -test.run(arguments='-f SConstruct2 .', -stdout=test.wrap_stdout("""\ -%(python)s do_incl.py frog.1 frog.inp -%(python)s do_inp.py frog.2 frog.inp -""" % { 'python':python })) - -test.must_match('frog.1', 'croak\ninput sound2\n') -test.must_match('frog.2', 'include sound1\nribbet\n') - -test.write('sound2', 'rudeep\n') - -test.run(arguments='-f SConstruct2 .', -stdout=test.wrap_stdout("""\ -%(python)s do_inp.py frog.2 frog.inp -""" % { 'python':python })) - -test.must_match('frog.1', 'croak\ninput sound2\n') -test.must_match('frog.2', 'include sound1\nrudeep\n') - test.pass_test() diff --git a/test/Scanner/empty-implicit.py b/test/Scanner/empty-implicit.py new file mode 100644 index 0000000..2112fd8 --- /dev/null +++ b/test/Scanner/empty-implicit.py @@ -0,0 +1,81 @@ +#!/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 Scanners are not called if a previous --implicit-cache +run stored an empty list of implicit dependencies. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', r""" +import os.path + +def scan(node, env, envkey, arg): + print 'XScanner: node =', os.path.split(str(node))[1] + return [] + +def exists_check(node, env): + return os.path.exists(str(node)) + +XScanner = Scanner(name = 'XScanner', + function = scan, + argument = None, + scan_check = exists_check, + skeys = ['.x']) + +def echo(env, target, source): + t = os.path.split(str(target[0]))[1] + s = os.path.split(str(source[0]))[1] + print 'create %s from %s' % (t, s) + open(t, 'wb').write(open(s, 'rb').read()) + +Echo = Builder(action = Action(echo, None), + src_suffix = '.x', + suffix = '.x') + +env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner]) + +f1 = env.Echo(source=['f1_in'], target=['f1_out']) +""") + +test.write('f1_in.x', 'f1_in.x\n') + +expect = test.wrap_stdout("""\ +XScanner: node = f1_in.x +create f1_out.x from f1_in.x +""") + +test.run(arguments = '--implicit-cache .', stdout = expect) + +# Run it again, and the output must contain only the "up to date" message, +# *not* the line printed by the XScanner function. + +test.up_to_date(options = '--implicit-cache', arguments = '.') + +test.pass_test() diff --git a/test/Scanner-exception.py b/test/Scanner/exception.py index 7615888..7615888 100644 --- a/test/Scanner-exception.py +++ b/test/Scanner/exception.py diff --git a/test/scan-once.py b/test/Scanner/generated.py index 044e260..36f35f6 100644 --- a/test/scan-once.py +++ b/test/Scanner/generated.py @@ -22,20 +22,17 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -""" -This test verifies that Scanners are called just once. - -This is actually a shotgun marriage of two separate tests, the simple -test originally created for this, plus a more complicated test based -on a real-life bug report submitted by Scott Lystig Fritchie. Both -have value: the simple test will be easier to debug if there are basic -scanning problems, while Scott's test has a lot of cool real-world -complexity that is valuable in its own right, including scanning of -generated .h files. +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ +Verify that we only scan generated .h files once. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +This originated as a real-life bug report submitted by Scott Lystig +Fritchie. It's been left as-is, rather than stripped down to bear +minimum, partly because it wasn't completely clear what combination of +factors triggered the bug Scott saw, and partly because the real-world +complexity is valuable in its own right. +""" import os.path import sys @@ -45,51 +42,12 @@ import TestSCons test = TestSCons.TestSCons() -test.subdir('simple', - 'SLF', - ['SLF', 'reftree'], ['SLF', 'reftree', 'include'], - ['SLF', 'src'], ['SLF', 'src', 'lib_geng']) +test.subdir('reftree', + ['reftree', 'include'], + 'src', + ['src', 'lib_geng']) test.write('SConstruct', """\ -SConscript('simple/SConscript') -SConscript('SLF/SConscript') -""") - -test.write(['simple', 'SConscript'], r""" -import os.path - -def scan(node, env, envkey, arg): - print 'XScanner: node =', os.path.split(str(node))[1] - return [] - -def exists_check(node, env): - return os.path.exists(str(node)) - -XScanner = Scanner(name = 'XScanner', - function = scan, - argument = None, - scan_check = exists_check, - skeys = ['.x']) - -def echo(env, target, source): - t = os.path.split(str(target[0]))[1] - s = os.path.split(str(source[0]))[1] - print 'create %s from %s' % (t, s) - -Echo = Builder(action = Action(echo, None), - src_suffix = '.x', - suffix = '.x') - -env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner]) - -f1 = env.Echo(source=['file1'], target=['file2']) -f2 = env.Echo(source=['file2'], target=['file3']) -f3 = env.Echo(source=['file3'], target=['file4']) -""") - -test.write(['simple', 'file1.x'], 'simple/file1.x\n') - -test.write(['SLF', 'SConscript'], """\ ### ### QQQ !@#$!@#$! I need to move the SConstruct file to be "above" ### both the source and install dirs, or the install dependencies @@ -129,9 +87,9 @@ env.Append(LIBPATH = [e["EXPORT_LIB"]]) env.Append(LIBPATH = [e["REF_LIB"]]) Mylib.Subdirs(env, "src") -""" % test.workpath('SLF')) +""" % test.workpath()) -test.write(['SLF', 'Mylib.py'], """\ +test.write('Mylib.py', """\ import os import string import re @@ -205,23 +163,23 @@ def AddLibDirs(env, str): """) -test.write(['SLF', 'reftree', 'include', 'lib_a.h'], """\ +test.write(['reftree', 'include', 'lib_a.h'], """\ char *a_letter(void); """) -test.write(['SLF', 'reftree', 'include', 'lib_b.h'], """\ +test.write(['reftree', 'include', 'lib_b.h'], """\ char *b_letter(void); """) -test.write(['SLF', 'reftree', 'include', 'lib_ja.h'], """\ +test.write(['reftree', 'include', 'lib_ja.h'], """\ char *j_letter_a(void); """) -test.write(['SLF', 'reftree', 'include', 'lib_jb.h.intentionally-moved'], """\ +test.write(['reftree', 'include', 'lib_jb.h.intentionally-moved'], """\ char *j_letter_b(void); """) -test.write(['SLF', 'src', 'SConscript'], """\ +test.write(['src', 'SConscript'], """\ # --- Begin SConscript boilerplate --- import Mylib Import("env") @@ -236,7 +194,7 @@ env = env.Copy() # Yes, clobber intentionally """) -test.write(['SLF', 'src', 'lib_geng', 'SConscript'], """\ +test.write(['src', 'lib_geng', 'SConscript'], """\ # --- Begin SConscript boilerplate --- import string import sys @@ -253,8 +211,9 @@ env = env.Copy() # Yes, clobber intentionally Mylib.AddCFlags(env, "-DGOOFY_DEMO") Mylib.AddIncludeDirs(env, ".") -# Not part of SLF's original stuff: On Windows, it's import to use the -# original test environment when we invoke SCons recursively. +# Not part of Scott Lystig Fritchies's original stuff: +# On Windows, it's import to use the original test environment +# when we invoke SCons recursively. import os recurse_env = env.Copy() recurse_env["ENV"] = os.environ @@ -297,10 +256,10 @@ lib_objs = map(lambda x: re.sub("\.c$", ".o", x), lib_srcs) Mylib.ExportHeader(env, exported_hdrs) Mylib.ExportLib(env, lib_fullname) -# The following were the original commands from SLF, making use of -# a shell script and a Makefile to build the library. These have -# been preserved, commented out below, but in order to make this -# test portable, we've replaced them with a Python script and a +# The following were the original commands from Scott Lystic Fritchie, +# making use of a shell script and a Makefile to build the library. +# These have been preserved, commented out below, but in order to make +# this test portable, we've replaced them with a Python script and a # recursive invocation of SCons (!). #cmd_both = "cd %s ; make generated ; make" % Dir(".") #cmd_generated = "cd %s ; sh MAKE-HEADER.sh" % Dir(".") @@ -313,8 +272,8 @@ def escape(s): s = '"' + s + '"' return s -cmd_generated = "%s $SOURCE" % (escape(sys.executable),) -cmd_justlib = "%s %s -C ${SOURCES[0].dir}" % ((sys.executable), +cmd_generated = "%s $SOURCE" % escape(sys.executable) +cmd_justlib = "%s %s -C ${SOURCES[0].dir}" % (escape(sys.executable), escape(sys.argv[0])) ##### Deps appear correct ... but wacky scanning? @@ -330,7 +289,7 @@ recurse_env.Command([lib_fullname] + lib_objs, cmd_justlib) """) -test.write(['SLF', 'src', 'lib_geng', 'MAKE-HEADER.py'], """\ +test.write(['src', 'lib_geng', 'MAKE-HEADER.py'], """\ #!/usr/bin/env python import os @@ -344,7 +303,7 @@ for h in ['libg_gx.h', 'libg_gy.h', 'libg_gz.h']: open(h, 'w').write('') """) -test.write(['SLF', 'src', 'lib_geng', 'SConstruct'], """\ +test.write(['src', 'lib_geng', 'SConstruct'], """\ import os Scanned = {} @@ -384,13 +343,13 @@ Default(l) # bug report. We're not using them--in order to make this script as # portable as possible, we're using a Python script and a recursive # invocation of SCons--but we're preserving them here for history. -#test.write(['SLF', 'src', 'lib_geng', 'MAKE-HEADER.sh'], """\ +#test.write(['src', 'lib_geng', 'MAKE-HEADER.sh'], """\ ##!/bin/sh # #exec touch $* #""") # -#test.write(['SLF', 'src', 'lib_geng', 'Makefile'], """\ +#test.write(['src', 'lib_geng', 'Makefile'], """\ #all: libg.a # #GEN_HDRS = libg_gx.h libg_gy.h libg_gz.h @@ -413,10 +372,10 @@ Default(l) # -rm -f libg.a *.o core core.* #""") -test.write(['SLF', 'src', 'lib_geng', 'libg_w.h'], """\ +test.write(['src', 'lib_geng', 'libg_w.h'], """\ """) -test.write(['SLF', 'src', 'lib_geng', 'libg_1.c'], """\ +test.write(['src', 'lib_geng', 'libg_1.c'], """\ #include <libg_w.h> #include <libg_gx.h> @@ -426,7 +385,7 @@ int g_1() } """) -test.write(['SLF', 'src', 'lib_geng', 'libg_2.c'], """\ +test.write(['src', 'lib_geng', 'libg_2.c'], """\ #include <libg_w.h> #include <libg_gx.h> #include <libg_gy.h> @@ -438,7 +397,7 @@ int g_2() } """) -test.write(['SLF', 'src', 'lib_geng', 'libg_3.c'], """\ +test.write(['src', 'lib_geng', 'libg_3.c'], """\ #include <libg_w.h> #include <libg_gx.h> @@ -448,36 +407,7 @@ int g_3() } """) -test.run(arguments = 'simple', - stdout = test.wrap_stdout("""\ -XScanner: node = file1.x -create file2.x from file1.x -create file3.x from file2.x -create file4.x from file3.x -""")) - -test.write(['simple', 'file2.x'], 'simple/file2.x\n') - -test.run(arguments = 'simple', - stdout = test.wrap_stdout("""\ -XScanner: node = file1.x -XScanner: node = file2.x -create file3.x from file2.x -create file4.x from file3.x -""")) - -test.write(['simple', 'file3.x'], 'simple/file3.x\n') - -test.run(arguments = 'simple', - stdout = test.wrap_stdout("""\ -XScanner: node = file1.x -XScanner: node = file2.x -XScanner: node = file3.x -create file4.x from file3.x -""")) - -test.run(arguments = 'SLF', - stderr=TestSCons.noisy_ar, +test.run(stderr=TestSCons.noisy_ar, match=TestSCons.match_re_dotall) # XXX Note that the generated .h files still get scanned twice, diff --git a/test/Scanner/multi-env.py b/test/Scanner/multi-env.py new file mode 100644 index 0000000..514fbca --- /dev/null +++ b/test/Scanner/multi-env.py @@ -0,0 +1,116 @@ +#!/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__" + + +""" +Verifies that using the same source file in different environments +will get the proper scanner for the environment being used. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + + +test.write('SConstruct', """ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) +input_re = re.compile(r'^input\s+(\S+)$', re.M) + +scan1 = Scanner(name = 'Include', + function = lambda N,E,P,A: A.findall(N.get_contents()), + argument = include_re, + skeys = ['.inp']) + +scan2 = Scanner(name = 'Input', + function = lambda N,E,P,A: A.findall(N.get_contents()), + argument = input_re, + skeys = ['.inp']) + +env1 = Environment() +env2 = Environment() + +env1.Append(SCANNERS=scan1) +env2.Append(SCANNERS=scan2) + +env1.Command('frog.1', 'frog.inp', r'%(_python_)s do_incl.py $TARGET $SOURCES') +env2.Command('frog.2', 'frog.inp', r'%(_python_)s do_inp.py $TARGET $SOURCES') + +""" % locals()) + +process = r""" +import sys + +def process(infp, outfp): + prefix = '%(command)s ' + l = len(prefix) + for line in infp.readlines(): + if line[:l] == prefix: + process(open(line[l:-1], 'rb'), outfp) + else: + outfp.write(line) + +process(open(sys.argv[2], 'rb'), + open(sys.argv[1], 'wb')) +sys.exit(0) +""" + +test.write('do_incl.py', process % { 'command' : 'include' }) +test.write('do_inp.py', process % { 'command' : 'input' }) + +test.write('frog.inp', """\ +include sound1 +input sound2 +""") + +test.write('sound1', 'croak\n') +test.write('sound2', 'ribbet\n') + +expect = test.wrap_stdout("""\ +%(_python_)s do_incl.py frog.1 frog.inp +%(_python_)s do_inp.py frog.2 frog.inp +""" % locals()) + +test.run(arguments='.', stdout=expect) + +test.must_match('frog.1', 'croak\ninput sound2\n') +test.must_match('frog.2', 'include sound1\nribbet\n') + +test.write('sound2', 'rudeep\n') + +expect = test.wrap_stdout("""\ +%(_python_)s do_inp.py frog.2 frog.inp +""" % locals()) + +test.run(arguments='.', stdout=expect) + +test.must_match('frog.1', 'croak\ninput sound2\n') +test.must_match('frog.2', 'include sound1\nrudeep\n') + +test.pass_test() diff --git a/test/parallel-rescan.py b/test/Scanner/parallel-rescan.py index 4a1f27e..4a1f27e 100644 --- a/test/parallel-rescan.py +++ b/test/Scanner/parallel-rescan.py diff --git a/test/Scanner/scan-once.py b/test/Scanner/scan-once.py new file mode 100644 index 0000000..7e02dd2 --- /dev/null +++ b/test/Scanner/scan-once.py @@ -0,0 +1,94 @@ +#!/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 Scanners are called just once. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', r""" +import os.path + +def scan(node, env, envkey, arg): + print 'XScanner: node =', os.path.split(str(node))[1] + return [] + +def exists_check(node, env): + return os.path.exists(str(node)) + +XScanner = Scanner(name = 'XScanner', + function = scan, + argument = None, + scan_check = exists_check, + skeys = ['.x']) + +def echo(env, target, source): + t = os.path.split(str(target[0]))[1] + s = os.path.split(str(source[0]))[1] + print 'create %s from %s' % (t, s) + +Echo = Builder(action = Action(echo, None), + src_suffix = '.x', + suffix = '.x') + +env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner]) + +f1 = env.Echo(source=['file1'], target=['file2']) +f2 = env.Echo(source=['file2'], target=['file3']) +f3 = env.Echo(source=['file3'], target=['file4']) +""") + +test.write('file1.x', 'file1.x\n') + +test.run(stdout = test.wrap_stdout("""\ +XScanner: node = file1.x +create file2.x from file1.x +create file3.x from file2.x +create file4.x from file3.x +""")) + +test.write('file2.x', 'file2.x\n') + +test.run(stdout = test.wrap_stdout("""\ +XScanner: node = file1.x +XScanner: node = file2.x +create file3.x from file2.x +create file4.x from file3.x +""")) + +test.write('file3.x', 'file3.x\n') + +test.run(stdout = test.wrap_stdout("""\ +XScanner: node = file1.x +XScanner: node = file2.x +XScanner: node = file3.x +create file4.x from file3.x +""")) + +test.pass_test() diff --git a/test/SharedLibrary.py b/test/SharedLibrary.py index d9b0350..f8447ca 100644 --- a/test/SharedLibrary.py +++ b/test/SharedLibrary.py @@ -94,6 +94,8 @@ EXPORTS """) test.write('f2a.c', r""" +#include <stdio.h> + void f2a(void) { @@ -102,6 +104,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include <stdio.h> void f2b(void) { @@ -131,6 +134,7 @@ EXPORTS """) test.write('f3a.c', r""" +#include <stdio.h> void f3a(void) { @@ -139,6 +143,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include <stdio.h> void f3b(void) { @@ -168,6 +173,7 @@ EXPORTS """) test.write('prog.c', r""" +#include <stdio.h> void f1(void); void f2a(void); void f2b(void); @@ -253,6 +259,7 @@ EXPORTS """) test.write('progbar.c', r""" +#include <stdio.h> void f4(void); int main(int argc, char *argv[]) diff --git a/test/TAR/TAR.py b/test/TAR/TAR.py index 9d5a617..c82e227 100644 --- a/test/TAR/TAR.py +++ b/test/TAR/TAR.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,12 +60,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(tools = ['tar'], TAR = r'%s mytar.py') +env = Environment(tools = ['tar'], TAR = r'%(_python_)s mytar.py') env.Tar(target = 'aaa.tar', source = ['file1', 'file2']) env.Tar(target = 'aaa.tar', source = 'file3') env.Tar(target = 'bbb', source = 'sub1') env.Tar(target = 'bbb', source = 'file4') -""" % python) +""" % locals()) test.write('file1', "file1\n") test.write('file2', "file2\n") @@ -98,7 +98,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() tar = foo.Dictionary('TAR') -bar = Environment(TAR = r'%s wrapper.py ' + tar) +bar = Environment(TAR = r'%(_python_)s wrapper.py ' + tar) f3 = Environment(TARFLAGS = '-c -z', TARSUFFIX = '.tar.gz') f4 = Environment(TARFLAGS = '-c -z', TARSUFFIX = '.tgz') f5 = Environment(TARFLAGS = '-c -z') @@ -112,7 +112,7 @@ f4.Tar(target = 'f4', source = 'file19') f4.Tar(target = 'f4', source = ['file20', 'file21']) f5.Tar(target = 'f5.tgz', source = 'file22') f5.Tar(target = 'f5.tgz', source = ['file23', 'file24']) -""" % python) +""" % locals()) for f in ['file10', 'file11', 'file12', 'file13', 'file14', 'file15', diff --git a/test/TAR/TARCOM.py b/test/TAR/TARCOM.py index f6e36e7..a39dd22 100644 --- a/test/TAR/TARCOM.py +++ b/test/TAR/TARCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['tar'], - TARCOM = r'%(python)s mytar.py $TARGET $SOURCE') + TARCOM = r'%(_python_)s mytar.py $TARGET $SOURCE') env.Tar('test1.tar', 'test1.in') """ % locals()) diff --git a/test/TAR/TARCOMSTR.py b/test/TAR/TARCOMSTR.py index 2bd3813..eee9b16 100644 --- a/test/TAR/TARCOMSTR.py +++ b/test/TAR/TARCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when tar is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['tar'], - TARCOM = r'%s mytar.py $TARGET $SOURCES', + TARCOM = r'%(_python_)s mytar.py $TARGET $SOURCES', TARCOMSTR = 'Taring $TARGET from $SOURCE') env.Tar('aaa.tar', 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*tar*/\n") diff --git a/test/TAR/TARFLAGS.py b/test/TAR/TARFLAGS.py index 2cda502..c592fe0 100644 --- a/test/TAR/TARFLAGS.py +++ b/test/TAR/TARFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -64,12 +64,14 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(tools = ['tar'], TAR = r'%s mytar.py', TARFLAGS = '-x') +env = Environment(tools = ['tar'], + TAR = r'%(_python_)s mytar.py', + TARFLAGS = '-x') env.Tar(target = 'aaa.tar', source = ['file1', 'file2']) env.Tar(target = 'aaa.tar', source = 'file3') env.Tar(target = 'bbb', source = 'sub1') env.Tar(target = 'bbb', source = 'file4') -""" % python) +""" % locals()) test.write('file1', "file1\n") test.write('file2', "file2\n") @@ -104,12 +106,12 @@ os.system(string.join(sys.argv[1:], " ")) foo = Environment() tar = foo['TAR'] bar = Environment(TAR = '', - TARFLAGS = r'%s wrapper.py ' + tar + ' -c -b 1') + TARFLAGS = r'%(_python_)s wrapper.py ' + tar + ' -c -b 1') foo.Tar(target = 'foo.tar', source = ['file10', 'file11']) foo.Tar(target = 'foo.tar', source = 'file12') bar.Tar(target = 'bar.tar', source = ['file13', 'file14']) bar.Tar(target = 'bar.tar', source = 'file15') -""" % python) +""" % locals()) test.write('file10', "file10\n") test.write('file11', "file11\n") diff --git a/test/TARGET-dir.py b/test/TARGET-dir.py index c599a16..09f20f0 100644 --- a/test/TARGET-dir.py +++ b/test/TARGET-dir.py @@ -68,6 +68,9 @@ test.write(['src', 'foo.h.in'], """\ """) test.write(['src', 'foo.c'], """\ +#include <stdio.h> +#include <stdlib.h> + #include <foo.h> int diff --git a/test/TEX/LATEX.py b/test/TEX/LATEX.py index 2544696..0636109 100644 --- a/test/TEX/LATEX.py +++ b/test/TEX/LATEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,10 +59,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LATEX = r'%s mylatex.py', tools=['latex']) +env = Environment(LATEX = r'%(_python_)s mylatex.py', tools=['latex']) env.DVI(target = 'test1.dvi', source = 'test1.ltx') env.DVI(target = 'test2.dvi', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -113,14 +113,14 @@ foo = Environment(ENV = ENV) latex = foo.Dictionary('LATEX') makeindex = foo.Dictionary('MAKEINDEX') bar = Environment(ENV = ENV, - LATEX = r'%s wrapper.py ' + latex, + LATEX = r'%(_python_)s wrapper.py ' + latex, MAKEINDEX = r' wrapper.py ' + makeindex) foo.DVI(target = 'foo.dvi', source = 'foo.ltx') bar.DVI(target = 'bar', source = 'bar.latex') bar.DVI(target = 'makeindex', source = 'makeindex.tex') foo.DVI(target = 'latexi', source = 'latexi.tex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/LATEXCOM.py b/test/TEX/LATEXCOM.py index 803d26d..a5044ae 100644 --- a/test/TEX/LATEXCOM.py +++ b/test/TEX/LATEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['latex'], - LATEXCOM = r'%(python)s mylatex.py $TARGET $SOURCE') + LATEXCOM = r'%(_python_)s mylatex.py $TARGET $SOURCE') env.DVI('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/LATEXCOMSTR.py b/test/TEX/LATEXCOMSTR.py index 5e31301..08fcccb 100644 --- a/test/TEX/LATEXCOMSTR.py +++ b/test/TEX/LATEXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['latex'], - LATEXCOM = r'%(python)s mylatex.py $TARGET $SOURCE', + LATEXCOM = r'%(_python_)s mylatex.py $TARGET $SOURCE', LATEXCOMSTR = 'Building $TARGET from $SOURCE') env.DVI('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/LATEXFLAGS.py b/test/TEX/LATEXFLAGS.py index fa2348f..b887038 100644 --- a/test/TEX/LATEXFLAGS.py +++ b/test/TEX/LATEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,10 +55,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LATEX = r'%s mylatex.py', LATEXFLAGS = '-x', tools=['latex']) +env = Environment(LATEX = r'%(_python_)s mylatex.py', + LATEXFLAGS = '-x', + tools=['latex']) env.DVI(target = 'test1.dvi', source = 'test1.ltx') env.Copy(LATEXFLAGS = '-t').DVI(target = 'test2.dvi', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -92,10 +94,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, LATEXFLAGS = '--output-comment Commentary') latex = foo.Dictionary('LATEX') -bar = Environment(ENV = ENV, LATEX = r'%s wrapper.py ' + latex) +bar = Environment(ENV = ENV, LATEX = r'%(_python_)s wrapper.py ' + latex) foo.DVI(target = 'foo.dvi', source = 'foo.ltx') bar.DVI(target = 'bar', source = 'bar.latex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/PDFLATEX.py b/test/TEX/PDFLATEX.py index 015db56..e1cf00e 100644 --- a/test/TEX/PDFLATEX.py +++ b/test/TEX/PDFLATEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,10 +59,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFLATEX = r'%s mypdflatex.py', tools=['pdflatex']) +env = Environment(PDFLATEX = r'%(_python_)s mypdflatex.py', tools=['pdflatex']) env.PDF(target = 'test1.pdf', source = 'test1.ltx') env.PDF(target = 'test2.pdf', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -110,10 +110,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) pdflatex = foo.Dictionary('PDFLATEX') -bar = Environment(ENV = ENV, PDFLATEX = r'%s wrapper.py ' + pdflatex) +bar = Environment(ENV = ENV, PDFLATEX = r'%(_python_)s wrapper.py ' + pdflatex) foo.PDF(target = 'foo.pdf', source = 'foo.ltx') bar.PDF(target = 'bar', source = 'bar.latex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/PDFLATEXCOM.py b/test/TEX/PDFLATEXCOM.py index f46ed37..1ce2642 100644 --- a/test/TEX/PDFLATEXCOM.py +++ b/test/TEX/PDFLATEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdflatex'], - PDFLATEXCOM = r'%(python)s mypdflatex.py $TARGET $SOURCE') + PDFLATEXCOM = r'%(_python_)s mypdflatex.py $TARGET $SOURCE') env.PDF('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/PDFLATEXCOMSTR.py b/test/TEX/PDFLATEXCOMSTR.py index 94cf121..284a52a 100644 --- a/test/TEX/PDFLATEXCOMSTR.py +++ b/test/TEX/PDFLATEXCOMSTR.py @@ -35,7 +35,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdflatex'], - PDFLATEXCOM = r'%(python)s mypdflatex.py $TARGET $SOURCE', + PDFLATEXCOM = r'%(_python_)s mypdflatex.py $TARGET $SOURCE', PDFLATEXCOMSTR = 'Building $TARGET from $SOURCE') env.PDF('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/PDFLATEXFLAGS.py b/test/TEX/PDFLATEXFLAGS.py index 0b6a9fc..a3948fe 100644 --- a/test/TEX/PDFLATEXFLAGS.py +++ b/test/TEX/PDFLATEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,10 +55,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFLATEX = r'%s mypdflatex.py', PDFLATEXFLAGS = '-x', tools=['pdflatex']) +env = Environment(PDFLATEX = r'%(_python_)s mypdflatex.py', + PDFLATEXFLAGS = '-x', + tools=['pdflatex']) env.PDF(target = 'test1.pdf', source = 'test1.ltx') env.Copy(PDFLATEXFLAGS = '-t').PDF(target = 'test2.pdf', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -92,10 +94,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, PDFLATEXFLAGS = '--output-comment Commentary') pdflatex = foo.Dictionary('PDFLATEX') -bar = Environment(ENV = ENV, PDFLATEX = r'%s wrapper.py ' + pdflatex) +bar = Environment(ENV = ENV, PDFLATEX = r'%(_python_)s wrapper.py ' + pdflatex) foo.PDF(target = 'foo.pdf', source = 'foo.ltx') bar.PDF(target = 'bar', source = 'bar.latex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/PDFTEX.py b/test/TEX/PDFTEX.py index 5b99c23..ad77b8a 100644 --- a/test/TEX/PDFTEX.py +++ b/test/TEX/PDFTEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFTEX = r'%s mypdftex.py', tools=['pdftex']) +env = Environment(PDFTEX = r'%(_python_)s mypdftex.py', tools=['pdftex']) env.PDF(target = 'test.pdf', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -97,10 +97,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) pdftex = foo.Dictionary('PDFTEX') -bar = Environment(ENV = ENV, PDFTEX = r'%s wrapper.py ' + pdftex) +bar = Environment(ENV = ENV, PDFTEX = r'%(_python_)s wrapper.py ' + pdftex) foo.PDF(target = 'foo.pdf', source = 'foo.tex') bar.PDF(target = 'bar', source = 'bar.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/TEX/PDFTEXCOM.py b/test/TEX/PDFTEXCOM.py index 2a7f06b..f760125 100644 --- a/test/TEX/PDFTEXCOM.py +++ b/test/TEX/PDFTEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdftex'], - PDFTEXCOM = r'%(python)s mypdftex.py $TARGET $SOURCE') + PDFTEXCOM = r'%(_python_)s mypdftex.py $TARGET $SOURCE') env.PDF('test1') """ % locals()) diff --git a/test/TEX/PDFTEXCOMSTR.py b/test/TEX/PDFTEXCOMSTR.py index dbb7b39..ac32ae1 100644 --- a/test/TEX/PDFTEXCOMSTR.py +++ b/test/TEX/PDFTEXCOMSTR.py @@ -35,7 +35,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdftex'], - PDFTEXCOM = r'%(python)s mypdftex.py $TARGET $SOURCE', + PDFTEXCOM = r'%(_python_)s mypdftex.py $TARGET $SOURCE', PDFTEXCOMSTR = 'Building $TARGET from $SOURCE') env.PDF('test1') """ % locals()) diff --git a/test/TEX/PDFTEXFLAGS.py b/test/TEX/PDFTEXFLAGS.py index 1a0f8df..94c5466 100644 --- a/test/TEX/PDFTEXFLAGS.py +++ b/test/TEX/PDFTEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,9 +55,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFTEX = r'%s mypdftex.py', PDFTEXFLAGS = '-x', tools=['pdftex']) +env = Environment(PDFTEX = r'%(_python_)s mypdftex.py', + PDFTEXFLAGS = '-x', + tools=['pdftex']) env.PDF(target = 'test.pdf', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -85,10 +87,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, PDFTEXFLAGS = '--output-comment Commentary') pdftex = foo.Dictionary('PDFTEX') -bar = Environment(ENV = ENV, PDFTEX = r'%s wrapper.py ' + pdftex) +bar = Environment(ENV = ENV, PDFTEX = r'%(_python_)s wrapper.py ' + pdftex) foo.PDF(target = 'foo.pdf', source = 'foo.tex') bar.PDF(target = 'bar', source = 'bar.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py index 4645c7c..7ea359b 100644 --- a/test/TEX/TEX.py +++ b/test/TEX/TEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', tools=['tex']) +env = Environment(TEX = r'%(_python_)s mytex.py', tools=['tex']) env.DVI(target = 'test.dvi', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -97,14 +97,14 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) tex = foo.Dictionary('TEX') -bar = Environment(ENV = ENV, TEX = r'%s wrapper.py ' + tex) +bar = Environment(ENV = ENV, TEX = r'%(_python_)s wrapper.py ' + tex) foo.DVI(target = 'foo.dvi', source = 'foo.tex') foo.DVI(target = 'foo-latex.dvi', source = 'foo-latex.tex') bar.DVI(target = 'bar', source = 'bar.tex') bar.DVI(target = 'bar-latex', source = 'bar-latex.tex') foo.DVI('rerun.tex') foo.DVI('bibtex-test.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/TEX/TEXCOM.py b/test/TEX/TEXCOM.py index 4957427..cf887a4 100644 --- a/test/TEX/TEXCOM.py +++ b/test/TEX/TEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['tex'], - TEXCOM = r'%(python)s mytex.py $TARGET $SOURCE') + TEXCOM = r'%(_python_)s mytex.py $TARGET $SOURCE') env.DVI('test1') """ % locals()) diff --git a/test/TEX/TEXCOMSTR.py b/test/TEX/TEXCOMSTR.py index 81e7123..66c2602 100644 --- a/test/TEX/TEXCOMSTR.py +++ b/test/TEX/TEXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['tex'], - TEXCOM = r'%(python)s mytex.py $TARGET $SOURCE', + TEXCOM = r'%(_python_)s mytex.py $TARGET $SOURCE', TEXCOMSTR = 'Building $TARGET from $SOURCE') env.DVI('test1') """ % locals()) diff --git a/test/TEX/TEXFLAGS.py b/test/TEX/TEXFLAGS.py index 7bd602f..c27ffe5 100644 --- a/test/TEX/TEXFLAGS.py +++ b/test/TEX/TEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,9 +55,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', TEXFLAGS = '-x', tools=['tex']) +env = Environment(TEX = r'%(_python_)s mytex.py', + TEXFLAGS = '-x', + tools=['tex']) env.DVI(target = 'test.dvi', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -85,10 +87,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, TEXFLAGS = '--output-comment Commentary') tex = foo.Dictionary('TEX') -bar = Environment(ENV = ENV, TEX = r'%s wrapper.py ' + tex) +bar = Environment(ENV = ENV, TEX = r'%(_python_)s wrapper.py ' + tex) foo.DVI(target = 'foo.dvi', source = 'foo.tex') bar.DVI(target = 'bar', source = 'bar.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/Value.py b/test/Value.py index 46f8232..85fcbd1 100644 --- a/test/Value.py +++ b/test/Value.py @@ -31,6 +31,8 @@ import sys import TestSCons import TestCmd +_python_ = TestSCons._python_ + test = TestSCons.TestSCons(match=TestCmd.match_re) # Run all of the tests with both types of source signature @@ -55,13 +57,25 @@ def create(target, source, env): env = Environment() env['BUILDERS']['B'] = Builder(action = create) -env['BUILDERS']['S'] = Builder(action = "%(python)s put $SOURCES into $TARGET") +env['BUILDERS']['S'] = Builder(action = '%(_python_)s put $SOURCES into $TARGET') env.B('f1.out', Value(P)) env.B('f2.out', env.Value(L)) env.B('f3.out', Value(C)) env.S('f4.out', Value(L)) -""" % {'source_signature':source_signature, - 'python':TestSCons.python}) + +def create_value (target, source, env): + target[0].write(source[0].get_contents ()) + +def create_value_file (target, source, env): + open(str(target[0]), 'wb').write(source[0].read()) + +env['BUILDERS']['B2'] = Builder(action = create_value) +env['BUILDERS']['B3'] = Builder(action = create_value_file) + +V = Value('my value') +env.B2(V, 'f3.out') +env.B3('f5.out', V) +""" % locals()) test.write('put', """ import os @@ -73,18 +87,25 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) test.run(arguments='-c') test.run() + out7 = """create_value(["'my value'"], ["f3.out"])""" + out8 = """create_value_file(["f5.out"], ["'my value'"])""" + out1 = """create(["f1.out"], ["'/usr/local'"])""" out2 = """create(["f2.out"], ["10"])""" out3 = """create\\(\\["f3.out"\\], \\["<.*.Custom instance at """ #" <- unconfuses emacs syntax highlighting + test.fail_test(string.find(test.stdout(), out1) == -1) test.fail_test(string.find(test.stdout(), out2) == -1) + test.fail_test(string.find(test.stdout(), out7) == -1) + test.fail_test(string.find(test.stdout(), out8) == -1) test.fail_test(re.search(out3, test.stdout()) == None) test.must_match('f1.out', "/usr/local") test.must_match('f2.out', "10") test.must_match('f3.out', "C=/usr/local") test.must_match('f4.out', '10') + test.must_match('f5.out', "C=/usr/local") test.up_to_date(arguments='.') @@ -111,6 +132,8 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) test.fail_test(string.find(test.stdout(), out4) == -1) test.fail_test(string.find(test.stdout(), out5) != -1) + test.fail_test(string.find(test.stdout(), out7) == -1) + test.fail_test(string.find(test.stdout(), out8) == -1) test.fail_test(re.search(out6, test.stdout()) == None) test.up_to_date('prefix=/var', '.') @@ -119,5 +142,6 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) test.must_match('f2.out', "4") test.must_match('f3.out', "C=/var") test.must_match('f4.out', "4") + test.must_match('f5.out', "C=/var") test.pass_test() diff --git a/test/YACC/YACC.py b/test/YACC/YACC.py index 9be1934..d3bc679 100644 --- a/test/YACC/YACC.py +++ b/test/YACC/YACC.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe if sys.platform == 'win32': @@ -64,10 +64,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(YACC = r'%s myyacc.py', tools=['default', 'yacc']) +env = Environment(YACC = r'%(_python_)s myyacc.py', tools=['default', 'yacc']) env.Program(target = 'aaa', source = 'aaa.y') env.Program(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', r""" int @@ -113,13 +113,13 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(YACCFLAGS='-d') yacc = foo.Dictionary('YACC') -bar = Environment(YACC = r'%s wrapper.py ' + yacc) +bar = Environment(YACC = r'%(_python_)s wrapper.py ' + yacc) foo.Program(target = 'foo', source = 'foo.y') bar.Program(target = 'bar', source = 'bar.y') foo.Program(target = 'hello', source = ['hello.cpp']) foo.CXXFile(target = 'file.cpp', source = ['file.yy'], YACCFLAGS='-d') foo.CFile(target = 'not_foo', source = 'foo.y') -""" % python) +""" % locals()) yacc = r""" %%{ diff --git a/test/YACC/YACCCOM.py b/test/YACC/YACCCOM.py index 5f7cd38..1425eb8 100644 --- a/test/YACC/YACCCOM.py +++ b/test/YACC/YACCCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $YACCCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACCCOM = r'%s myyacc.py $TARGET $SOURCES') + YACCCOM = r'%(_python_)s myyacc.py $TARGET $SOURCES') env.CFile(target = 'aaa', source = 'aaa.y') env.CFile(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', "aaa.y\n/*yacc*/\n") test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n") diff --git a/test/YACC/YACCCOMSTR.py b/test/YACC/YACCCOMSTR.py index cfb48b7..b2c128d 100644 --- a/test/YACC/YACCCOMSTR.py +++ b/test/YACC/YACCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when yacc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACCCOM = r'%s myyacc.py $TARGET $SOURCES', + YACCCOM = r'%(_python_)s myyacc.py $TARGET $SOURCES', YACCCOMSTR = 'Yaccing $TARGET from $SOURCE') env.CFile(target = 'aaa', source = 'aaa.y') env.CFile(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', "aaa.y\n/*yacc*/\n") test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n") diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 2779597..a94bc8f 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe if sys.platform == 'win32': @@ -62,9 +62,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(YACC = r'%s myyacc.py', YACCFLAGS = '-x', tools=['yacc', '%s', '%s']) +env = Environment(YACC = r'%(_python_)s myyacc.py', + YACCFLAGS = '-x', + tools=['yacc', '%(linker)s', '%(compiler)s']) env.Program(target = 'aaa', source = 'aaa.y') -""" % (python, linker, compiler)) +""" % locals()) test.write('aaa.y', r""" int diff --git a/test/YACC/YACCHFILESUFFIX.py b/test/YACC/YACCHFILESUFFIX.py index 389018f..231472d 100644 --- a/test/YACC/YACCHFILESUFFIX.py +++ b/test/YACC/YACCHFILESUFFIX.py @@ -31,7 +31,7 @@ utility that writes to an odd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,12 +58,12 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACC = r'%s myyacc.py', + YACC = r'%(_python_)s myyacc.py', YACCFLAGS = '-d', YACCHFILESUFFIX = '.hsuffix') env.CFile(target = 'aaa', source = 'aaa.y') env.CFile(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', "aaa.y\n/*yacc*/\n") test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n") diff --git a/test/YACC/YACCHXXFILESUFFIX.py b/test/YACC/YACCHXXFILESUFFIX.py index b564d5e..182f08b 100644 --- a/test/YACC/YACCHXXFILESUFFIX.py +++ b/test/YACC/YACCHXXFILESUFFIX.py @@ -31,7 +31,7 @@ utility that writes to an odd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,11 +58,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACC = r'%s myyacc.py', + YACC = r'%(_python_)s myyacc.py', YACCFLAGS = '-d', YACCHXXFILESUFFIX = '.hxxsuffix') env.CXXFile(target = 'aaa', source = 'aaa.yy') -""" % python) +""" % locals()) test.write('aaa.yy', "aaa.yy\n/*yacc*/\n") diff --git a/test/ZIP/ZIP.py b/test/ZIP/ZIP.py index 33c54dd..646677d 100644 --- a/test/ZIP/ZIP.py +++ b/test/ZIP/ZIP.py @@ -31,7 +31,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -66,12 +66,12 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['zip'], - ZIPCOM = r'%s myzip.py $TARGET $SOURCES') + ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCES') env.Zip(target = 'aaa.zip', source = ['file1', 'file2']) env.Zip(target = 'aaa.zip', source = 'file3') env.Zip(target = 'bbb', source = 'sub1') env.Zip(target = 'bbb', source = 'file4') -""" % python) +""" % locals()) test.write('file1', "file1\n") test.write('file2', "file2\n") diff --git a/test/ZIP/ZIPCOM.py b/test/ZIP/ZIPCOM.py index 42b8cff..460abe4 100644 --- a/test/ZIP/ZIPCOM.py +++ b/test/ZIP/ZIPCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['zip'], - ZIPCOM = r'%(python)s myzip.py $TARGET $SOURCE') + ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCE') env.Zip('test1.zip', 'test1.in') """ % locals()) diff --git a/test/ZIP/ZIPCOMSTR.py b/test/ZIP/ZIPCOMSTR.py index 0ee90fd..5284d0a 100644 --- a/test/ZIP/ZIPCOMSTR.py +++ b/test/ZIP/ZIPCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when zip is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['zip'], - ZIPCOM = r'%s myzip.py $TARGET $SOURCES', + ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCES', ZIPCOMSTR = 'Zipping $TARGET from $SOURCE') env.Zip('aaa.zip', 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*zip*/\n") diff --git a/test/bad-variables.py b/test/bad-variables.py index 59fc184..cb6b357 100644 --- a/test/bad-variables.py +++ b/test/bad-variables.py @@ -33,17 +33,24 @@ import TestSCons test = TestSCons.TestSCons() -test.write('SConstruct', """\ +SConstruct_path = test.workpath('SConstruct') +SConscript_path = test.workpath('SConscript') + +test.write(SConstruct_path, """\ env = Environment() env['foo-bar'] = 1 """) -test.run(arguments = '.', status = 2, stderr=""" +expect_stderr = """ scons: *** Illegal construction variable `foo-bar' -File "SConstruct", line 2, in ? -""") +File "%(SConstruct_path)s", line 2, in ? +""" % locals() + +test.run(arguments='.', status=2, stderr=expect_stderr) + -test.write('SConstruct', """\ + +test.write(SConstruct_path, """\ SConscript('SConscript') """) @@ -52,9 +59,11 @@ env = Environment() env['foo(bar)'] = 1 """) -test.run(arguments = '.', status = 2, stderr=""" +expect_stderr = """ scons: *** Illegal construction variable `foo(bar)' -File "SConscript", line 2, in ? -""") +File "%(SConscript_path)s", line 2, in ? +""" % locals() + +test.run(arguments='.', status=2, stderr=expect_stderr) test.pass_test() diff --git a/test/builderrors.py b/test/builderrors.py index 4eb6bfa..8c7c4ab 100644 --- a/test/builderrors.py +++ b/test/builderrors.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -47,13 +47,13 @@ sys.exit(exitval) """) test.write(['one', 'SConstruct'], """ -B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES') env = Environment(BUILDERS = { 'B0' : B0, 'B1' : B1 }) env.B1(target = 'f1.out', source = 'f1.in') env.B0(target = 'f2.out', source = 'f2.in') env.B0(target = 'f3.out', source = 'f3.in') -""" % (python, python)) +""" % locals()) test.write(['one', 'f1.in'], "one/f1.in\n") test.write(['one', 'f2.in'], "one/f2.in\n") @@ -67,13 +67,13 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) test.fail_test(os.path.exists(test.workpath('f3.out'))) test.write(['two', 'SConstruct'], """ -B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES') env = Environment(BUILDERS = { 'B0': B0, 'B1' : B1 }) env.B0(target = 'f1.out', source = 'f1.in') env.B1(target = 'f2.out', source = 'f2.in') env.B0(target = 'f3.out', source = 'f3.in') -""" % (python, python)) +""" % locals()) test.write(['two', 'f1.in'], "two/f1.in\n") test.write(['two', 'f2.in'], "two/f2.in\n") @@ -87,13 +87,13 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) test.fail_test(os.path.exists(test.workpath('f3.out'))) test.write(['three', 'SConstruct'], """ -B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES') env = Environment(BUILDERS = { 'B0' : B0, 'B1': B1 }) env.B0(target = 'f1.out', source = 'f1.in') env.B0(target = 'f2.out', source = 'f2.in') env.B1(target = 'f3.out', source = 'f3.in') -""" % (python, python)) +""" % locals()) test.write(['three', 'f1.in'], "three/f1.in\n") test.write(['three', 'f2.in'], "three/f2.in\n") @@ -120,4 +120,62 @@ err = test.stderr() test.fail_test(string.find(err, 'Exception') != -1 or \ string.find(err, 'Traceback') != -1) + +# Test ETOOLONG (arg list too long). This is not in exitvalmap, +# but that shouldn't cause a scons traceback. +long_cmd = 'xyz ' + "foobarxyz" * 100000 +test.write('SConstruct', """ +env=Environment() +if env['PLATFORM'] == 'posix': + from SCons.Platform.posix import fork_spawn + env['SPAWN'] = fork_spawn +env.Command(target='longcmd.out', source=[], action='echo %s') +"""%long_cmd) + +test.run(status=2, stderr=None) +err = test.stderr() +test.fail_test(string.find(err, 'Exception') != -1 or \ + string.find(err, 'Traceback') != -1) +# Python 1.5.2 on a FC3 system doesn't even get to the exitvalmap +# because it fails with "No such file or directory." Just comment +# this out for now, there are plenty of other good tests below. +#test.fail_test(string.find(err, "too long") == -1 and # posix +# string.find(err, "nvalid argument") == -1) # win32 + + +# Test bad shell ('./one' is a dir, so it can't be used as a shell). +# This will also give an exit status not in exitvalmap, +# with error "Permission denied". +test.write('SConstruct', """ +env=Environment() +if env['PLATFORM'] == 'posix': + from SCons.Platform.posix import fork_spawn + env['SPAWN'] = fork_spawn +env['SHELL'] = 'one' +env.Command(target='badshell.out', source=[], action='foo') +""") + +test.run(status=2, stderr=None) +err = test.stderr() +test.fail_test(string.find(err, 'Exception') != -1 or \ + string.find(err, 'Traceback') != -1) +test.fail_test(string.find(err, "ermission") == -1 and \ + string.find(err, "such file") == -1) + + +# Test command with exit status -1. +# Should not give traceback. +test.write('SConstruct', """ +import os +env = Environment(ENV = os.environ) +env.Command('dummy.txt', None, ['python -c "import sys; sys.exit(-1)"']) +""") + +test.run(status=2, stderr=None) +err = test.stderr() +test.fail_test(string.find(err, 'Exception') != -1 or \ + string.find(err, 'Traceback') != -1) + + +# No tests failed; OK. test.pass_test() diff --git a/test/chdir.py b/test/chdir.py index b46764b..1a1a2d7 100644 --- a/test/chdir.py +++ b/test/chdir.py @@ -31,7 +31,7 @@ Command() calls and execution work1s correctly. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -99,7 +99,7 @@ ofp.close """) test.write(['work1', 'SConstruct'], """ -cat_command = r"%(python)s %(cat_py)s ${TARGET.file} ${SOURCE.file}" +cat_command = r'%(_python_)s %(cat_py)s ${TARGET.file} ${SOURCE.file}' no_chdir_act = Action(cat_command) chdir_sub4_act = Action(cat_command, chdir=1) @@ -229,14 +229,14 @@ work2_sub_f1_out = test.workpath('work2', 'sub', 'f1.out') work2_sub_f2_out = test.workpath('work2', 'sub', 'f2.out') test.write(['work2', 'SConstruct'], """\ -cat_command = r"%(python)s %(cat_py)s ${TARGET.file} ${SOURCE.file}" +cat_command = r'%(_python_)s %(cat_py)s ${TARGET.file} ${SOURCE.file}' env = Environment() env.Command('sub/f1.out', 'sub/f1.in', cat_command, chdir=1) env.Command('sub/f2.out', 'sub/f2.in', [ - r"%(python)s %(cat_py)s .temp ${SOURCE.file}", - r"%(python)s %(cat_py)s ${TARGET.file} .temp", + r'%(_python_)s %(cat_py)s .temp ${SOURCE.file}', + r'%(_python_)s %(cat_py)s ${TARGET.file} .temp', ], chdir=1) """ % locals()) @@ -246,13 +246,13 @@ test.write(['work2', 'sub', 'f2.in'], "work2/sub/f2.in") expect = test.wrap_stdout("""\ os.chdir('sub') -%(python)s %(cat_py)s f1.out f1.in +%(_python_)s %(cat_py)s f1.out f1.in os.chdir(%(work2)s) os.chdir('sub') -%(python)s %(cat_py)s .temp f2.in +%(_python_)s %(cat_py)s .temp f2.in os.chdir(%(work2)s) os.chdir('sub') -%(python)s %(cat_py)s f2.out .temp +%(_python_)s %(cat_py)s f2.out .temp os.chdir(%(work2)s) """ % locals()) diff --git a/test/dependency-cycle.py b/test/dependency-cycle.py index 8d1275f..b2a8974 100644 --- a/test/dependency-cycle.py +++ b/test/dependency-cycle.py @@ -40,6 +40,7 @@ env.Depends(foo3, foo1) """) test.write('f1.c', r""" +#include <stdio.h> void f1(void) { diff --git a/test/errors.py b/test/errors.py index 120ea3a..6e0a05f 100644 --- a/test/errors.py +++ b/test/errors.py @@ -29,7 +29,7 @@ import TestSCons import string import sys -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) @@ -85,7 +85,7 @@ a.append(2) test.run(status = 2, stderr = """\ AttributeError: 'int' object has no attribute 'append': - File "SConstruct", line 2: + File ".+SConstruct", line 2: a.append\(2\) """) @@ -98,7 +98,7 @@ a == 1 test.run(status = 2, stderr = """\ NameError: [^\n]* - File "SConstruct", line 1: + File ".+SConstruct", line 1: a == 1 """) @@ -110,7 +110,7 @@ a ! x """) test.run(stdout = "scons: Reading SConscript files ...\n", - stderr = """ File "SConstruct", line 2 + stderr = """ File ".+SConstruct", line 2 a ! x @@ -130,7 +130,7 @@ a[2] = 3 test.run(status = 2, stderr = """\ TypeError: object does not support item assignment: - File "SConstruct", line 2: + File ".+SConstruct", line 2: a\[2\] = 3 """) @@ -146,7 +146,7 @@ raise SCons.Errors.UserError, 'Depends() require both sources and targets.' test.run(stdout = "scons: Reading SConscript files ...\n", stderr = """ scons: \*\*\* Depends\(\) require both sources and targets. -File "SConstruct", line 4, in \? +File ".+SConstruct", line 4, in \? """, status=2) @@ -163,7 +163,7 @@ test.run(stdout = "scons: Reading SConscript files ...\ninternal error\n", File ".+", line \d+, in .+ File ".+", line \d+, in .+ File ".+", line \d+, in .+ - File "SConstruct", line \d+, in \? + File ".+SConstruct", line \d+, in \? raise InternalError, 'error inside' InternalError: error inside """, status=2) @@ -178,8 +178,10 @@ sys.exit(2) # Test ... test.write('SConstruct', """ env=Environment() -Default(env.Command(['one.out', 'two.out'], ['foo.in'], action=r'%s build.py')) -"""%python) +Default(env.Command(['one.out', 'two.out'], + ['foo.in'], + action=r'%(_python_)s build.py')) +""" % locals()) test.run(status=2, stderr="scons: \\*\\*\\* \\[one.out\\] Error 2\n") diff --git a/test/exceptions.py b/test/exceptions.py index 584d4f1..01a2855 100644 --- a/test/exceptions.py +++ b/test/exceptions.py @@ -25,16 +25,19 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os +import re import string import sys import TestSCons import TestCmd -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) -test.write('SConstruct', """ +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """\ def func(source = None, target = None, env = None): raise "func exception" B = Builder(action = func) @@ -51,10 +54,10 @@ Traceback \((most recent call|innermost) last\): )*( File ".+", line \d+, in \S+ )*( File ".+", line \d+, in \S+ [^\n]+ -)* File "SConstruct", line 3, in func +)* File "%s", line 2, in func raise "func exception" func exception -""" +""" % re.escape(SConstruct_path) test.run(arguments = "foo.out", stderr = expected_stderr, status = 2) @@ -69,11 +72,11 @@ import sys sys.exit(1) """) -test.write('SConstruct', """ -Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE') +test.write(SConstruct_path, """ +Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE') env = Environment(BUILDERS = { 'Fail' : Fail }) env.Fail(target = 'f1', source = 'f1.in') -""" % (python)) +""" % locals()) test.write('f1.in', "f1.in\n") @@ -87,13 +90,13 @@ test.run(arguments = '-j2 .', status = 2, stderr = expected_stderr) # even if the exception is raised during the Task.prepare() # [Node.prepare()] -test.write('SConstruct', """ -Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE') +test.write(SConstruct_path, """ +Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE') env = Environment(BUILDERS = { 'Fail' : Fail }) env.Fail(target = 'f1', source = 'f1.in') env.Fail(target = 'f2', source = 'f2.in') env.Fail(target = 'f3', source = 'f3.in') -""" % (python)) +""" % locals()) # f2.in is not created to cause a Task.prepare exception test.write('f3.in', 'f3.in\n') diff --git a/test/expansion.py b/test/expansion.py index 2c22291..0f72134 100644 --- a/test/expansion.py +++ b/test/expansion.py @@ -52,6 +52,8 @@ env.Program(r'%s') os.path.join('$SUBDIR', 'foo4.c'))) test.write(['sub', 'f1.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('f2.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -72,6 +76,8 @@ main(int argc, char *argv[]) """) test.write(['sub', 'f3.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -82,6 +88,8 @@ main(int argc, char *argv[]) """) test.write(['sub', 'foo4.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/explain.py b/test/explain.py index 7f0fbb5..f69b00f 100644 --- a/test/explain.py +++ b/test/explain.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -85,7 +85,7 @@ kscan = Scanner(name = 'kfile', argument = None, skeys = ['.k']) -cat = Builder(action = r"%s %s $TARGET $SOURCES") +cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES') env = Environment() env.Append(BUILDERS = {'Cat':cat}, @@ -97,7 +97,7 @@ env.Install('../inc', 'aaa') env.InstallAs('../inc/bbb.k', 'bbb.k') env.Install('../inc', 'ddd') env.InstallAs('../inc/eee', 'eee.in') -""" % (python, cat_py) +""" % locals() args = '--debug=explain .' @@ -109,10 +109,12 @@ Import("env") env.Cat('file1', 'file1.in') env.Cat('file2', 'file2.k') env.Cat('file3', ['xxx', 'yyy', 'zzz']) -env.Command('file4', 'file4.in', r"%s %s $TARGET $FILE4FLAG $SOURCES", FILE4FLAG="-") +env.Command('file4', 'file4.in', + r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', + FILE4FLAG='-') env.Cat('file5', 'file5.k') env.Cat('subdir/file6', 'subdir/file6.in') -""" % (python, cat_py)) +""" % locals()) test.write(['work1', 'src', 'aaa'], "aaa 1\n") test.write(['work1', 'src', 'bbb.k'], """\ @@ -155,15 +157,15 @@ work1_inc_eee = test.workpath('work1', 'inc', 'eee') work1_inc_bbb_k = test.workpath('work1', 'inc', 'bbb.k') # -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: building `file1' because it doesn't exist -%(python)s %(cat_py)s file1 file1.in +%(_python_)s %(cat_py)s file1 file1.in scons: building `file2' because it doesn't exist -%(python)s %(cat_py)s file2 file2.k +%(_python_)s %(cat_py)s file2 file2.k scons: building `file3' because it doesn't exist -%(python)s %(cat_py)s file3 xxx yyy zzz +%(_python_)s %(cat_py)s file3 xxx yyy zzz scons: building `file4' because it doesn't exist -%(python)s %(cat_py)s file4 - file4.in +%(_python_)s %(cat_py)s file4 - file4.in scons: building `%(work1_inc_aaa)s' because it doesn't exist Install file: "aaa" as "%(work1_inc_aaa)s" scons: building `%(work1_inc_ddd)s' because it doesn't exist @@ -173,10 +175,12 @@ Install file: "eee.in" as "%(work1_inc_eee)s" scons: building `%(work1_inc_bbb_k)s' because it doesn't exist Install file: "bbb.k" as "%(work1_inc_bbb_k)s" scons: building `file5' because it doesn't exist -%(python)s %(cat_py)s file5 file5.k +%(_python_)s %(cat_py)s file5 file5.k scons: building `%(subdir_file6)s' because it doesn't exist -%(python)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s -""" % locals())) +%(_python_)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file1'], "file1.in 1\n") test.must_match(['work1', 'src', 'file2'], """\ @@ -203,23 +207,25 @@ test.write(['work1', 'src', 'yyy'], "yyy 2\n") test.write(['work1', 'src', 'zzz'], "zzz 2\n") test.write(['work1', 'src', 'bbb.k'], "bbb.k 2\ninclude ccc\n") -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file1' because `file1.in' changed -%(python)s %(cat_py)s file1 file1.in +%(_python_)s %(cat_py)s file1 file1.in scons: rebuilding `file2' because `yyy' changed -%(python)s %(cat_py)s file2 file2.k +%(_python_)s %(cat_py)s file2 file2.k scons: rebuilding `file3' because: `yyy' changed `zzz' changed -%(python)s %(cat_py)s file3 xxx yyy zzz +%(_python_)s %(cat_py)s file3 xxx yyy zzz scons: rebuilding `%(work1_inc_bbb_k)s' because: `%(work1_inc_ddd)s' is no longer a dependency `%(work1_inc_eee)s' is no longer a dependency `bbb.k' changed Install file: "bbb.k" as "%(work1_inc_bbb_k)s" scons: rebuilding `file5' because `%(work1_inc_bbb_k)s' changed -%(python)s %(cat_py)s file5 file5.k -""" % locals())) +%(_python_)s %(cat_py)s file5 file5.k +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file1'], "file1.in 2\n") test.must_match(['work1', 'src', 'file2'], """\ @@ -243,10 +249,12 @@ Import("env") env.Cat('file3', ['xxx', 'yyy']) """) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because `zzz' is no longer a dependency -%(python)s %(cat_py)s file3 xxx yyy -""" % locals())) +%(_python_)s %(cat_py)s file3 xxx yyy +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\n") @@ -256,10 +264,12 @@ Import("env") env.Cat('file3', ['xxx', 'yyy', 'zzz']) """) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because `zzz' is a new dependency -%(python)s %(cat_py)s file3 xxx yyy zzz -""" % locals())) +%(_python_)s %(cat_py)s file3 xxx yyy zzz +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") @@ -269,12 +279,14 @@ Import("env") env.Cat('file3', ['zzz', 'yyy', 'xxx']) """) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because the dependency order changed: old: ['xxx', 'yyy', 'zzz'] new: ['zzz', 'yyy', 'xxx'] -%(python)s %(cat_py)s file3 zzz yyy xxx -""" % locals())) +%(_python_)s %(cat_py)s file3 zzz yyy xxx +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") @@ -283,20 +295,22 @@ test.write(['work1', 'src', 'SConscript'], """\ Import("env") f3 = File('file3') env.Cat(f3, ['zzz', 'yyy', 'xxx']) -env.AddPostAction(f3, r"%(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy") -env.AddPreAction(f3, r"%(python)s %(cat_py)s ${TARGET}.alt $SOURCES") +env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy') +env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') """ % locals()) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because the build action changed: - old: %(python)s %(cat_py)s $TARGET $SOURCES - new: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES - %(python)s %(cat_py)s $TARGET $SOURCES - %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy -%(python)s %(cat_py)s file3.alt zzz yyy xxx -%(python)s %(cat_py)s file3 zzz yyy xxx -%(python)s %(cat_py)s file3.yyy zzz yyy xxx yyy -""" % locals())) + old: %(_python_)s %(cat_py)s $TARGET $SOURCES + new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy +%(_python_)s %(cat_py)s file3.alt zzz yyy xxx +%(_python_)s %(cat_py)s file3 zzz yyy xxx +%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx yyy +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") @@ -307,22 +321,24 @@ test.write(['work1', 'src', 'SConscript'], """\ Import("env") f3 = File('file3') env.Cat(f3, ['zzz', 'yyy', 'xxx']) -env.AddPostAction(f3, r"%(python)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx") -env.AddPreAction(f3, r"%(python)s %(cat_py)s ${TARGET}.alt $SOURCES") +env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx') +env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') """ % locals()) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because the build action changed: - old: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES - %(python)s %(cat_py)s $TARGET $SOURCES - %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy - new: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES - %(python)s %(cat_py)s $TARGET $SOURCES - %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx -%(python)s %(cat_py)s file3.alt zzz yyy xxx -%(python)s %(cat_py)s file3 zzz yyy xxx -%(python)s %(cat_py)s file3.yyy zzz yyy xxx xxx -""" % locals())) + old: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy + new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx +%(_python_)s %(cat_py)s file3.alt zzz yyy xxx +%(_python_)s %(cat_py)s file3 zzz yyy xxx +%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx xxx +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") @@ -331,14 +347,18 @@ test.must_match(['work1', 'src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\nxxx 1\n") # test.write(['work1', 'src', 'SConscript'], """\ Import("env") -env.Command('file4', 'file4.in', r"%(python)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES", FILE4FLAG="") +env.Command('file4', 'file4.in', + r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', + FILE4FLAG='') """ % locals()) -test.run(chdir='work1/src',arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file4' because the contents of the build action changed - action: %(python)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES -%(python)s %(cat_py)s file4 file4.in -""" % locals())) + action: %(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES +%(_python_)s %(cat_py)s file4 file4.in +""" % locals()) + +test.run(chdir='work1/src',arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file4'], "file4.in 1\n") @@ -363,7 +383,7 @@ Import("env") env.Cat('file1', 'file1.in') env.Cat('file2', 'file2.k') env.Cat('file3', ['xxx', 'yyy', 'zzz']) -env.Command('file4', 'file4.in', r"%(python)s %(cat_py)s $TARGET - $SOURCES") +env.Command('file4', 'file4.in', r'%(_python_)s %(cat_py)s $TARGET - $SOURCES') env.Cat('file5', 'file5.k') env.Cat('subdir/file6', 'subdir/file6.in') """ % locals()) @@ -437,20 +457,20 @@ work4_inc_eee = test.workpath('work4', 'inc', 'eee') test.run(chdir='work4/src', arguments=args, stdout=test.wrap_stdout("""\ scons: rebuilding `file1' because `file1.in' changed -%(python)s %(cat_py)s file1 file1.in +%(_python_)s %(cat_py)s file1 file1.in scons: rebuilding `file2' because `yyy' changed -%(python)s %(cat_py)s file2 file2.k +%(_python_)s %(cat_py)s file2 file2.k scons: rebuilding `file3' because: `yyy' changed `zzz' changed -%(python)s %(cat_py)s file3 xxx yyy zzz +%(_python_)s %(cat_py)s file3 xxx yyy zzz scons: rebuilding `%(work4_inc_bbb_k)s' because: `%(work4_inc_ddd)s' is no longer a dependency `%(work4_inc_eee)s' is no longer a dependency `bbb.k' changed Install file: "bbb.k" as "%(work4_inc_bbb_k)s" scons: rebuilding `file5' because `%(work4_inc_bbb_k)s' changed -%(python)s %(cat_py)s file5 file5.k +%(_python_)s %(cat_py)s file5 file5.k """ % locals())) test.must_match(['work4', 'src', 'file1'], "file1.in 2\n") diff --git a/test/gnutools.py b/test/gnutools.py index 82c83ef..4bcea00 100644 --- a/test/gnutools.py +++ b/test/gnutools.py @@ -31,7 +31,7 @@ Testing the gnu tool chain, i.e. the tools 'gcc', 'g++' and 'gnulink'. import TestSCons import string import sys -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _dll = TestSCons._dll dll_ = TestSCons.dll_ @@ -91,10 +91,13 @@ test.write(['work1', 'cppfile2.cpp'],""" /* cpp file 2 */ """) +mygcc_py = test.workpath('gnutools','mygcc.py') +mygxx_py = test.workpath('gnutools','myg++.py') + test.write(['work1', 'SConstruct'],""" env = Environment(tools=['gcc','g++','gnulink'], - CC=r'%s %s', - CXX=r'%s %s', + CC=r'%(_python_)s %(mygcc_py)s', + CXX=r'%(_python_)s %(mygxx_py)s', OBJSUFFIX='.o', SHOBJSUFFIX='.os') env.Program('c-only', Split('cfile1.c cfile2.c')) @@ -104,8 +107,7 @@ env.Program('c-and-cpp', Split('cfile1.c cppfile1.cpp')) env.SharedLibrary('c-only', Split('cfile1.c cfile2.c')) env.SharedLibrary('cpp-only', Split('cppfile1.cpp cppfile2.cpp')) env.SharedLibrary('c-and-cpp', Split('cfile1.c cppfile1.cpp')) -""" % (python, test.workpath('gnutools','mygcc.py'), - python, test.workpath('gnutools','myg++.py'))) +""" % locals()) test.run(chdir='work1') diff --git a/test/ignore-command.py b/test/ignore-command.py index 201c488..d4de8d3 100644 --- a/test/ignore-command.py +++ b/test/ignore-command.py @@ -36,7 +36,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,13 +53,13 @@ sys.exit(1) test.write('SConstruct', """\ env = Environment() -f1 = env.Command('f1.out', 'f1.in', "%(python)s build.py $TARGET $SOURCE") -f2 = env.Command('f2.out', 'f2.in', "-%(python)s build.py $TARGET $SOURCE") -f3 = env.Command('f3.out', 'f3.in', "- %(python)s build.py $TARGET $SOURCE") -f4 = env.Command('f4.out', 'f4.in', "@-%(python)s build.py $TARGET $SOURCE") -f5 = env.Command('f5.out', 'f5.in', "@- %(python)s build.py $TARGET $SOURCE") -f6 = env.Command('f6.out', 'f6.in', "-@%(python)s build.py $TARGET $SOURCE") -f7 = env.Command('f7.out', 'f7.in', "-@ %(python)s build.py $TARGET $SOURCE") +f1 = env.Command('f1.out', 'f1.in', '%(_python_)s build.py $TARGET $SOURCE') +f2 = env.Command('f2.out', 'f2.in', '-%(_python_)s build.py $TARGET $SOURCE') +f3 = env.Command('f3.out', 'f3.in', '- %(_python_)s build.py $TARGET $SOURCE') +f4 = env.Command('f4.out', 'f4.in', '@-%(_python_)s build.py $TARGET $SOURCE') +f5 = env.Command('f5.out', 'f5.in', '@- %(_python_)s build.py $TARGET $SOURCE') +f6 = env.Command('f6.out', 'f6.in', '-@%(_python_)s build.py $TARGET $SOURCE') +f7 = env.Command('f7.out', 'f7.in', '-@ %(_python_)s build.py $TARGET $SOURCE') Default(f2, f3, f4, f5, f6, f7) """ % locals()) diff --git a/test/implicit-cache/GetOption.py b/test/implicit-cache/GetOption.py new file mode 100644 index 0000000..5915cca --- /dev/null +++ b/test/implicit-cache/GetOption.py @@ -0,0 +1,53 @@ +#!/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 SetOption/GetOption('implicit_cache') works and can +be overridden from the command line. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +assert not GetOption('implicit_cache') +SetOption('implicit_cache', 1) +assert GetOption('implicit_cache') +""") + +test.run() + +test.write('SConstruct', """ +assert GetOption('implicit_cache') +SetOption('implicit_cache', 0) +assert GetOption('implicit_cache') +""") + +test.run(arguments='--implicit-cache') + + +test.pass_test() diff --git a/test/implicit-cache/SetOption.py b/test/implicit-cache/SetOption.py new file mode 100644 index 0000000..ee2afa5 --- /dev/null +++ b/test/implicit-cache/SetOption.py @@ -0,0 +1,70 @@ +#!/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 SetOption('implicit_cache', 1) actually enables implicit +caching by detecting the case where implicit caching causes inaccurate +builds: a same-named file dropped into a directory earlier in the +CPPPATH list will *not* be detected because we use what's in the cache. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +SetOption('implicit_cache', 1) +env=Environment(CPPPATH=['i1', 'i2']) +env.Object('foo.c') +""") + +test.subdir('i1') +test.subdir('i2') + +test.write('foo.c', """ +#include <foo.h> + +void foo(void) +{ + FOO_H_DEFINED + ++x; /* reference x */ +} +""") + +test.write('i2/foo.h', """ +#define FOO_H_DEFINED int x = 1; +""") + +test.run(arguments = '.') + +test.write('i1/foo.h', """ +this line will cause a syntax error if it's included by a rebuild +"""); + +test.up_to_date(arguments = '.') + + +test.pass_test() diff --git a/test/option--implicit-cache.py b/test/implicit-cache/basic.py index 2508cf2..0c9196c 100644 --- a/test/option--implicit-cache.py +++ b/test/implicit-cache/basic.py @@ -24,10 +24,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import os -import sys +import os.path + import TestSCons -import string _exe = TestSCons._exe _obj = TestSCons._obj @@ -67,8 +66,7 @@ Import("env") env.Program(target='prog', source='prog.c') """) -test.write('nodeps.in', -r""" +test.write('nodeps.in', r""" int main(int argc, char *argv[]) { @@ -78,24 +76,20 @@ main(int argc, char *argv[]) """) -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 1\n" #include <bar.h> """) -test.write(['include', 'bar.h'], -r""" +test.write(['include', 'bar.h'], r""" #define BAR_STRING "include/bar.h 1\n" """) -test.write(['include', 'baz.h'], -r""" +test.write(['include', 'baz.h'], r""" #define BAZ_STRING "include/baz.h 1\n" """) -test.write(['subdir', 'prog.c'], -r""" +test.write(['subdir', 'prog.c'], r""" #include <foo.h> #include <stdio.h> @@ -110,19 +104,16 @@ main(int argc, char *argv[]) } """) -test.write(['subdir', 'include', 'foo.h'], -r""" +test.write(['subdir', 'include', 'foo.h'], r""" #define FOO_STRING "subdir/include/foo.h 1\n" #include "bar.h" """) -test.write(['subdir', 'include', 'bar.h'], -r""" +test.write(['subdir', 'include', 'bar.h'], r""" #define BAR_STRING "subdir/include/bar.h 1\n" """) -test.write('one.c' , -r""" +test.write('one.c' , r""" #include <foo.h> void one(void) { } @@ -141,9 +132,10 @@ test.run(program = test.workpath(variant_prog), test.up_to_date(arguments = args) -# Make sure implicit dependenies work right when one is modifed: -test.write(['include', 'foo.h'], -r""" + + +# Make sure implicit dependencies work right when one is modifed: +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 2\n" #include "bar.h" """) @@ -161,10 +153,11 @@ test.run(program = test.workpath(variant_prog), test.up_to_date(arguments = args) + + # Make sure that changing the order of includes causes rebuilds and # doesn't produce redundant rebuilds: -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 2\n" #include "bar.h" #include "baz.h" @@ -183,8 +176,9 @@ test.run(program = test.workpath(variant_prog), test.up_to_date(arguments = args) -test.write(['include', 'foo.h'], -r""" + + +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 2\n" #include "baz.h" #include "bar.h" @@ -203,19 +197,18 @@ test.run(program = test.workpath(variant_prog), test.up_to_date(arguments = args) + + # Add inc2/foo.h that should shadow include/foo.h, but # because of implicit dependency caching, scons doesn't # detect this: -test.write(['inc2', 'foo.h'], -r""" +test.write(['inc2', 'foo.h'], r""" #define FOO_STRING "inc2/foo.h 1\n" #include <bar.h> """) test.run(arguments = "--implicit-cache " + args) -test.run(arguments = "--implicit-cache " + args) - test.run(program = test.workpath(prog), stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") @@ -225,9 +218,10 @@ test.run(program = test.workpath(subdir_prog), test.run(program = test.workpath(variant_prog), stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") + + # Now modifying include/foo.h should make scons aware of inc2/foo.h -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 3\n" #include "bar.h" """) @@ -243,11 +237,12 @@ test.run(program = test.workpath(subdir_prog), test.run(program = test.workpath(variant_prog), stdout = "subdir/prog.c\ninclude/foo.h 3\ninclude/bar.h 1\n") -# test in the face of a file with no dependencies where the source file is generated: + + +# test a file with no dependencies where the source file is generated: test.run(arguments = "--implicit-cache nodeps%s"%_exe) -test.write('nodeps.in', -r""" +test.write('nodeps.in', r""" #include <foo.h> int @@ -259,116 +254,64 @@ main(int argc, char *argv[]) """) test.run(arguments = "--implicit-cache one%s"%_obj) -test.run(arguments = "--implicit-cache one%s"%_obj) + + # Test forcing of implicit caching: -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 3\n" #include "bar.h" """) test.run(arguments = "--implicit-cache " + args) -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 3\n" #include "baz.h" #include "bar.h" """) -test.run(arguments = "--implicit-deps-unchanged " + variant_prog) -assert string.find(test.stdout(), 'is up to date') == -1, test.stdout() +test.not_up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) -test.write(['include', 'baz.h'], -r""" +test.write(['include', 'baz.h'], r""" #define BAZ_STRING "include/baz.h 2\n" """) -test.run(arguments = "--implicit-deps-unchanged " + variant_prog) -assert string.find(test.stdout(), 'is up to date') != -1, test.stdout() +test.up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) + +test.not_up_to_date(arguments = variant_prog) + -test.run(arguments = variant_prog) -assert string.find(test.stdout(), 'is up to date') == -1, test.stdout() # Test forcing rescanning: -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 3\n" #include "bar.h" """) test.run(arguments = "--implicit-cache " + args) -test.write(['include', 'foo.h'], -r""" +test.write(['include', 'foo.h'], r""" #define FOO_STRING "include/foo.h 3\n" #include "baz.h" #include "bar.h" """) -test.run(arguments = "--implicit-deps-unchanged " + variant_prog) -assert string.find(test.stdout(), 'is up to date') == -1, test.stdout() +test.not_up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) -test.write(['include', 'baz.h'], -r""" +test.write(['include', 'baz.h'], r""" #define BAZ_STRING "include/baz.h 2\n" """) -test.run(arguments = "--implicit-deps-unchanged " + variant_prog) -assert string.find(test.stdout(), 'is up to date') != -1, test.stdout() - -test.run(arguments = "--implicit-deps-changed " + variant_prog) -assert string.find(test.stdout(), 'is up to date') == -1, test.stdout() - -# Test that Set/GetOption('implicit_cache') works: -test.write('SConstruct', """ -assert not GetOption('implicit_cache') -SetOption('implicit_cache', 1) -assert GetOption('implicit_cache') -""") - -test.run() - -test.write('SConstruct', """ -assert GetOption('implicit_cache') -SetOption('implicit_cache', 0) -assert GetOption('implicit_cache') -""") - -test.run(arguments='--implicit-cache') - -# Test to make sure SetOption('implicit_cache', 1) actually enables implicit caching -# by detecting the one case where implicit caching causes inaccurate builds: -test.write('SConstruct', """ -SetOption('implicit_cache', 1) -env=Environment(CPPPATH=['i1', 'i2']) -env.Object('foo.c') -""") - -test.subdir('i1') -test.subdir('i2') - -test.write('foo.c', """ -#include <foo.h> - -void foo(void) -{ - FOO_H_DEFINED - ++x; /* reference x */ -} -""") - -test.write('i2/foo.h', """ -#define FOO_H_DEFINED int x = 1; -""") - -test.run() +test.up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) -test.write('i1/foo.h', """ -"""); +test.not_up_to_date(options = "--implicit-deps-changed", + arguments = variant_prog) -test.run() test.pass_test() diff --git a/test/import.py b/test/import.py index 3663f53..bb070ab 100644 --- a/test/import.py +++ b/test/import.py @@ -33,6 +33,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + platforms = [ 'aix', 'cygwin', @@ -139,27 +141,33 @@ tools = [ # Intel no compiler warning.. intel_no_compiler_fmt = """ -scons: warning: Failed to find Intel compiler for version='None', abi='%s' -File "SConstruct", line 1, in ? +scons: warning: Failed to find Intel compiler for version='None', abi='%(abi)s' +File "%(SConstruct_path)s", line 1, in ? """ -intel_no_compiler_32_warning = intel_no_compiler_fmt % 'ia32' -intel_no_compiler_64_warning = intel_no_compiler_fmt % 'x86_64' +abi = 'ia32' +intel_no_compiler_32_warning = intel_no_compiler_fmt % locals() + +abi = 'x86_64' +intel_no_compiler_64_warning = intel_no_compiler_fmt % locals() # Intel no top dir warning. intel_no_top_dir_fmt = """ -scons: warning: Can't find Intel compiler top dir for version='None', abi='%s' -File "SConstruct", line 1, in ? -""" +scons: warning: Can't find Intel compiler top dir for version='None', abi='%(abi)s' +File "%(SConstruct_path)s", line 1, in ? +""" % locals() -intel_no_top_dir_32_warning = intel_no_top_dir_fmt % 'ia32' -intel_no_top_dir_64_warning = intel_no_top_dir_fmt % 'x86_64' +abi = 'ia32' +intel_no_top_dir_32_warning = intel_no_top_dir_fmt % locals() + +abi = 'x86_64' +intel_no_top_dir_64_warning = intel_no_top_dir_fmt % locals() # Intel no license directory warning intel_license_warning = """ scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort. -File "SConstruct", line 1, in ? -""" +File "%(SConstruct_path)s", line 1, in ? +""" % locals() intel_warnings = [ intel_license_warning, @@ -176,15 +184,20 @@ intel_warnings = [ moc = test.where_is('moc') if moc: import os.path + + qtdir = os.path.dirname(os.path.dirname(moc)) + qt_err = """ -scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%s) -File "SConstruct", line 1, in ? -""" % os.path.dirname(os.path.dirname(moc)) +scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%(qtdir)s) +File "%(SConstruct_path)s", line 1, in ? +""" % locals() + else: + qt_err = """ scons: warning: Could not detect qt, using empty QTDIR -File "SConstruct", line 1, in ? -""" +File "%(SConstruct_path)s", line 1, in ? +""" % locals() error_output = { 'icl' : intel_warnings, diff --git a/test/long-lines.py b/test/long-lines.py index afa8455..1c501e3 100644 --- a/test/long-lines.py +++ b/test/long-lines.py @@ -73,6 +73,8 @@ env.SharedLibrary(target = 'shared', source = 'shared.c', no_import_lib=1) """ % (arflag_init, arflag, linkflag_init, linkflag)) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -83,6 +85,8 @@ main(int argc, char *argv[]) """) test.write('static.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -93,6 +97,8 @@ main(int argc, char *argv[]) """) test.write('shared.c', r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/multi.py b/test/multi.py index 5a5d667..c8b8df4 100644 --- a/test/multi.py +++ b/test/multi.py @@ -36,6 +36,7 @@ import TestSCons test = TestSCons.TestSCons(match=TestCmd.match_re) +_python_ = TestSCons._python_ # # A builder with "multi" set can be called multiple times and @@ -131,11 +132,11 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:]) test.write('SConstruct', """ -B = Builder(action='%(python)s build.py $foo $TARGET $SOURCES', multi=1) +B = Builder(action='%(_python_)s build.py $foo $TARGET $SOURCES', multi=1) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'file03.out', source = 'file03a.in', foo=1) env.B(target = 'file03.out', source = 'file03b.in', foo=2) -""" % {'python':TestSCons.python}) +""" % locals()) test.write('file03a.in', 'file03a.in\n') test.write('file03b.in', 'file03b.in\n') @@ -162,17 +163,17 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:]) test.write('SConstruct', """ -B = Builder(action='%(python)s build.py $foo $TARGET $SOURCES', multi=1) +B = Builder(action='%(_python_)s build.py $foo $TARGET $SOURCES', multi=1) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'file4.out', source = 'file4a.in', foo=3) env.B(target = 'file4.out', source = 'file4b.in', foo=3) -""" % {'python':TestSCons.python}) +""" % locals()) test.write('file4a.in', 'file4a.in\n') test.write('file4b.in', 'file4b.in\n') python_expr = string.replace(TestSCons.python, '\\', '\\\\') -act = TestSCons.re_escape('%s build.py \$foo \$TARGET \$SOURCES' % python_expr) +act = TestSCons.re_escape('"%s" build.py \$foo \$TARGET \$SOURCES' % python_expr) test.run(arguments='file4.out', stderr=(""" diff --git a/test/multiline.py b/test/multiline.py index 302e17d..59eba60 100644 --- a/test/multiline.py +++ b/test/multiline.py @@ -29,6 +29,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,14 +43,14 @@ sys.exit(0) """) test.write('SConstruct', """ -B1 = Builder(action = [ [ r'%s', 'build.py', '.temp', '$SOURCES' ], - [ r'%s', 'build.py', '$TARGETS', '.temp'] ]) -B2 = Builder(action = r'%s' + " build.py .temp $SOURCES\\n" + r'%s' + " build.py $TARGETS .temp") +B1 = Builder(action = [ [ r'%(python)s', 'build.py', '.temp', '$SOURCES' ], + [ r'%(python)s', 'build.py', '$TARGETS', '.temp'] ]) +B2 = Builder(action = r'%(_python_)s' + ' build.py .temp $SOURCES\\n' + r'%(_python_)s' + " build.py $TARGETS .temp") env = Environment(BUILDERS = { 'B1' : B1, 'B2' : B2 }) env.B1(target = 'foo1.out', source = 'foo1.in') env.B2(target = 'foo2.out', source = 'foo2.in') env.B1(target = 'foo3.out', source = 'foo3.in') -""" % (python, python, python, python)) +""" % locals()) test.write('foo1.in', "foo1.in\n") diff --git a/test/option--.py b/test/option--.py index 5f70769..9540397 100644 --- a/test/option--.py +++ b/test/option--.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,16 +41,16 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = '-f1.out', source = 'f1.in') env.MyBuild(target = '-f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") -expect = test.wrap_stdout("%s build.py -f1.out\n%s build.py -f2.out\n" % (python, python)) +expect = test.wrap_stdout('%(_python_)s build.py -f1.out\n%(_python_)s build.py -f2.out\n' % locals()) test.run(arguments = '-- -f1.out -f2.out', stdout = expect) diff --git a/test/option--D.py b/test/option--D.py index d1a118e..cca8ed1 100644 --- a/test/option--D.py +++ b/test/option--D.py @@ -28,7 +28,7 @@ import sys import TestSCons import os -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,14 +44,14 @@ file.close() test.write('SConstruct', """ import SCons.Defaults -B = Builder(action=r'%s build.py $TARGET $SOURCES') +B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES') env = Environment() env['BUILDERS']['B'] = B env.B(target = 'sub1/foo.out', source = 'sub1/foo.in') Export('env') SConscript('sub1/SConscript') SConscript('sub2/SConscript') -""" % python) +""" % locals()) test.write(['sub1', 'SConscript'], """ Import('env') diff --git a/test/option--Q.py b/test/option--Q.py index 4d1a005..f99031c 100644 --- a/test/option--Q.py +++ b/test/option--Q.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,19 +41,19 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGET') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGET') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") test.run(arguments = '-Q f1.out f2.out', stdout = """\ -%s build.py f1.out -%s build.py f2.out -""" % (python, python)) +%(_python_)s build.py f1.out +%(_python_)s build.py f2.out +""" % locals()) test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.fail_test(not os.path.exists(test.workpath('f2.out'))) diff --git a/test/option--U.py b/test/option--U.py index db6532e..3b0cc0d 100644 --- a/test/option--U.py +++ b/test/option--U.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.subdir('sub1', 'sub2', 'sub3') @@ -47,7 +47,7 @@ file.close() test.write('SConstruct', r""" import SCons.Defaults env = Environment() -env['BUILDERS']['B'] = Builder(action=r'%s build.py $TARGET $SOURCES', multi=1) +env['BUILDERS']['B'] = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES', multi=1) Default(env.B(target = 'sub1/foo.out', source = 'sub1/foo.in')) Export('env') SConscript('sub2/SConscript') @@ -56,7 +56,7 @@ BuildDir('sub2b', 'sub2') SConscript('sub2b/SConscript') Default(env.B(target = 'sub2/xxx.out', source = 'xxx.in')) SConscript('SConscript') -""" % python) +""" % locals()) test.write(['sub2', 'SConscript'], """ Import('env') diff --git a/test/option--Y.py b/test/option--Y.py index 62d8b7a..99d6939 100644 --- a/test/option--Y.py +++ b/test/option--Y.py @@ -49,6 +49,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """) test.write(['repository', 'aaa.c'], r""" +#include <stdio.h> void aaa(void) { @@ -57,6 +58,7 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include <stdio.h> void bbb(void) { @@ -65,6 +67,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -95,6 +99,8 @@ test.up_to_date(chdir = 'work1', options = opts, arguments = '.') # test.write(['work1', 'bbb.c'], r""" +#include <stdio.h> +#include <stdlib.h> void bbb(void) { @@ -113,6 +119,8 @@ test.up_to_date(chdir = 'work1', options = opts, arguments = '.') # test.write(['work1', 'aaa.c'], r""" +#include <stdio.h> +#include <stdlib.h> void aaa(void) { @@ -121,6 +129,8 @@ aaa(void) """) test.write(['work1', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> extern void aaa(void); extern void bbb(void); int @@ -175,6 +185,8 @@ test.write(['r.OLD', 'SConstruct'], SConstruct) test.write(['r.NEW', 'SConstruct'], SConstruct) test.write(['r.OLD', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -201,6 +213,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = '.') test.writable('r.NEW', 1) test.write(['r.NEW', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -220,6 +234,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = '.') # test.write(['work2', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -240,6 +256,8 @@ test.writable('r.OLD', 1) test.writable('r.NEW', 1) test.write(['r.OLD', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -250,6 +268,8 @@ main(int argc, char *argv[]) """) test.write(['r.NEW', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/option--cs.py b/test/option--cs.py index 16a3a73..1e62c49 100644 --- a/test/option--cs.py +++ b/test/option--cs.py @@ -34,7 +34,7 @@ import shutil import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj @@ -51,6 +51,8 @@ for src in sys.argv[2:]: file.close() """) +cache = test.workpath('cache') + test.write(['src1', 'SConstruct'], """ def cat(env, source, target): target = str(target[0]) @@ -61,13 +63,13 @@ def cat(env, source, target): f.write(open(src, "rb").read()) f.close() env = Environment(BUILDERS={'Internal':Builder(action=cat), - 'External':Builder(action='%s build.py $TARGET $SOURCES')}) + 'External':Builder(action='%(_python_)s build.py $TARGET $SOURCES')}) env.External('aaa.out', 'aaa.in') env.External('bbb.out', 'bbb.in') env.Internal('ccc.out', 'ccc.in') env.Internal('all', ['aaa.out', 'bbb.out', 'ccc.out']) -CacheDir(r'%s') -""" % (python, test.workpath('cache'))) +CacheDir(r'%(cache)s') +""" % locals()) test.write(['src1', 'aaa.in'], "aaa.in\n") test.write(['src1', 'bbb.in'], "bbb.in\n") @@ -103,14 +105,14 @@ test.run(chdir = 'src1', arguments = '-c .') # Verify that using --cache-show reports the files as being rebuilt, # even though we actually fetch them from the cache. Then clean up. -test.run(chdir = 'src1', - arguments = '--cache-show .', - stdout = test.wrap_stdout("""\ -%s build.py aaa.out aaa.in -%s build.py bbb.out bbb.in +expect = test.wrap_stdout("""\ +%(_python_)s build.py aaa.out aaa.in +%(_python_)s build.py bbb.out bbb.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""" % (python, python))) +""" % locals()) + +test.run(chdir = 'src1', arguments = '--cache-show .', stdout = expect) test.must_not_exist(test.workpath('src1', 'cat.out')) @@ -121,14 +123,14 @@ test.run(chdir = 'src1', arguments = '-c .') # Verify that using --cache-show -n reports the files as being rebuilt, # even though we don't actually fetch them from the cache. No need to # clean up. -test.run(chdir = 'src1', - arguments = '--cache-show -n .', - stdout = test.wrap_stdout("""\ -%s build.py aaa.out aaa.in -%s build.py bbb.out bbb.in +expect = test.wrap_stdout("""\ +%(_python_)s build.py aaa.out aaa.in +%(_python_)s build.py bbb.out bbb.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""" % (python, python))) +""" % locals()) + +test.run(chdir = 'src1', arguments = '--cache-show -n .', stdout = expect) test.must_not_exist(test.workpath('src1', 'cat.out')) @@ -158,6 +160,8 @@ CacheDir(r'%s') """ % (test.workpath('cache'))) test.write(['src2', 'hello.c'], r"""\ +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { diff --git a/test/option--debug.py b/test/option--debug.py index f60710d..a56f261 100644 --- a/test/option--debug.py +++ b/test/option--debug.py @@ -24,12 +24,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons import sys import string import re import time +import TestSCons + +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.write('SConstruct', """ @@ -70,7 +73,7 @@ test.write('bar.h', """ 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.fail_test(string.find(test.stdout(), "SCons") == -1) ############################ # test --debug=presub @@ -93,7 +96,7 @@ FILE = Builder(action="$FILECOM") TEMP = Builder(action="$TEMPCOM") LIST = Builder(action="$LISTCOM") FUNC = Builder(action=cat) -env = Environment(PYTHON='%s', +env = Environment(PYTHON='%(_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", @@ -116,7 +119,7 @@ env.LIST('file15.out', 'file15.in') env.LIST('file16.out', 'file16.in') env.FUNC('file17.out', 'file17.in') env.FUNC('file18.out', 'file18.in') -""" % TestSCons.python) +""" % locals()) test.write('file01.in', "file01.in\n") test.write('file02.in', "file02.in\n") @@ -139,34 +142,34 @@ test.write('file18.in', "file18.in\n") expect = """\ Building file01.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file01.in file01.out +%(_python_)s cat.py file01.in file01.out Building file02.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file02.in file02.out +%(_python_)s cat.py file02.in file02.out Building file03.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file03.in temp +%(_python_)s cat.py file03.in temp Building file03.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file03.out +%(_python_)s cat.py temp file03.out Building file04.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file04.in temp +%(_python_)s cat.py file04.in temp Building file04.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file04.out +%(_python_)s cat.py temp file04.out Building file05.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file05.in temp +%(_python_)s cat.py file05.in temp Building file05.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file05.out +%(_python_)s cat.py temp file05.out Building file06.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file06.in temp +%(_python_)s cat.py file06.in temp Building file06.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file06.out +%(_python_)s cat.py temp file06.out Building file07.out with action: cat(target, source, env) cat(["file07.out"], ["file07.in"]) @@ -178,42 +181,42 @@ Building file09.out with action: cat(["file09.out"], ["file09.in"]) Building file11.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file11.in file11.out +%(_python_)s cat.py file11.in file11.out Building file12.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file12.in file12.out +%(_python_)s cat.py file12.in file12.out Building file13.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file13.in temp +%(_python_)s cat.py file13.in temp Building file13.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file13.out +%(_python_)s cat.py temp file13.out Building file14.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file14.in temp +%(_python_)s cat.py file14.in temp Building file14.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file14.out +%(_python_)s cat.py temp file14.out Building file15.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file15.in temp +%(_python_)s cat.py file15.in temp Building file15.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file15.out +%(_python_)s cat.py temp file15.out Building file16.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file16.in temp +%(_python_)s cat.py file16.in temp Building file16.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file16.out +%(_python_)s cat.py temp file16.out Building file17.out with action: cat(target, source, env) cat(["file17.out"], ["file17.in"]) Building file18.out with action: cat(target, source, env) cat(["file18.out"], ["file18.in"]) -""" -expect = string.replace(expect, '__PYTHON__', TestSCons.python) +""" % locals() + test.run(arguments = "--debug=presub .", stdout=test.wrap_stdout(expect)) test.must_match('file01.out', "file01.in\n") diff --git a/test/option--max-drift.py b/test/option--max-drift.py index bc26f33..1ac077a 100644 --- a/test/option--max-drift.py +++ b/test/option--max-drift.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -43,11 +43,11 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") @@ -59,8 +59,8 @@ test.run(arguments = 'f1.out') test.run(arguments = 'f1.out f2.out', stdout = test.wrap_stdout( """scons: `f1.out' is up to date. -%s build.py f2.out f2.in -""" % python)) +%(_python_)s build.py f2.out f2.in +""" % locals())) atime = os.path.getatime(test.workpath('f1.in')) mtime = os.path.getmtime(test.workpath('f1.in')) @@ -72,11 +72,12 @@ os.utime(test.workpath('f1.in'), (atime,mtime)) test.up_to_date(options='--max-drift=0', arguments='f1.out f2.out') -test.run(arguments = '--max-drift=-1 f1.out f2.out', - stdout = test.wrap_stdout( -"""%s build.py f1.out f1.in +expect = test.wrap_stdout( +"""%(_python_)s build.py f1.out f1.in scons: `f2.out' is up to date. -""" % python)) +""" % locals()) + +test.run(arguments = '--max-drift=-1 f1.out f2.out', stdout = expect) # Test that Set/GetOption('max_drift') works: test.write('SConstruct', """ @@ -99,10 +100,10 @@ test.run(arguments='--max-drift=1') # by mucking with the file timestamps to make SCons not realize the source has changed test.write('SConstruct', """ SetOption('max_drift', 0) -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.write('foo.in', 'foo.in\n') diff --git a/test/option-c.py b/test/option-c.py index 8814827..7ab4129 100644 --- a/test/option-c.py +++ b/test/option-c.py @@ -32,7 +32,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo1.out', source = 'foo1.in') env.B(target = 'foo2.out', source = 'foo2.xxx') @@ -67,7 +67,7 @@ if hasattr(os, 'symlink'): env.Command(['touch1.out', 'touch2.out'], [], [Touch('${TARGETS[0]}'), Touch('${TARGETS[1]}')]) -""" % python) +""" % locals()) test.write('foo1.in', "foo1.in\n") @@ -191,7 +191,7 @@ test.write(['subd', 'foox.in'], "foox.in\n") test.write('aux1.x', "aux1.x\n") test.write('aux2.x', "aux2.x\n") test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }, FOO = 'foo2') env.B(target = 'foo1.out', source = 'foo1.in') env.B(target = 'foo2.out', source = 'foo2.xxx') @@ -201,7 +201,7 @@ SConscript('subd/SConscript') Clean(foo2_xxx, ['aux1.x']) env.Clean(['${FOO}.xxx'], ['aux2.x']) Clean('.', ['subd']) -""" % python) +""" % locals()) test.write(['subd', 'SConscript'], """ Clean('.', 'foox.in') @@ -248,12 +248,12 @@ test.must_not_exist(test.workpath('subdir')) # Ensure that Set/GetOption('clean') works correctly: test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') assert not GetOption('clean') -"""%python) +""" % locals()) test.write('foo.in', '"Foo", I say!\n') @@ -261,36 +261,36 @@ test.run(arguments='foo.out') test.must_match(test.workpath('foo.out'), '"Foo", I say!\n') test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') assert GetOption('clean') SetOption('clean', 0) assert GetOption('clean') -"""%python) +""" % locals()) test.run(arguments='-c foo.out') test.must_not_exist(test.workpath('foo.out')) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -"""%python) +""" % locals()) test.run(arguments='foo.out') test.must_match(test.workpath('foo.out'), '"Foo", I say!\n') test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') assert not GetOption('clean') SetOption('clean', 1) assert GetOption('clean') -"""%python) +""" % locals()) test.run(arguments='foo.out') test.must_not_exist(test.workpath('foo.out')) diff --git a/test/option-i.py b/test/option-i.py index b0a84f8..a4ea4ac 100644 --- a/test/option-i.py +++ b/test/option-i.py @@ -28,7 +28,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,14 +46,14 @@ sys.exit(1) """) test.write('SConstruct', """ -Succeed = Builder(action = r'%s succeed.py $TARGETS') -Fail = Builder(action = r'%s fail.py $TARGETS') +Succeed = Builder(action = r'%(_python_)s succeed.py $TARGETS') +Fail = Builder(action = r'%(_python_)s fail.py $TARGETS') env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail(target = 'aaa.1', source = 'aaa.in') env.Succeed(target = 'aaa.out', source = 'aaa.1') env.Fail(target = 'bbb.1', source = 'bbb.in') env.Succeed(target = 'bbb.out', source = 'bbb.1') -""" % (python, python)) +""" % locals()) test.write('aaa.in', "aaa.in\n") test.write('bbb.in', "bbb.in\n") diff --git a/test/option-j.py b/test/option-j.py index fdf7b83..8f4c190 100644 --- a/test/option-j.py +++ b/test/option-j.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ try: import threading @@ -64,7 +64,7 @@ foo you """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') @@ -80,7 +80,7 @@ t = env.Command(target=['foo/foo1.out', 'foo/foo2.out'], source='foo/foo.in', action=copyn) env.Install('out', t) -""" % python) +""" % locals()) def RunTest(args, extra): """extra is used to make scons rebuild the output file""" @@ -160,7 +160,7 @@ os.environ['PYTHONPATH'] = save_pythonpath # Test SetJobs() with no -j: test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') @@ -178,7 +178,7 @@ env.Install('out', t) assert GetOption('num_jobs') == 1 SetOption('num_jobs', 2) assert GetOption('num_jobs') == 2 -""" % python) +""" % locals()) # This should be a parallel build because the SConscript sets jobs to 2. # fail if the second file was not started @@ -188,7 +188,7 @@ test.fail_test(not (start2 < finish1)) # Test SetJobs() with -j: test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') @@ -206,7 +206,7 @@ env.Install('out', t) assert GetOption('num_jobs') == 1 SetOption('num_jobs', 2) assert GetOption('num_jobs') == 1 -""" % python) +""" % locals()) # This should be a serial build since -j 1 overrides the call to SetJobs(). # fail if the second file was started @@ -230,14 +230,14 @@ sys.exit(1) """) test.write('SConstruct', """ -MyCopy = Builder(action = r'%s mycopy.py $TARGET $SOURCE') -Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE') +MyCopy = Builder(action = r'%(_python_)s mycopy.py $TARGET $SOURCE') +Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE') env = Environment(BUILDERS = { 'MyCopy' : MyCopy, 'Fail' : Fail }) env.Fail(target = 'f3', source = 'f3.in') env.MyCopy(target = 'f4', source = 'f4.in') env.MyCopy(target = 'f5', source = 'f5.in') env.MyCopy(target = 'f6', source = 'f6.in') -""" % (python, python)) +""" % locals()) test.write('f3.in', "f3.in\n") test.write('f4.in', "f4.in\n") diff --git a/test/option-k.py b/test/option-k.py index 45c31d2..0a46606 100644 --- a/test/option-k.py +++ b/test/option-k.py @@ -28,7 +28,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,13 +50,13 @@ sys.exit(1) """) test.write(['work1', 'SConstruct'], """\ -Succeed = Builder(action = r'%s ../succeed.py $TARGETS') -Fail = Builder(action = r'%s ../fail.py $TARGETS') +Succeed = Builder(action = r'%(_python_)s ../succeed.py $TARGETS') +Fail = Builder(action = r'%(_python_)s ../fail.py $TARGETS') env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail(target = 'aaa.1', source = 'aaa.in') env.Succeed(target = 'aaa.out', source = 'aaa.1') env.Succeed(target = 'bbb.out', source = 'bbb.in') -""" % (python, python)) +""" % locals()) test.write(['work1', 'aaa.in'], "aaa.in\n") test.write(['work1', 'bbb.in'], "bbb.in\n") @@ -93,14 +93,14 @@ test.must_match(['work1', 'bbb.out'], "succeed.py: bbb.out\n") test.write(['work2', 'SConstruct'], """\ -Succeed = Builder(action = r'%s ../succeed.py $TARGETS') -Fail = Builder(action = r'%s ../fail.py $TARGETS') +Succeed = Builder(action = r'%(_python_)s ../succeed.py $TARGETS') +Fail = Builder(action = r'%(_python_)s ../fail.py $TARGETS') env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail('aaa.out', 'aaa.in') env.Succeed('bbb.out', 'aaa.out') env.Succeed('ccc.out', 'ccc.in') env.Succeed('ddd.out', 'ccc.in') -""" % (python, python)) +""" % locals()) test.write(['work2', 'aaa.in'], "aaa.in\n") test.write(['work2', 'ccc.in'], "ccc.in\n") @@ -113,11 +113,11 @@ test.run(chdir = 'work2', scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... -%s ../fail.py aaa.out -%s ../succeed.py ccc.out -%s ../succeed.py ddd.out +%(_python_)s ../fail.py aaa.out +%(_python_)s ../succeed.py ccc.out +%(_python_)s ../succeed.py ddd.out scons: done building targets (errors occurred during build). -""" % (python, python, python)) +""" % locals()) test.must_not_exist(['work2', 'aaa.out']) test.must_not_exist(['work2', 'bbb.out']) diff --git a/test/option-n.py b/test/option-n.py index 769c4dd..2e7694b 100644 --- a/test/option-n.py +++ b/test/option-n.py @@ -47,7 +47,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,14 +61,14 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') env.Install('install', 'f3.in') BuildDir('build', 'src', duplicate=1) SConscript('build/SConscript', "env") -""" % python) +""" % locals()) test.write(['src', 'SConscript'], """ Import("env") @@ -82,9 +82,9 @@ test.write(['src', 'f4.in'], "src/f4.in\n") args = 'f1.out f2.out' expect = test.wrap_stdout("""\ -%s build.py f1.out -%s build.py f2.out -""" % (python, python)) +%(_python_)s build.py f1.out +%(_python_)s build.py f2.out +""" % locals()) test.run(arguments = args, stdout = expect) test.fail_test(not os.path.exists(test.workpath('f1.out'))) @@ -118,8 +118,8 @@ test.fail_test(not os.path.exists(test.workpath('f1.out'))) # Test that SCons does not write a modified .sconsign when -n is used. expect = test.wrap_stdout("""\ -%s build.py f1.out -""" % python) +%(_python_)s build.py f1.out +""" % locals()) test.unlink('.sconsign.dblite') test.write('f1.out', "X1.out\n") test.run(arguments = '-n f1.out', stdout = expect) diff --git a/test/option-q.py b/test/option-q.py index e8460f0..9b67d0a 100644 --- a/test/option-q.py +++ b/test/option-q.py @@ -34,7 +34,7 @@ import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.write('build.py', r""" import sys @@ -45,11 +45,11 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action=r'%s build.py $TARGET $SOURCES') +B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'aaa.out', source = 'aaa.in') env.B(target = 'bbb.out', source = 'bbb.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n") test.write('bbb.in', "bbb.in\n") diff --git a/test/option-s.py b/test/option-s.py index c1061ba..b3bde5f 100644 --- a/test/option-s.py +++ b/test/option-s.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,11 +41,11 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGET') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGET') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") diff --git a/test/option/debug-dtree.py b/test/option/debug-dtree.py index 0a7f4d2..06296b9 100644 --- a/test/option/debug-dtree.py +++ b/test/option/debug-dtree.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-findlibs.py b/test/option/debug-findlibs.py index b18841b..4220402 100644 --- a/test/option/debug-findlibs.py +++ b/test/option/debug-findlibs.py @@ -24,12 +24,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons import sys import string import re import time +import TestSCons + +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.subdir('sub1', 'sub2') @@ -49,9 +52,9 @@ env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx', LIBS = ['iii', 'jjj', 'kkk', 'lll', 'mmm'], LIBPREFIXES = ['a-', 'b-', 'c-'], LIBSUFFIXES = ['.aaa', '.bbb', '.ccc'], - LINKCOM = '%(python)s cat.py $TARGET $SOURCES') + LINKCOM = '%(_python_)s cat.py $TARGET $SOURCES') env.Program('foo', 'a.ooo',) -""" % {'python' : TestSCons.python}) +""" % locals()) test.write('a.ooo', "a.ooo\n") @@ -198,8 +201,8 @@ test.run(arguments = "--debug=findlibs foo.xxx", findlibs: looking for 'c-mmm.ccc' in 'sub1' ... findlibs: looking for 'c-mmm.ccc' in 'sub2' ... findlibs: looking for 'c-mmm.ccc' in '.' ... -%(python)s cat.py foo.xxx a.ooo -""" % {'python' : TestSCons.python})) +%(_python_)s cat.py foo.xxx a.ooo +""" % locals())) test.must_match('foo.xxx', "a.ooo\n") diff --git a/test/option/debug-includes.py b/test/option/debug-includes.py index eb7f818..52d64a9 100644 --- a/test/option/debug-includes.py +++ b/test/option/debug-includes.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-stacktrace.py b/test/option/debug-stacktrace.py index 1a3052a..aff25f2 100644 --- a/test/option/debug-stacktrace.py +++ b/test/option/debug-stacktrace.py @@ -114,4 +114,25 @@ if err and must_contain_all_lines(test.stderr(), inner_lines): +# Test that full path names to SConscript files show up in stack traces. + +test.write('SConstruct', """\ +1/0 +""") + +test.run(arguments = '--debug=stacktrace', + status = 2, + stderr = None) + +lines = [ + ' File "%s", line 1:' % test.workpath('SConstruct'), +] + +err = must_contain_all_lines(test.stderr(), lines) +if err: + print string.join(err, '') + test.fail_test(1) + + + test.pass_test() diff --git a/test/option/debug-stree.py b/test/option/debug-stree.py index 69aab06..8ffadc6 100644 --- a/test/option/debug-stree.py +++ b/test/option/debug-stree.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-time.py b/test/option/debug-time.py index 5766cff..b1471ba 100644 --- a/test/option/debug-time.py +++ b/test/option/debug-time.py @@ -38,6 +38,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-tree.py b/test/option/debug-tree.py index faf85d9..4f025c2 100644 --- a/test/option/debug-tree.py +++ b/test/option/debug-tree.py @@ -47,6 +47,8 @@ env.Program('Foo', Split('Foo.c Bar.c')) # (UNIX/Linux) and case-insensitive (Windows) systems. test.write('Foo.c', r""" +#include <stdio.h> +#include <stdlib.h> #include "Foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/profile.py b/test/option/profile.py index b6a0027..9207066 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -33,7 +33,11 @@ import TestSCons test = TestSCons.TestSCons() -test.write('SConstruct', "\n") +test.write('SConstruct', """\ +Command('file.out', 'file.in', Copy("$TARGET", "$SOURCE")) +""") + +test.write('file.in', "file.in\n") scons_prof = test.workpath('scons.prof') @@ -63,30 +67,30 @@ test.fail_test(string.find(s, 'option_parser.py') == -1) scons_prof = test.workpath('scons2.prof') -test.run(arguments = "--profile %s -h" % scons_prof) -test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1) -test.fail_test(string.find(test.stdout(), 'Options:') == -1) +test.run(arguments = "--profile %s" % scons_prof) stats = pstats.Stats(scons_prof) stats.sort_stats('time') -sys.stdout = StringIO.StringIO() +try: + save_stdout = sys.stdout + sys.stdout = StringIO.StringIO() -stats.strip_dirs().print_stats() + stats.strip_dirs().print_stats() -s = sys.stdout.getvalue() + s = sys.stdout.getvalue() +finally: + sys.stdout = save_stdout test.fail_test(string.find(s, 'Main.py') == -1) -test.fail_test(string.find(s, 'print_help') == -1) test.fail_test(string.find(s, '_main') == -1) -test.fail_test(string.find(s, 'option_parser.py') == -1) +test.fail_test(string.find(s, 'FS.py') == -1) scons_prof = test.workpath('scons3.prof') test.run(arguments = "--profile %s --debug=memory -h" % scons_prof) -print test.stdout() test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1) test.fail_test(string.find(test.stdout(), 'Options:') == -1) diff --git a/test/overrides.py b/test/overrides.py index 69f7440..dabf689 100644 --- a/test/overrides.py +++ b/test/overrides.py @@ -31,7 +31,7 @@ import sys test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.write('SConstruct', """ env = Environment(CCFLAGS='-DFOO', LIBS=['a']) @@ -69,11 +69,11 @@ env['LIBS'] = buildlibs test.write('SConstruct', """ env = Environment() env.Program('hello', 'hello.c', - CC=r'%s mycc.py', - LINK=r'%s mylink.py', + CC=r'%(_python_)s mycc.py', + LINK=r'%(_python_)s mylink.py', OBJSUFFIX='.not_obj', PROGSUFFIX='.not_exe') -"""%(python,python)) +""" % locals()) test.write('hello.c',"this ain't no c file!\n") @@ -97,13 +97,13 @@ test.up_to_date(arguments='hello.not_exe') test.write('SConstruct', """\ env = Environment() env.Program('goodbye', 'goodbye.c', - CC=r'%s mycc.py', - LINK=r'%s mylink.py', + CC=r'%(_python_)s mycc.py', + LINK=r'%(_python_)s mylink.py', OBJSUFFIX='.not_obj', PROGSUFFIX='.not_exe', targets='ttt', sources='sss') -""" % (python, python)) +""" % locals()) test.write('goodbye.c',"this ain't no c file!\n") diff --git a/test/redirection.py b/test/redirection.py index 5aac517..cededdb 100644 --- a/test/redirection.py +++ b/test/redirection.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,14 +44,14 @@ sys.exit(0) test.write('SConstruct', r""" env = Environment() env.Command(target='foo1', source='bar1', - action= '%s cat.py $SOURCES > $TARGET') + action= '%(_python_)s cat.py $SOURCES > $TARGET') env.Command(target='foo2', source='bar2', - action= '%s cat.py < $SOURCES > $TARGET') + action= '%(_python_)s cat.py < $SOURCES > $TARGET') env.Command(target='foo3', source='bar3', - action='%s cat.py $SOURCES | %s cat.py > $TARGET') + action='%(_python_)s cat.py $SOURCES | %(_python_)s cat.py > $TARGET') env.Command(target='foo4', source='bar4', - action='%s cat.py <$SOURCES |%s cat.py >$TARGET') -""" % (python, python, python, python, python, python)) + action='%(_python_)s cat.py <$SOURCES |%(_python_)s cat.py >$TARGET') +""" % locals()) test.write('bar1', 'bar1\r\n') test.write('bar2', 'bar2\r\n') diff --git a/test/runtest/aegis/batch-output.py b/test/runtest/aegis/batch-output.py new file mode 100644 index 0000000..4020239 --- /dev/null +++ b/test/runtest/aegis/batch-output.py @@ -0,0 +1,60 @@ +#!/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 writing Aegis batch output to a file. +""" + +import TestRuntest + +test = TestRuntest.TestRuntest() + +test.subdir('test') + +test.write_failing_test(['test', 'fail.py']) + +test.write_no_result_test(['test', 'no_result.py']) + +test.write_passing_test(['test', 'pass.py']) + +test.run(arguments = '-o aegis.out --aegis test', status=1) + +expect = """\ +test_result = [ + { file_name = "test/fail.py"; + exit_status = 1; }, + { file_name = "test/no_result.py"; + exit_status = 2; }, + { file_name = "test/pass.py"; + exit_status = 0; }, +]; +""" + +# The mode is 'r' (not default 'rb') because QMTest opens the file +# description on which we write as non-binary. +test.must_match('aegis.out', expect, mode='r') + +test.pass_test() diff --git a/test/runtest/baseline/combined.py b/test/runtest/baseline/combined.py index 6382cb1..ab91e87 100644 --- a/test/runtest/baseline/combined.py +++ b/test/runtest/baseline/combined.py @@ -30,8 +30,14 @@ Test a combination of a passing test, failing test, and no-result test with no argument on the command line. """ +import os.path + import TestRuntest +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') +test_pass_py = os.path.join('test', 'pass.py') + test = TestRuntest.TestRuntest() test.subdir('test') @@ -45,37 +51,37 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test --- TEST RESULTS ------------------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL FAILING TEST STDOUT FAILING TEST STDERR - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT NO RESULT TEST STDERR - test/pass.py : PASS + %(test_pass_py)s : PASS --- TESTS WITH UNEXPECTED OUTCOMES ------------------------------------------- - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT - test/pass.py : PASS + %(test_pass_py)s : PASS --- STATISTICS --------------------------------------------------------------- - 1 ( 33%) tests as expected - 1 ( 33%) tests unexpected PASS - 1 ( 33%) tests unexpected NO_RESULT -""" + 1 ( 33%%) tests as expected + 1 ( 33%%) tests unexpected PASS + 1 ( 33%%) tests unexpected NO_RESULT +""" % locals() -test.run(arguments = '--qmtest -b . test', stdout = expect) +test.run(arguments = '-b . test', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/baseline/fail.py b/test/runtest/baseline/fail.py index b650a8c..b61e5da 100644 --- a/test/runtest/baseline/fail.py +++ b/test/runtest/baseline/fail.py @@ -38,7 +38,7 @@ test.write_failing_test(['test', 'fail.py']) # NOTE: The "test/fail.py : FAIL" line has spaces at the end. -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/fail.py +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/fail.py --- TEST RESULTS ------------------------------------------------------------- test/fail.py : FAIL @@ -57,6 +57,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 1 (100%) tests as expected """ -test.run(arguments = '--qmtest -b . test/fail.py', stdout = expect) +test.run(arguments = '-b . test/fail.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/baseline/no_result.py b/test/runtest/baseline/no_result.py index dc2586d..9ef815d 100644 --- a/test/runtest/baseline/no_result.py +++ b/test/runtest/baseline/no_result.py @@ -36,7 +36,7 @@ test.subdir('test') test.write_no_result_test(['test', 'no_result.py']) -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/no_result.py +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/no_result.py --- TEST RESULTS ------------------------------------------------------------- test/no_result.py : NO_RESULT @@ -55,6 +55,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 1 (100%) tests unexpected NO_RESULT """ -test.run(arguments = '--qmtest -b . test/no_result.py', stdout = expect) +test.run(arguments = '-b . test/no_result.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/baseline/pass.py b/test/runtest/baseline/pass.py index b32ecbe..f574e57 100644 --- a/test/runtest/baseline/pass.py +++ b/test/runtest/baseline/pass.py @@ -38,7 +38,7 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/pass.py : PASS" line has spaces at the end. -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/pass.py +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/pass.py --- TEST RESULTS ------------------------------------------------------------- test/pass.py : PASS @@ -53,6 +53,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 1 (100%) tests unexpected PASS """ -test.run(arguments = '--qmtest -b . test/pass.py', stdout = expect) +test.run(arguments = '-b . test/pass.py', stdout = expect) test.pass_test() diff --git a/test/runtest/fallback.py b/test/runtest/fallback.py new file mode 100644 index 0000000..90cd4f2 --- /dev/null +++ b/test/runtest/fallback.py @@ -0,0 +1,104 @@ +#!/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 that runtest.py falls back (with a warning) using --noqmtest +if it can't find qmtest.py on the $PATH. +""" + +import os +import os.path +import re +import string + +import TestRuntest + +python = TestRuntest.python +_python_ = TestRuntest._python_ + +test = TestRuntest.TestRuntest(noqmtest=1) + +qmtest_py = test.where_is('qmtest.py') + +if qmtest_py: + dir = os.path.split(qmtest_py)[0] + path = string.split(os.environ['PATH'], os.pathsep) + path.remove(dir) + os.environ['PATH'] = string.join(path, os.pathsep) + +test.subdir('test') + +test_pass_py = os.path.join('test', 'pass.py') +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') + +workpath_pass_py = test.workpath(test_pass_py) +workpath_fail_py = test.workpath(test_fail_py) +workpath_no_result_py = test.workpath(test_no_result_py) + +test.write_failing_test(test_fail_py) +test.write_no_result_test(test_no_result_py) +test.write_passing_test(test_pass_py) + +if re.search('\s', python): + expect_python = _python_ +else: + expect_python = python + +expect_stdout = """\ +%(expect_python)s -tt %(workpath_fail_py)s +FAILING TEST STDOUT +%(expect_python)s -tt %(workpath_no_result_py)s +NO RESULT TEST STDOUT +%(expect_python)s -tt %(workpath_pass_py)s +PASSING TEST STDOUT + +Failed the following test: +\t%(test_fail_py)s + +NO RESULT from the following test: +\t%(test_no_result_py)s +""" % locals() + +expect_stderr = """\ +Warning: qmtest.py not found on $PATH, assuming --noqmtest option. +FAILING TEST STDERR +NO RESULT TEST STDERR +PASSING TEST STDERR +""" + +testlist = [ + test_fail_py, + test_no_result_py, + test_pass_py, +] + +test.run(arguments = string.join(testlist), + status = 1, + stdout = expect_stdout, + stderr = expect_stderr) + +test.pass_test() diff --git a/test/runtest/noqmtest.py b/test/runtest/noqmtest.py new file mode 100644 index 0000000..c442125 --- /dev/null +++ b/test/runtest/noqmtest.py @@ -0,0 +1,94 @@ +#!/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 that the --noqmtest option invokes tests directly via Python, not +using qmtest. +""" + +import os.path +import re +import string + +import TestRuntest + +python = TestRuntest.python +_python_ = TestRuntest._python_ + +test = TestRuntest.TestRuntest(noqmtest=1) + +test.subdir('test') + +test_pass_py = os.path.join('test', 'pass.py') +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') + +workpath_pass_py = test.workpath(test_pass_py) +workpath_fail_py = test.workpath(test_fail_py) +workpath_no_result_py = test.workpath(test_no_result_py) + +test.write_failing_test(test_fail_py) +test.write_no_result_test(test_no_result_py) +test.write_passing_test(test_pass_py) + +if re.search('\s', python): + expect_python = _python_ +else: + expect_python = python + +expect_stdout = """\ +%(expect_python)s -tt %(workpath_fail_py)s +FAILING TEST STDOUT +%(expect_python)s -tt %(workpath_no_result_py)s +NO RESULT TEST STDOUT +%(expect_python)s -tt %(workpath_pass_py)s +PASSING TEST STDOUT + +Failed the following test: +\t%(test_fail_py)s + +NO RESULT from the following test: +\t%(test_no_result_py)s +""" % locals() + +expect_stderr = """\ +FAILING TEST STDERR +NO RESULT TEST STDERR +PASSING TEST STDERR +""" + +testlist = [ + test_fail_py, + test_no_result_py, + test_pass_py, +] + +test.run(arguments = '--noqmtest %s' % string.join(testlist), + status = 1, + stdout = expect_stdout, + stderr = expect_stderr) + +test.pass_test() diff --git a/test/runtest/print_time.py b/test/runtest/print_time.py index 1d86baa..39bf810 100644 --- a/test/runtest/print_time.py +++ b/test/runtest/print_time.py @@ -29,9 +29,16 @@ Test a combination of a passing test, failing test, and no-result test with no argument on the command line. """ +import os.path +import re + import TestCmd import TestRuntest +test_fail_py = re.escape(os.path.join('test', 'fail.py')) +test_no_result_py = re.escape(os.path.join('test', 'no_result.py')) +test_pass_py = re.escape(os.path.join('test', 'pass.py')) + test = TestRuntest.TestRuntest(match = TestCmd.match_re) test.subdir('test') @@ -45,10 +52,10 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream --context print_time=1 test +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream\(print_time='1'\)" test --- TEST RESULTS ------------------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL FAILING TEST STDOUT @@ -56,7 +63,7 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc Total execution time: \d+\.\d+ seconds - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT @@ -64,26 +71,26 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc Total execution time: \d+\.\d+ seconds - test/pass.py : PASS + %(test_pass_py)s : PASS Total execution time: \d+\.\d+ seconds --- TESTS THAT DID NOT PASS -------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT --- STATISTICS --------------------------------------------------------------- 3 tests total - 1 \( 33%\) tests PASS - 1 \( 33%\) tests FAIL - 1 \( 33%\) tests NO_RESULT -""" + 1 \( 33%%\) tests PASS + 1 \( 33%%\) tests FAIL + 1 \( 33%%\) tests NO_RESULT +""" % locals() -test.run(arguments = '--qmtest -t test', stdout = expect) +test.run(arguments = '-t test', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/python.py b/test/runtest/python.py index 76eec7d..1af32dd 100644 --- a/test/runtest/python.py +++ b/test/runtest/python.py @@ -28,35 +28,40 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test that the -P option lets us specify a Python version to use. """ +import os.path +import re +import sys + +if not hasattr(os.path, 'pardir'): + os.path.pardir = '..' + import TestRuntest test = TestRuntest.TestRuntest() -mypython_py = test.workpath('mypython.py') -mypython_out = test.workpath('mypython.out') +test_pass_py = os.path.join('test', 'pass.py') -test.subdir('test') +head, python = os.path.split(TestRuntest.python) +head, dir = os.path.split(head) -test.write_passing_test(['test', 'pass.py']) +mypython = os.path.join(head, dir, os.path.pardir, dir, python) -test.write(mypython_py, """\ -#!/usr/bin/env python -import os -import sys -import string -open(r'%s', 'a').write(string.join(sys.argv) + '\\n') -os.system(string.join([sys.executable] + sys.argv[1:])) -""" % mypython_out) +if re.search('\s', mypython): + _mypython_ = '"' + mypython + '"' +else: + _mypython_ = mypython -test.chmod(mypython_py, 0755) +test.subdir('test') + +test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream --context python=%(mypython_py)s test +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" --context python="%(mypython)s" test --- TEST RESULTS ------------------------------------------------------------- - test/pass.py : PASS + %(test_pass_py)s : PASS --- TESTS THAT DID NOT PASS -------------------------------------------------- @@ -70,11 +75,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%%) tests PASS """ % locals() -test.run(arguments = '--qmtest -P %s test' % mypython_py, - stdout = expect) - -test.must_match(mypython_out, """\ -%s ./test/pass.py -""" % mypython_py) +test.run(arguments = '-P %s test' % _mypython_, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/combined.py b/test/runtest/simple/combined.py index 1640d94..58d2f27 100644 --- a/test/runtest/simple/combined.py +++ b/test/runtest/simple/combined.py @@ -30,10 +30,16 @@ Test a combination of a passing test, failing test, and no-result test with no argument on the command line. """ +import os.path + import TestRuntest test = TestRuntest.TestRuntest() +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') +test_pass_py = os.path.join('test', 'pass.py') + test.subdir('test') test.write_failing_test(['test', 'fail.py']) @@ -45,39 +51,39 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test --- TEST RESULTS ------------------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL FAILING TEST STDOUT FAILING TEST STDERR - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT NO RESULT TEST STDERR - test/pass.py : PASS + %(test_pass_py)s : PASS --- TESTS THAT DID NOT PASS -------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT --- STATISTICS --------------------------------------------------------------- 3 tests total - 1 ( 33%) tests PASS - 1 ( 33%) tests FAIL - 1 ( 33%) tests NO_RESULT -""" + 1 ( 33%%) tests PASS + 1 ( 33%%) tests FAIL + 1 ( 33%%) tests NO_RESULT +""" % locals() -test.run(arguments = '--qmtest test', stdout = expect) +test.run(arguments = 'test', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/fail.py b/test/runtest/simple/fail.py index ba2cc97..ec9f532 100644 --- a/test/runtest/simple/fail.py +++ b/test/runtest/simple/fail.py @@ -38,7 +38,7 @@ test.write_failing_test(['test', 'fail.py']) # NOTE: The "test/fail.py : FAIL" line has spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/fail.py +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/fail.py --- TEST RESULTS ------------------------------------------------------------- test/fail.py : FAIL @@ -59,6 +59,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests FAIL """ -test.run(arguments = '--qmtest test/fail.py', stdout = expect) +test.run(arguments = 'test/fail.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/no_result.py b/test/runtest/simple/no_result.py index 7c9687e..4ec6e78 100644 --- a/test/runtest/simple/no_result.py +++ b/test/runtest/simple/no_result.py @@ -36,7 +36,7 @@ test.subdir('test') test.write_no_result_test(['test', 'no_result.py']) -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/no_result.py +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/no_result.py --- TEST RESULTS ------------------------------------------------------------- test/no_result.py : NO_RESULT @@ -57,6 +57,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests NO_RESULT """ -test.run(arguments = '--qmtest test/no_result.py', stdout = expect) +test.run(arguments = 'test/no_result.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/pass.py b/test/runtest/simple/pass.py index 8dfc996..c3a8b02 100644 --- a/test/runtest/simple/pass.py +++ b/test/runtest/simple/pass.py @@ -38,7 +38,7 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/pass.py : PASS" line has spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/pass.py +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/pass.py --- TEST RESULTS ------------------------------------------------------------- test/pass.py : PASS @@ -55,6 +55,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests PASS """ -test.run(arguments = '--qmtest test/pass.py', stdout = expect) +test.run(arguments = 'test/pass.py', stdout = expect) test.pass_test() diff --git a/test/runtest/src.py b/test/runtest/src.py index 2f723b4..3063a4e 100644 --- a/test/runtest/src.py +++ b/test/runtest/src.py @@ -29,6 +29,8 @@ Verify that we find tests under the src/ tree only if they end with *Tests.py. """ +import os.path + import TestRuntest test = TestRuntest.TestRuntest(verbose=1) @@ -36,6 +38,9 @@ test = TestRuntest.TestRuntest(verbose=1) test.subdir(['src'], ['src', 'suite']) +src_passTests_py = os.path.join('src', 'passTests.py') +src_suite_passTests_py = os.path.join('src', 'suite', 'passTests.py') + test.write_passing_test(['src', 'pass.py']) test.write_passing_test(['src', 'passTests.py']) @@ -44,15 +49,15 @@ test.write_passing_test(['src', 'suite', 'pass.py']) test.write_passing_test(['src', 'suite', 'passTests.py']) -# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both -# have spaces at the end. +# NOTE: The "test/pass.py : PASS" and "test/passTests.py : PASS" lines +# both have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream src +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" src --- TEST RESULTS ------------------------------------------------------------- - src/passTests.py : PASS + %(src_passTests_py)s : PASS - src/suite/passTests.py : PASS + %(src_suite_passTests_py)s : PASS --- TESTS THAT DID NOT PASS -------------------------------------------------- @@ -63,9 +68,9 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 2 tests total - 2 (100%) tests PASS -""" + 2 (100%%) tests PASS +""" % locals() -test.run(arguments = '--qmtest src', stdout = expect) +test.run(arguments = 'src', stdout = expect) test.pass_test() diff --git a/test/runtest/testlistfile.py b/test/runtest/testlistfile.py new file mode 100644 index 0000000..d738530 --- /dev/null +++ b/test/runtest/testlistfile.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__" + +""" +Test a list of tests to run in a file specified with the -f option. +""" + +import os.path + +import TestCmd +import TestRuntest + +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') +test_pass_py = os.path.join('test', 'pass.py') + +test = TestRuntest.TestRuntest() + +test.subdir('test') + +test.write_failing_test(['test', 'fail.py']) + +test.write_no_result_test(['test', 'no_result.py']) + +test.write_passing_test(['test', 'pass.py']) + +test.write('t.txt', """\ +#%(test_fail_py)s +%(test_pass_py)s +""" % locals()) + +# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both +# have spaces at the end. + +expect = """qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" %(test_pass_py)s +--- TEST RESULTS ------------------------------------------------------------- + + %(test_pass_py)s : PASS + +--- TESTS THAT DID NOT PASS -------------------------------------------------- + + None. + + +--- STATISTICS --------------------------------------------------------------- + + 1 tests total + + 1 (100%%) tests PASS +""" % locals() + +test.run(arguments = '-f t.txt', stdout = expect) + +test.pass_test() diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py new file mode 100644 index 0000000..e1c14cf --- /dev/null +++ b/test/runtest/xml/output.py @@ -0,0 +1,191 @@ +#!/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 writing XML output to a file. +""" + +import os.path +import re +import sys + +import TestRuntest + +test = TestRuntest.TestRuntest() + +test_fail_py = re.escape(os.path.join('test', 'fail.py')) +test_no_result_py = re.escape(os.path.join('test', 'no_result.py')) +test_pass_py = re.escape(os.path.join('test', 'pass.py')) + +# sys.stdout and sys.stderr are open non-binary ('w' instead of 'wb') +# so the lines written on Windows are terminated \r\n, not just \n. The +# expressions below use 'cr' as the optional carriage return character. +if sys.platform in ['win32']: + cr = '\r' +else: + cr = '' + +test.subdir('test') + +test.write_fake_scons_source_tree() + +test.write_failing_test(['test', 'fail.py']) + +test.write_no_result_test(['test', 'no_result.py']) + +test.write_passing_test(['test', 'pass.py']) + +test.run(arguments = '-o xml.out --xml test', status = 1) + +expect_engine = """\ +<annotation key="scons_test\\.engine"> + __build__='D456' + __buildsys__='another_fake_system' + __date__='Dec 31 1999' + __developer__='John Doe' + __version__='4\\.5\\.6' +</annotation> +""" + +expect_script = """\ +<annotation key="scons_test\\.script"> + __build__='D123' + __buildsys__='fake_system' + __date__='Jan 1 1970' + __developer__='Anonymous' + __version__='1\\.2\\.3' +</annotation> +""" + +# The actual values printed for sys and os.environ will be completely +# dependent on the local values. Don't bother trying to match, just +# look to see if the opening tag exists. + +expect_sys = """\ +<annotation key="scons_test\\.sys"> +""" + +expect_os_environ = """\ +<annotation key="scons_test\\.os\\.environ"> +""" + +expect_fail = """\ + <result id="%(test_fail_py)s" kind="test" outcome="FAIL"> + <annotation name="Test\\.exit_code"> + "1" + </annotation> + <annotation name="Test\\.stderr"> + "<pre>FAILING TEST STDERR%(cr)s +</pre>" + </annotation> + <annotation name="Test\\.stdout"> + "<pre>FAILING TEST STDOUT%(cr)s +</pre>" + </annotation> + <annotation name="qmtest\\.cause"> + "Non-zero exit_code\\." + </annotation> + <annotation name="qmtest\\.end_time"> + "[\\d.]+" + </annotation> + <annotation name="qmtest\\.start_time"> + "[\\d.]+" + </annotation> + <annotation name="qmtest\\.target"> + "local" + </annotation> + </result> +""" % locals() + +expect_no_result = """\ + <result id="%(test_no_result_py)s" kind="test" outcome="FAIL"> + <annotation name="Test.exit_code"> + "2" + </annotation> + <annotation name="Test\\.stderr"> + "<pre>NO RESULT TEST STDERR%(cr)s +</pre>" + </annotation> + <annotation name="Test\\.stdout"> + "<pre>NO RESULT TEST STDOUT%(cr)s +</pre>" + </annotation> + <annotation name="qmtest\\.cause"> + "Non-zero exit_code\\." + </annotation> + <annotation name="qmtest\\.end_time"> + "[\\d.]+" + </annotation> + <annotation name="qmtest\\.start_time"> + "[\\d.]+" + </annotation> + <annotation name="qmtest\\.target"> + "local" + </annotation> + </result> +""" % locals() + +expect_pass = """\ + <result id="%(test_pass_py)s" kind="test" outcome="PASS"> + <annotation name="qmtest\\.end_time"> + "[\\d.]+" + </annotation> + <annotation name="qmtest\\.start_time"> + "[\\d.]+" + </annotation> + <annotation name="qmtest\\.target"> + "local" + </annotation> + </result> +""" % locals() + +xml_out = test.read('xml.out', 'r') + +expect = [ + expect_engine, + expect_script, + expect_sys, + expect_os_environ, + expect_fail, + expect_no_result, + expect_pass, +] + +non_matches = [] + +for e in expect: + if not re.search(e, xml_out): + non_matches.append(e) + +if non_matches: + for n in non_matches: + print "DID NOT MATCH " + '='*60 + print n + print "ACTUAL XML OUTPUT " + '='*60 + print xml_out + test.fail_test() + +test.pass_test() diff --git a/test/same-name.py b/test/same-name.py index 99a0ea5..8f71ac7 100644 --- a/test/same-name.py +++ b/test/same-name.py @@ -41,6 +41,8 @@ env.Program(source = ['foo.c', 'bu/bu.c']) """) test.write('foo.c', r""" +#include <stdio.h> +#include <stdlib.h> #include <bu/bu.h> int main(int argc, char *argv[]) @@ -57,6 +59,7 @@ void bu(void); """) test.write(['bu', 'bu.c'], r""" +#include <stdio.h> void bu(void) { diff --git a/test/sconsign/script.py b/test/sconsign/script.py index 9e0caa5..d94a956 100644 --- a/test/sconsign/script.py +++ b/test/sconsign/script.py @@ -91,6 +91,8 @@ env2.Program('sub2/hello.c') """) test.write(['work1', 'sub1', 'hello.c'], r"""\ +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -101,6 +103,8 @@ main(int argc, char *argv[]) """) test.write(['work1', 'sub2', 'hello.c'], r"""\ +#include <stdio.h> +#include <stdlib.h> #include <inc1.h> #include <inc2.h> int @@ -283,6 +287,8 @@ env2.Program('sub2/hello.c') """) test.write(['work2', 'sub1', 'hello.c'], r"""\ +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { @@ -293,6 +299,8 @@ main(int argc, char *argv[]) """) test.write(['work2', 'sub2', 'hello.c'], r"""\ +#include <stdio.h> +#include <stdlib.h> #include <inc1.h> #include <inc2.h> int diff --git a/test/signature-order.py b/test/signature-order.py index 8fb15bf..6ec839d 100644 --- a/test/signature-order.py +++ b/test/signature-order.py @@ -65,6 +65,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['work1', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include <aaa.h> #include <bbb.h> int @@ -98,6 +100,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['work2', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> #include "aaa.h" #include "bbb.h" int diff --git a/test/silent-command.py b/test/silent-command.py index a5da7a8..91880bd 100644 --- a/test/silent-command.py +++ b/test/silent-command.py @@ -36,7 +36,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,13 +52,13 @@ fp.close() test.write('SConstruct', """\ env = Environment() -env.Command('f1.out', 'f1.in', "%(python)s build.py $TARGET $SOURCE") -env.Command('f2.out', 'f2.in', "@%(python)s build.py $TARGET $SOURCE") -env.Command('f3.out', 'f3.in', "@ %(python)s build.py $TARGET $SOURCE") -env.Command('f4.out', 'f4.in', "@-%(python)s build.py $TARGET $SOURCE") -env.Command('f5.out', 'f5.in', "@- %(python)s build.py $TARGET $SOURCE") -env.Command('f6.out', 'f6.in', "-@%(python)s build.py $TARGET $SOURCE") -env.Command('f7.out', 'f7.in', "-@ %(python)s build.py $TARGET $SOURCE") +env.Command('f1.out', 'f1.in', '%(_python_)s build.py $TARGET $SOURCE') +env.Command('f2.out', 'f2.in', '@%(_python_)s build.py $TARGET $SOURCE') +env.Command('f3.out', 'f3.in', '@ %(_python_)s build.py $TARGET $SOURCE') +env.Command('f4.out', 'f4.in', '@-%(_python_)s build.py $TARGET $SOURCE') +env.Command('f5.out', 'f5.in', '@- %(_python_)s build.py $TARGET $SOURCE') +env.Command('f6.out', 'f6.in', '-@%(_python_)s build.py $TARGET $SOURCE') +env.Command('f7.out', 'f7.in', '-@ %(_python_)s build.py $TARGET $SOURCE') """ % locals()) test.write('f1.in', "f1.in\n") @@ -70,7 +70,7 @@ test.write('f6.in', "f6.in\n") test.write('f7.in', "f7.in\n") expect = test.wrap_stdout("""\ -%(python)s build.py f1.out f1.in +%(_python_)s build.py f1.out f1.in """ % locals()) test.run(arguments = '.', stdout = expect) diff --git a/test/special-filenames.py b/test/special-filenames.py index 98096b7..11930e5 100644 --- a/test/special-filenames.py +++ b/test/special-filenames.py @@ -30,6 +30,8 @@ import sys import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() attempt_file_names = [ @@ -68,11 +70,13 @@ for fn in attempt_file_names: def buildFileStr(fn): return "env.Build(source=r\"\"\"%s.in\"\"\", target=r\"\"\"%s.out\"\"\")" % ( fn, fn ) +xxx = string.join(map(buildFileStr, file_names), '\n') + test.write("SConstruct", """ -env=Environment(BUILDERS = {'Build' : Builder(action = '%s cat.py $TARGET $SOURCE')}) +env=Environment(BUILDERS = {'Build' : Builder(action = '%(_python_)s cat.py $TARGET $SOURCE')}) -%s -""" % (TestSCons.python, string.join(map(buildFileStr, file_names), '\n'))) +%(xxx)s +""" % locals()) test.run(arguments='.') diff --git a/test/srcchange.py b/test/srcchange.py index ef92aea..ac549f6 100644 --- a/test/srcchange.py +++ b/test/srcchange.py @@ -33,6 +33,8 @@ import os.path import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.write('getrevision', """ @@ -59,16 +61,18 @@ SubRevision = Action(subrevision) env=Environment() content_env=env.Copy() content_env.TargetSignatures('content') -content_env.Command('revision.in', [], '%(python)s getrevision > $TARGET') +content_env.Command('revision.in', [], '%(_python_)s getrevision > $TARGET') content_env.AlwaysBuild('revision.in') env.Precious('main.c') env.Command('main.c', 'revision.in', SubRevision) exe = env.Program('main.c') env.Default(exe) -""" % {'python':TestSCons.python}) +""" % locals()) test.write('main.c', """\ #include <stdio.h> +#include <stdlib.h> +#include <stdio.h> int main(int argc, char *argv[]) { @@ -82,8 +86,8 @@ test.write('revnum.in', '3.2\n') prog = 'main' + TestSCons._exe light_build=test.wrap_stdout("""\ -%(python)s getrevision > revision.in -""" % {'python':TestSCons.python}) +%(_python_)s getrevision > revision.in +""" % locals()) test.run(arguments='.') test.must_exist(prog) diff --git a/test/strfunction.py b/test/strfunction.py index a0b2344..62240ee 100644 --- a/test/strfunction.py +++ b/test/strfunction.py @@ -30,7 +30,7 @@ Test how using strfunction() to report different types of import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,12 +53,12 @@ def func(target, source, env): func1action = Action(func, strfunction) func2action = Action(func, strfunction=strfunction) -cmd = r"%(python)s cat.py $SOURCE $TARGET" +cmd = r'%(_python_)s cat.py $SOURCE $TARGET' cmd1action = Action(cmd, strfunction) cmd2action = Action(cmd, strfunction=strfunction) -list = [ r"%(python)s cat.py $SOURCE .temp", - r"%(python)s cat.py .temp $TARGET" ] +list = [ r'%(_python_)s cat.py $SOURCE .temp', + r'%(_python_)s cat.py .temp $TARGET' ] listaction = Action(list, strfunction=strfunction) lazy = '$LAZY' @@ -94,7 +94,7 @@ env = Environment(BUILDERS = { 'Dict' : Builder(action=dict), }, - LAZY = r"%(python)s cat.py $SOURCE $TARGET") + LAZY = r'%(_python_)s cat.py $SOURCE $TARGET') env.Cmd('cmd.out', 'cmd.in') env.Cmd1Str('cmd1str.out', 'cmdstr.in') @@ -139,27 +139,27 @@ test.write('dict7.list', "dict7.list\n") test.write('dict8.liststr', "dict8.liststr\n") expect = test.wrap_stdout("""\ -%(python)s cat.py cmd.in cmd.out +%(_python_)s cat.py cmd.in cmd.out Building cmd1str.out from cmdstr.in Building cmd2str.out from cmdstr.in -%(python)s cat.py dict1.cmd dict1.out +%(_python_)s cat.py dict1.cmd dict1.out Building dict2.out from dict2.cmdstr func(["dict3.out"], ["dict3.func"]) Building dict4.out from dict4.funcstr -%(python)s cat.py dict5.lazy dict5.out +%(_python_)s cat.py dict5.lazy dict5.out Building dict6.out from dict6.lazystr -%(python)s cat.py dict7.list .temp -%(python)s cat.py .temp dict7.out +%(_python_)s cat.py dict7.list .temp +%(_python_)s cat.py .temp dict7.out Building dict8.out from dict8.liststr Building dict8.out from dict8.liststr func(["func.out"], ["func.in"]) Building func1str.out from funcstr.in Building func2str.out from funcstr.in -%(python)s cat.py lazy.in lazy.out +%(_python_)s cat.py lazy.in lazy.out Building lazy1str.out from lazystr.in Building lazy2str.out from lazystr.in -%(python)s cat.py list.in .temp -%(python)s cat.py .temp list.out +%(_python_)s cat.py list.in .temp +%(_python_)s cat.py .temp list.out Building liststr.out from liststr.in Building liststr.out from liststr.in target.out diff --git a/test/subclassing.py b/test/subclassing.py index a040dd4..18be1bc 100644 --- a/test/subclassing.py +++ b/test/subclassing.py @@ -49,6 +49,8 @@ env.Program('hello', 'hello.c') """) test.write('hello.c', """\ +#include <stdio.h> +#include <stdlib.h> int main(int argc, char *argv[]) { printf("hello.c\\n"); diff --git a/test/subdir.py b/test/subdir.py index 03cbed3..991eb23 100644 --- a/test/subdir.py +++ b/test/subdir.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,13 +42,13 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = "%s build.py $TARGETS $SOURCES") +B = Builder(action = '%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'subdir/f1.out', source = 'subdir/f1.in') env.B(target = 'subdir/f2.out', source = 'subdir/f2.in') env.B(target = 'subdir/f3.out', source = 'subdir/f3.in') env.B(target = 'subdir/f4.out', source = 'subdir/f4.in') -""" % python) +""" % locals()) test.write(['subdir', 'f1.in'], "f1.in\n") test.write(['subdir', 'f2.in'], "f2.in\n") diff --git a/test/subdivide.py b/test/subdivide.py index 18219bf..a816957 100644 --- a/test/subdivide.py +++ b/test/subdivide.py @@ -63,6 +63,8 @@ env.Default(p) """ % TestSCons._obj) test.write('foo.c', """\ +#include <stdio.h> +#include <stdlib.h> void foo(void) { printf("foo.c\\n"); @@ -70,6 +72,8 @@ foo(void) { """) test.write(['src', 'main.c'], """\ +#include <stdio.h> +#include <stdlib.h> extern void foo(void); extern void bar(void); int @@ -82,6 +86,8 @@ main(int argc, char *argv[]) { """) test.write(['src', 'sub', 'bar.c'], """\ +#include <stdio.h> +#include <stdlib.h> void bar(void) { printf("bar.c\\n"); diff --git a/test/symlink/BuildDir.py b/test/symlink/BuildDir.py new file mode 100644 index 0000000..eee0e4d --- /dev/null +++ b/test/symlink/BuildDir.py @@ -0,0 +1,64 @@ +#!/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__" + +""" +XXX Put a description of the test here. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +if not hasattr(os, 'symlink'): + print "No os.symlink() method, no symlinks to test." + test.no_result(1) + +test.subdir('obj', + ['obj', 'subdir'], + 'src', + 'srcdir') + +test.write('SConstruct', """ +env = Environment() +BuildDir('obj/subdir', 'src') +Program('hello', ['obj/subdir/main.c']) +""") + +test.write(['srcdir', 'main.c'], r""" +int +main(int ac, char *argv[]) +{ + printf("srcdir/main.c\n"); +} +""") + +os.symlink('../srcdir/main.c', 'src/main.c') + +test.run(arguments = '.') + +test.pass_test() diff --git a/test/symlink.py b/test/symlink/dangling-include.py index ef7a55c..b5ea1e0 100644 --- a/test/symlink.py +++ b/test/symlink/dangling-include.py @@ -25,11 +25,10 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ -Test how we handle symlinks in end-cases. +Test how we handle #includes of dangling symlinks. """ import os -import string import TestSCons @@ -55,18 +54,6 @@ expect = """\ scons: *** Source `foo.h' not found, needed by target `%s'. Stop. """% foo_obj -test.run(arguments = '.', - status = 2, - stderr = expect) - -test.write('SConstruct', """ -Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) -""") - -test.symlink('nonexistent', 'file.in') - -test.run(arguments = '.', - status = 2, - stderr = "scons: *** Source `file.in' not found, needed by target `file.out'. Stop.\n") +test.run(arguments = '.', status = 2, stderr = expect) test.pass_test() diff --git a/test/symlink/dangling-source.py b/test/symlink/dangling-source.py new file mode 100644 index 0000000..e242e61 --- /dev/null +++ b/test/symlink/dangling-source.py @@ -0,0 +1,53 @@ +#!/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 how we handle dangling symlinks as source files. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +if not hasattr(os, 'symlink'): + print "No os.symlink() method, no symlinks to test." + test.no_result(1) + +test.write('SConstruct', """ +Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) +""") + +test.symlink('nonexistent', 'file.in') + +expect = """\ +scons: *** Source `file.in' not found, needed by target `file.out'. Stop. +""" + +test.run(arguments = '.', status = 2, stderr = expect) + +test.pass_test() diff --git a/test/up-to-date.py b/test/up-to-date.py index 460401a..cec5952 100644 --- a/test/up-to-date.py +++ b/test/up-to-date.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,13 +42,13 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') env.B(target = 'f4.out', source = 'f4.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") @@ -57,13 +57,14 @@ test.write('f4.in', "f4.in\n") test.run(arguments = 'f1.out f3.out') -test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout = -test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: `f1.out' is up to date. -%s build.py f2.out f2.in +%(_python_)s build.py f2.out f2.in scons: `f3.out' is up to date. -%s build.py f4.out f4.in -""" % (python, python))) +%(_python_)s build.py f4.out f4.in +""" % locals()) + +test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout = expect) test.pass_test() |