Merged revisions 1582-1665 via svnmerge from
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 2 Nov 2006 16:21:36 +0000 (16:21 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 2 Nov 2006 16:21:36 +0000 (16:21 +0000)
http://scons.tigris.org/svn/scons/branches/core

........
  r1585 | stevenknight | 2006-08-06 21:21:12 -0500 (Sun, 06 Aug 2006) | 1 line

  0.96.D430 - Fix bug with finding Fortran modules in build directories. (Nicolas Vigier)
........
  r1586 | stevenknight | 2006-08-06 22:54:39 -0500 (Sun, 06 Aug 2006) | 1 line

  0.96.D431 - Fix use of BuildDir when the source file is a relative-path symlink. (Nicola Vi
........
  r1587 | timot | 2006-08-10 14:45:00 -0500 (Thu, 10 Aug 2006) | 1 line

  fix Platform SDK init
........
  r1589 | stevenknight | 2006-08-12 13:28:51 -0500 (Sat, 12 Aug 2006) | 1 line

  0.96.D432 - Change the default mingw linker from g++ to gcc. (Mariusz Olko)
........
  r1590 | stevenknight | 2006-08-13 11:16:32 -0500 (Sun, 13 Aug 2006) | 1 line

  0.96.D433 - More runtest.py enhancements.
........
  r1594 | stevenknight | 2006-08-15 04:47:46 -0500 (Tue, 15 Aug 2006) | 1 line

  0.96.D434 - Print the full path of SConscript files in stack traces. (Dobes Vandermeer)
........
  r1600 | timot | 2006-08-16 11:34:44 -0500 (Wed, 16 Aug 2006) | 1 line

  add M4 to mingw tools
........
  r1611 | stevenknight | 2006-08-19 16:25:24 -0500 (Sat, 19 Aug 2006) | 1 line

  0.96.D435 - Add an SCons XMLResultStream to capture test results for mailing in. Get Aegis
........
  r1617 | timot | 2006-08-21 16:19:03 -0500 (Mon, 21 Aug 2006) | 1 line

  handling of spawnve returning an error code that is not in exitvalmap
........
  r1619 | stevenknight | 2006-09-01 19:07:47 -0500 (Fri, 01 Sep 2006) | 1 line

  0.96.D436 - Win32 test portability and other test fixes.
........
  r1620 | stevenknight | 2006-09-02 20:21:51 -0500 (Sat, 02 Sep 2006) | 2 lines

  Bring msvc.py in sync with Aegis repository.
........
  r1621 | stevenknight | 2006-09-02 20:23:48 -0500 (Sat, 02 Sep 2006) | 2 lines

  Move to keep symlink tests together.
........
  r1622 | garyo | 2006-09-06 11:51:42 -0500 (Wed, 06 Sep 2006) | 1 line

  Fix for Issue #1370; allow exit values not in exitvalmap.  Added some tests for this kind of thing.  Also improved win32 err msg if command exits with nonzero to show actual cmd, not just "cmd.exe".  Note this fix improves posix and win32 behavior.
........
  r1623 | stevenknight | 2006-09-07 06:35:16 -0500 (Thu, 07 Sep 2006) | 1 line

  0.96.D440 - Fix runtest.py with QMTest on Windows.
........
  r1625 | stevenknight | 2006-09-09 09:22:15 -0500 (Sat, 09 Sep 2006) | 3 lines

  Comment out a long-command test which fails on older Pythons (1.5.2)
  on Fedora Core 3.  We can restore it in the future.
........
  r1626 | stevenknight | 2006-09-09 16:17:44 -0500 (Sat, 09 Sep 2006) | 1 line

  0.96.D441 - Allow Python Values to be the targets of Builders. (Anonymous)
........
  r1627 | stevenknight | 2006-09-09 20:25:53 -0500 (Sat, 09 Sep 2006) | 1 line

  0.96.D442 - Support src_dir on SConscript() calls. (Dobes Vandermeer)
........
  r1628 | stevenknight | 2006-09-10 07:28:54 -0500 (Sun, 10 Sep 2006) | 1 line

  0.96.D443 - Add miscellaneous utility scripts and config changes.
........
  r1629 | stevenknight | 2006-09-11 04:45:01 -0500 (Mon, 11 Sep 2006) | 1 line

  0.96.D444 - Add a test case for BuildDir handling of nested SConscript files. (Adam Simpkin
........
  r1630 | stevenknight | 2006-09-11 11:34:07 -0500 (Mon, 11 Sep 2006) | 1 line

  0.96.D445 - Workaround bug in early versions of thePython 2.4 profiler.
........
  r1631 | stevenknight | 2006-09-19 19:12:51 -0500 (Tue, 19 Sep 2006) | 1 line

  0.96.D446 - Fix Visual Studio common prefix handling to only treat common prefixes on comple
........
  r1632 | stevenknight | 2006-09-25 07:11:44 -0500 (Mon, 25 Sep 2006) | 1 line

  0.96.D447 - Fix tests that fail due to warnings from (some versions?) of gcc. (Sohail Soman
........
  r1633 | stevenknight | 2006-09-25 07:57:48 -0500 (Mon, 25 Sep 2006) | 1 line

  0.96.D448 - Handle python paths with quotes in tests.
........
  r1634 | stevenknight | 2006-09-25 14:38:07 -0500 (Mon, 25 Sep 2006) | 1 line

  0.96.D449 - Fix SCons build when python is not in the path (e.g. on Windows). (Chad Austin)
........
  r1635 | stevenknight | 2006-09-26 11:28:23 -0500 (Tue, 26 Sep 2006) | 1 line

  0.96.D450 - Handle warnings from Python 2.1; make sure we still test on Python 1.5.
........
  r1636 | stevenknight | 2006-09-27 05:34:23 -0500 (Wed, 27 Sep 2006) | 1 line

  0.96.D451 - Avoid calling Options validators and converters twice.
........
  r1637 | stevenknight | 2006-09-28 08:12:38 -0500 (Thu, 28 Sep 2006) | 1 line

  0.96.D452 - Allow setting MSVS_VERSION after initialization to select the Visual Studio vers
........
  r1638 | stevenknight | 2006-09-30 08:38:15 -0500 (Sat, 30 Sep 2006) | 1 line

  0.96.D453 - Give the MSVC resource builder a src_builder list and .rc src_suffix. (Leanid N
........
  r1639 | stevenknight | 2006-10-12 08:50:58 -0500 (Thu, 12 Oct 2006) | 1 line

  0.96.D454 - Test handling of env.Append() and env.Prepend(), making sure it works on later P
........
  r1640 | stevenknight | 2006-10-15 20:42:09 -0500 (Sun, 15 Oct 2006) | 1 line

  0.96.D455 - Support the runtest.py -f option when using QMTest.
........
  r1641 | stevenknight | 2006-10-15 21:20:02 -0500 (Sun, 15 Oct 2006) | 1 line

  0.96.D456 - Fix an error in ListOption handling caused by making new copies of Options objec
........
  r1642 | stevenknight | 2006-10-16 05:53:14 -0500 (Mon, 16 Oct 2006) | 1 line

  0.96.D457 - Fix new Append()/Prepend() handling of dictionaries in later Python versions (2.
........
  r1643 | stevenknight | 2006-10-16 07:13:16 -0500 (Mon, 16 Oct 2006) | 1 line

  0.96.D458 - Allow Install() to handle directories as sources. (Matthew A. Nicholson)
........
  r1644 | stevenknight | 2006-10-17 09:17:58 -0500 (Tue, 17 Oct 2006) | 1 line

  0.96.D459 - Add a test to make sure SideEffect() doesn't interfere with CacheDir(). Refacto
........
  r1645 | stevenknight | 2006-10-17 10:20:22 -0500 (Tue, 17 Oct 2006) | 1 line

  0.96.D460 - Do not use -fPIC when using gcc on win32 (MinGW). (Jan Nijtmans)
........
  r1646 | stevenknight | 2006-10-17 17:21:58 -0500 (Tue, 17 Oct 2006) | 6 lines

  Move all the scons.org stuff from the scons source tree itself to a
  directory next to the trunk, and delete the copies from the branches.
  There's a lot of stuff there (what with all of the documentation of
  the different versions) and it's ridiculous to make everyone sync it
  just to work on the code.
........
  r1647 | stevenknight | 2006-10-17 23:18:29 -0500 (Tue, 17 Oct 2006) | 1 line

  0.96.D461 - Fix the tests of runtest.py so they skip appropriately if qmtest.py isn't instal
........
  r1648 | stevenknight | 2006-10-18 08:48:47 -0500 (Wed, 18 Oct 2006) | 1 line

  0.96.D462 - When using --implicit-cache, do not re-scan files if the scanner returned no imp
........
  r1649 | stevenknight | 2006-10-18 19:42:13 -0500 (Wed, 18 Oct 2006) | 1 line

  0.96.D463 - More test portability fixes.
........
  r1650 | stevenknight | 2006-10-19 00:30:23 -0500 (Thu, 19 Oct 2006) | 1 line

  0.96.D464 - Add a cpp.py module that knows how to find dependencies from #include lines like
........
  r1651 | stevenknight | 2006-10-20 06:49:51 -0500 (Fri, 20 Oct 2006) | 1 line

  0.96.D465 - Fix unresolved variable name in win32 portion of test.
........
  r1652 | stevenknight | 2006-10-23 00:20:38 -0500 (Mon, 23 Oct 2006) | 1 line

  0.96.D466 - Add an option for tracing files to and from the CacheDir.
........
  r1653 | stevenknight | 2006-10-23 00:29:32 -0500 (Mon, 23 Oct 2006) | 1 line

  0.96.D467 - Make {Append,Prepend}Unique() handle adding elements to empty lists like {Append
........
  r1654 | stevenknight | 2006-10-23 02:38:06 -0500 (Mon, 23 Oct 2006) | 1 line

  0.96.D468 - Allow Debug.caller() to take multiple arguments; add a debug utility to post-pro
........
  r1655 | stevenknight | 2006-10-23 03:16:42 -0500 (Mon, 23 Oct 2006) | 1 line

  0.96.D469 - Reduce unnecessary calls to Node.FS.disambiguate(), undoing (?) a performance hi
........
  r1656 | stevenknight | 2006-10-25 00:06:27 -0500 (Wed, 25 Oct 2006) | 1 line

  0.96.D470 - More test portability fixes.
........
  r1657 | stevenknight | 2006-10-25 00:16:22 -0500 (Wed, 25 Oct 2006) | 1 line

  0.96.D471 - Have runtest.py fall back to the --noqmtest option (with a warning) if qmtest.py
........
  r1658 | stevenknight | 2006-10-25 12:12:02 -0500 (Wed, 25 Oct 2006) | 1 line

  0.96.D472 - Document the default use of the /Z7 flag for Visual Studio and ways to use /Zi.
........
  r1659 | stevenknight | 2006-10-26 23:53:51 -0500 (Thu, 26 Oct 2006) | 1 line

  0.96.D473 - Have runtest.py -d accomodate different Python library locations.
........
  r1660 | stevenknight | 2006-10-27 00:03:59 -0500 (Fri, 27 Oct 2006) | 1 line

  0.96.D474 - Patch to support running SCons under WingIDE. (Allen Bierbaum)
........
  r1661 | stevenknight | 2006-10-27 12:17:27 -0500 (Fri, 27 Oct 2006) | 1 line

  0.96.D475 - Restore execution of all Environment unit tests.
........
  r1662 | stevenknight | 2006-10-31 23:22:58 -0600 (Tue, 31 Oct 2006) | 1 line

  0.96.D476 - Eliminate unnecessary print from a test, left over from debugging.
........
  r1663 | stevenknight | 2006-10-31 23:32:00 -0600 (Tue, 31 Oct 2006) | 1 line

  0.96.D477 - Support creating shared object files from assembly language. (James Y. Knight)
........
  r1664 | stevenknight | 2006-10-31 23:44:08 -0600 (Tue, 31 Oct 2006) | 1 line

  0.96.D478 - Fix the Memoizer to deal with a compiled .pyo or .pyc file that's in a different
........
  r1665 | stevenknight | 2006-11-01 21:59:18 -0600 (Wed, 01 Nov 2006) | 1 line

  0.96.D479 - Put back the scons-{LICENSE,README} files in the scons-loacal package; add tests
........

git-svn-id: http://scons.tigris.org/svn/scons/trunk@1667 fdb21ef1-2011-0410-befe-b5e4ea1792b1

394 files changed:
HOWTO/release.txt
HOWTO/subrelease.txt
QMTest/TestRuntest.py
QMTest/TestSCons.py
QMTest/classes.qmc
QMTest/scons_tdb.py
SConstruct
bin/ae-cvs-ci [new file with mode: 0755]
bin/ae-svn-ci [new file with mode: 0755]
bin/caller-tree.py [new file with mode: 0644]
bin/scons-cdist
bin/scons-diff.py [new file with mode: 0644]
config
doc/SConscript
doc/man/scons.1
runtest.py
src/CHANGES.txt
src/engine/MANIFEST.in
src/engine/SCons/ActionTests.py
src/engine/SCons/Debug.py
src/engine/SCons/Defaults.py
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Memoize.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Node/Python.py
src/engine/SCons/Node/PythonTests.py
src/engine/SCons/Node/__init__.py
src/engine/SCons/Options/ListOption.py
src/engine/SCons/Options/ListOptionTests.py
src/engine/SCons/Options/OptionsTests.py
src/engine/SCons/Options/__init__.py
src/engine/SCons/Platform/posix.py
src/engine/SCons/Platform/win32.py
src/engine/SCons/Scanner/CTests.py
src/engine/SCons/Script/Main.py
src/engine/SCons/Script/SConscript.py
src/engine/SCons/Tool/as.py
src/engine/SCons/Tool/fortran.py
src/engine/SCons/Tool/gcc.py
src/engine/SCons/Tool/mingw.py
src/engine/SCons/Tool/mslink.xml
src/engine/SCons/Tool/msvc.py
src/engine/SCons/Tool/msvc.xml
src/engine/SCons/Tool/msvs.py
src/engine/SCons/Tool/msvsTests.py
src/engine/SCons/cpp.py [new file with mode: 0644]
src/engine/SCons/cppTests.py [new file with mode: 0644]
src/test_copyrights.py
src/test_files.py [new file with mode: 0644]
src/test_setup.py
test/AR/AR.py
test/AR/ARCOM.py
test/AR/ARCOMSTR.py
test/AR/ARFLAGS.py
test/AS/AS.py
test/AS/ASCOM.py
test/AS/ASCOMSTR.py
test/AS/ASFLAGS.py
test/AS/ASPP.py
test/AS/ASPPCOM.py
test/AS/ASPPCOMSTR.py
test/AS/ASPPFLAGS.py
test/Actions/actions.py
test/Actions/pre-post.py
test/Alias/Alias.py
test/BadBuilder.py
test/BitKeeper/BITKEEPERCOM.py
test/BitKeeper/BITKEEPERCOMSTR.py
test/BuildDir/BuildDir.py
test/BuildDir/Sconscript-build_dir.py
test/BuildDir/errors.py
test/BuildDir/nested-sconscripts.py [new file with mode: 0644]
test/BuildDir/reflect.py
test/CC/CC.py
test/CC/CCCOM.py
test/CC/CCCOMSTR.py
test/CC/CCFLAGS.py
test/CC/SHCC.py
test/CC/SHCCCOM.py
test/CC/SHCCCOMSTR.py
test/CC/SHCCFLAGS.py
test/CFILESUFFIX.py
test/CPPDEFINES.py
test/CPPFLAGS.py
test/CPPSUFFIXES.py
test/CVS.py
test/CVSCOM.py
test/CVSCOMSTR.py
test/CXX/CXX.py
test/CXX/CXXCOM.py
test/CXX/CXXCOMSTR.py
test/CXX/CXXFILESUFFIX.py
test/CXX/SHCXX.py
test/CXX/SHCXXCOM.py
test/CXX/SHCXXCOMSTR.py
test/CXX/SHCXXFLAGS.py
test/CacheDir.py [deleted file]
test/CacheDir/BuildDir.py [new file with mode: 0644]
test/CacheDir/CacheDir.py [new file with mode: 0644]
test/CacheDir/SideEffect.py [new file with mode: 0644]
test/CacheDir/debug.py [new file with mode: 0644]
test/CacheDir/multi-targets.py [new file with mode: 0644]
test/CacheDir/source-scanner.py [new file with mode: 0644]
test/Case.py
test/Command.py
test/CommandGenerator.py
test/Configure/CONFIGUREDIR.py
test/Configure/CONFIGURELOG.py
test/Configure/Configure.py
test/DSUFFIXES.py
test/DVIPDF/DVIPDF.py
test/DVIPDF/DVIPDFCOM.py
test/DVIPDF/DVIPDFCOMSTR.py
test/DVIPDF/DVIPDFFLAGS.py
test/DVIPS/DVIPS.py
test/DVIPS/DVIPSFLAGS.py
test/DVIPS/PSCOM.py
test/DVIPS/PSCOMSTR.py
test/Default.py
test/Depends.py
test/ENV.py
test/ESCAPE.py
test/Environment.py
test/Execute.py
test/Fortran/F77.py
test/Fortran/F77COM.py
test/Fortran/F77COMSTR.py
test/Fortran/F77FLAGS.py
test/Fortran/F90.py
test/Fortran/F90COM.py
test/Fortran/F90COMSTR.py
test/Fortran/F90FLAGS.py
test/Fortran/F95.py
test/Fortran/F95COM.py
test/Fortran/F95COMSTR.py
test/Fortran/F95FLAGS.py
test/Fortran/FORTRAN.py
test/Fortran/FORTRANCOM.py
test/Fortran/FORTRANCOMSTR.py
test/Fortran/FORTRANFLAGS.py
test/Fortran/FORTRANMODDIR.py
test/Fortran/FORTRANSUFFIXES.py
test/Fortran/SHF77.py
test/Fortran/SHF77COM.py
test/Fortran/SHF77COMSTR.py
test/Fortran/SHF77FLAGS.py
test/Fortran/SHF90.py
test/Fortran/SHF90COM.py
test/Fortran/SHF90COMSTR.py
test/Fortran/SHF90FLAGS.py
test/Fortran/SHF95.py
test/Fortran/SHF95COM.py
test/Fortran/SHF95COMSTR.py
test/Fortran/SHF95FLAGS.py
test/Fortran/SHFORTRAN.py
test/Fortran/SHFORTRANCOM.py
test/Fortran/SHFORTRANCOMSTR.py
test/Fortran/SHFORTRANFLAGS.py
test/Fortran/USE-MODULE.py
test/Fortran/module-subdir.py [new file with mode: 0644]
test/Ghostscript/GS.py
test/Ghostscript/GSCOM.py
test/Ghostscript/GSCOMSTR.py
test/Ghostscript/GSFLAGS.py
test/IDL/MIDLCOM.py
test/IDL/MIDLCOMSTR.py
test/Ignore.py
test/Install/Install.py
test/Install/InstallAs.py
test/Install/directories.py [new file with mode: 0644]
test/Java/JAR.py
test/Java/JARCOM.py
test/Java/JARCOMSTR.py
test/Java/JAVAC.py
test/Java/JAVACCOM.py
test/Java/JAVACCOMSTR.py
test/Java/JAVAH.py
test/Java/JAVAHCOM.py
test/Java/JAVAHCOMSTR.py
test/Java/RMIC.py
test/Java/RMICCOM.py
test/Java/RMICCOMSTR.py
test/LEX/LEX.py
test/LEX/LEXCOM.py
test/LEX/LEXCOMSTR.py
test/LEX/LEXFLAGS.py
test/LIBPATH.py
test/LIBPREFIXES.py
test/LIBS.py
test/LIBSUFFIXES.py
test/LINK/LINK.py
test/LINK/LINKCOM.py
test/LINK/LINKCOMSTR.py
test/LINK/LINKFLAGS.py
test/LINK/SHLINK.py
test/LINK/SHLINKCOM.py
test/LINK/SHLINKCOMSTR.py
test/LINK/SHLINKFLAGS.py
test/Library.py
test/M4/M4.py
test/M4/M4COM.py
test/M4/M4COMSTR.py
test/MSVC/PCHCOM.py
test/MSVC/PCHCOMSTR.py
test/MSVC/RCCOM.py
test/MSVC/RCCOMSTR.py
test/MSVC/generate-rc.py [new file with mode: 0644]
test/MSVC/msvc.py
test/MSVS/common-prefix.py
test/MSVS/runfile.py
test/MSVS/vs-6.0-files.py
test/MSVS/vs-7.0-files.py
test/MSVS/vs-7.1-files.py
test/MSVS/vs-8.0-files.py
test/MinGW/RCCOM.py
test/MinGW/RCCOMSTR.py
test/NodeOps.py
test/Object.py
test/Options/BoolOption.py
test/Options/EnumOption.py
test/Options/ListOption.py
test/Options/PackageOption.py
test/Options/PathOption.py
test/ParseConfig.py
test/ParseDepends.py
test/Perforce/P4COM.py
test/Perforce/P4COMSTR.py
test/Perforce/Perforce.py
test/Precious.py
test/Program-j.py
test/Program.py
test/QT/QTFLAGS.py
test/QT/moc-from-header.py
test/QT/warnings.py
test/RANLIB/RANLIB.py
test/RANLIB/RANLIBCOM.py
test/RANLIB/RANLIBCOMSTR.py
test/RANLIB/RANLIBFLAGS.py
test/RCS/RCS_COCOM.py
test/RCS/RCS_COCOMSTR.py
test/RCS/diskcheck.py
test/RCS/implicit.py
test/RPATH.py
test/Repository/CPPPATH.py
test/Repository/LIBPATH.py
test/Repository/M4.py
test/Repository/Program.py
test/Repository/StaticLibrary.py
test/Repository/absolute-path.py
test/Repository/include.py
test/Repository/link-object.py
test/Repository/multi-dir.py
test/Repository/no-SConsignFile.py
test/Repository/no-repository.py
test/Repository/signature-order.py
test/Repository/top-level-path.py
test/Repository/variants.py
test/Repository/within-repository.py
test/Rpcgen/RPCGEN.py
test/Rpcgen/RPCGENCLIENTFLAGS.py
test/Rpcgen/RPCGENFLAGS.py
test/Rpcgen/RPCGENHEADERFLAGS.py
test/Rpcgen/RPCGENSERVICEFLAGS.py
test/Rpcgen/RPCGENXDRFLAGS.py
test/SCCS/SCCSCOM.py
test/SCCS/SCCSCOMSTR.py
test/SCCS/diskcheck.py
test/SConscript/SConscript.py [moved from test/SConscript.py with 59% similarity]
test/SConscript/SConscriptChdir.py [new file with mode: 0644]
test/SConscript/env.py [new file with mode: 0644]
test/SConscript/src_dir.py [new file with mode: 0644]
test/SConscript/variables.py [new file with mode: 0644]
test/SConscript/white-space.py [new file with mode: 0644]
test/SConsignFile.py
test/SHELL.py
test/SHLIBPREFIX.py
test/SHLIBSUFFIX.py
test/SPAWN.py
test/SWIG/SWIG.py
test/SWIG/SWIGCOM.py
test/SWIG/SWIGCOMSTR.py
test/Scanner/Scanner.py [moved from test/Scanner.py with 65% similarity]
test/Scanner/empty-implicit.py [new file with mode: 0644]
test/Scanner/exception.py [moved from test/Scanner-exception.py with 100% similarity]
test/Scanner/generated.py [moved from test/scan-once.py with 72% similarity]
test/Scanner/multi-env.py [new file with mode: 0644]
test/Scanner/parallel-rescan.py [moved from test/parallel-rescan.py with 100% similarity]
test/Scanner/scan-once.py [new file with mode: 0644]
test/SharedLibrary.py
test/TAR/TAR.py
test/TAR/TARCOM.py
test/TAR/TARCOMSTR.py
test/TAR/TARFLAGS.py
test/TARGET-dir.py
test/TEX/LATEX.py
test/TEX/LATEXCOM.py
test/TEX/LATEXCOMSTR.py
test/TEX/LATEXFLAGS.py
test/TEX/PDFLATEX.py
test/TEX/PDFLATEXCOM.py
test/TEX/PDFLATEXCOMSTR.py
test/TEX/PDFLATEXFLAGS.py
test/TEX/PDFTEX.py
test/TEX/PDFTEXCOM.py
test/TEX/PDFTEXCOMSTR.py
test/TEX/PDFTEXFLAGS.py
test/TEX/TEX.py
test/TEX/TEXCOM.py
test/TEX/TEXCOMSTR.py
test/TEX/TEXFLAGS.py
test/Value.py
test/YACC/YACC.py
test/YACC/YACCCOM.py
test/YACC/YACCCOMSTR.py
test/YACC/YACCFLAGS.py
test/YACC/YACCHFILESUFFIX.py
test/YACC/YACCHXXFILESUFFIX.py
test/ZIP/ZIP.py
test/ZIP/ZIPCOM.py
test/ZIP/ZIPCOMSTR.py
test/bad-variables.py
test/builderrors.py
test/chdir.py
test/dependency-cycle.py
test/errors.py
test/exceptions.py
test/expansion.py
test/explain.py
test/gnutools.py
test/ignore-command.py
test/implicit-cache/GetOption.py [new file with mode: 0644]
test/implicit-cache/SetOption.py [new file with mode: 0644]
test/implicit-cache/basic.py [moved from test/option--implicit-cache.py with 71% similarity]
test/import.py
test/long-lines.py
test/multi.py
test/multiline.py
test/option--.py
test/option--D.py
test/option--Q.py
test/option--U.py
test/option--Y.py
test/option--cs.py
test/option--debug.py
test/option--max-drift.py
test/option-c.py
test/option-i.py
test/option-j.py
test/option-k.py
test/option-n.py
test/option-q.py
test/option-s.py
test/option/debug-dtree.py
test/option/debug-findlibs.py
test/option/debug-includes.py
test/option/debug-stacktrace.py
test/option/debug-stree.py
test/option/debug-time.py
test/option/debug-tree.py
test/option/profile.py
test/overrides.py
test/redirection.py
test/runtest/aegis/batch-output.py [new file with mode: 0644]
test/runtest/baseline/combined.py
test/runtest/baseline/fail.py
test/runtest/baseline/no_result.py
test/runtest/baseline/pass.py
test/runtest/fallback.py [new file with mode: 0644]
test/runtest/noqmtest.py [new file with mode: 0644]
test/runtest/print_time.py
test/runtest/python.py
test/runtest/simple/combined.py
test/runtest/simple/fail.py
test/runtest/simple/no_result.py
test/runtest/simple/pass.py
test/runtest/src.py
test/runtest/testlistfile.py [new file with mode: 0644]
test/runtest/xml/output.py [new file with mode: 0644]
test/same-name.py
test/sconsign/script.py
test/signature-order.py
test/silent-command.py
test/special-filenames.py
test/srcchange.py
test/strfunction.py
test/subclassing.py
test/subdir.py
test/subdivide.py
test/symlink/BuildDir.py [new file with mode: 0644]
test/symlink/dangling-include.py [moved from test/symlink.py with 79% similarity]
test/symlink/dangling-source.py [new file with mode: 0644]
test/up-to-date.py

index 397033a1e18c0b22a3b097f2966721e6a523db12..88f93521a42277a3cd474007cc36e5bd0b9db252 100644 (file)
@@ -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
index fb799e692c88af5285c76eaaec1f47a6f53b6742..6826c81792da4ed59e4f1d95f88c0184b3ecc260 100644 (file)
@@ -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
index a4bcd05d9ae889b7e0b957bcc1df6c06bd490727..94527469e97dc83765ee00a8e0e7e2f3ec46a52d 100644 (file)
@@ -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)
 
index 0904d315253b647b5fe5142d606b3f93ab71fc1d..de15526431726f3eba0a3afef08de6cde65ef793 100644 (file)
@@ -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([]):
index 73e3df3a53ed200cc40bbb57e1d0754a293d3bd7..88de0615dc79bffa743595bc479fe7dbbf3dd245 100644 (file)
@@ -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>
index 145c2a7a6e2ad42ad2c45df4c8b1048a7b26ec46..e0d76830f90f514cf4cfb9611583504e9ef8530d 100644 (file)
@@ -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.")
index 49cc6ff3174028234616b120022b6b7e557aeb25..0fdacd527ca54bea245d8d7754f721962f8d7fd3 100644 (file)
@@ -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 (executable)
index 0000000..3dcc287
--- /dev/null
@@ -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 (executable)
index 0000000..e5b81a4
--- /dev/null
@@ -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 (file)
index 0000000..5d907b8
--- /dev/null
@@ -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, '')
index 425e430b1711759d02dd6d45607cec4dd10c4405..58b1bae0a4241e8b48e93d6ec2dceac6ec170966 100644 (file)
 # 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 (file)
index 0000000..6cfe25a
--- /dev/null
@@ -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)
diff --git a/config b/config
index e540484f8e75aa6802045e66b48b68af7f9b9f4d..b055bdb279db7b37b1e50800a32947900c0de254 100644 (file)
--- a/config
+++ b/config
@@ -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";
+ *
+ */
index 6162f9399b93721eb4847d6eaef21c128e602712..6f92fbc841ed871859d7c60ab6a830de669d865c 100644 (file)
@@ -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)
index 49f9a305509b9da264c83b7b8e0d820a68c853ea..a12bd68d6782ce50d8d819633cdfd7202ec3d3d7 100644 (file)
@@ -420,6 +420,24 @@ Will not remove any targets specified by the
 .BR NoClean ()
 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
@@ -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
 
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
index 7f5cbc3c95c1da1577d3fdccb4e5ef4fdfa27e36..5440c1072b54f2c0a78b644ddc1c26313d317e54 100644 (file)
@@ -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:
index ccbc3af56007440bdf0215fb9500eeca650c3acc..88e70dc88339e2a775b02cdbf258a6e0f4cfb163 100644 (file)
 
 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.
index 9d6c9721c54a887c86723a426e6969600a01efc7..c762f1cd58973d61123ddf7b506e53a50af1dedd 100644 (file)
@@ -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
index 1085586e5ebc0056ac6f754c0da4315c86c7e242..57910de412335740f98f06094db6ba0de89b1747 100644 (file)
@@ -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
index 1cff9c6c51b41a1b4c2fec4fc9cd4e9182ad9444..47d2134975a83957fd01fd6de32565a51f12834e 100644 (file)
@@ -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()
index cb628b827028c82a8a163d93c90cd7cb6d93c9c6..7513c0ddd47131a95eca134dd6e6762014f838f5 100644 (file)
@@ -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,
index d76f71d5645ea97d2add97c66752276bcde87c7b..7aa190913c34ee42d47faa81f6dd065954551dc1 100644 (file)
@@ -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
index c56f1f52d31d910e4a4cd0ea3697ba1f4dda14d4..52aac235700241f416d4ad742899959cfb524904 100644 (file)
@@ -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):
index 134206f3f681ff78cabcd02640e2e711c76d13d5..c2a302725b6549f32f15d60af2607dcedb6e4122 100644 (file)
@@ -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,
index ce5bcc0cfa8d1243770b6d2ad8d3cbd3f574c686..382bca3a9baba76e2e46465cd70e548b96c32bca 100644 (file)
@@ -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__"""
index 98e08a9f2851c4bc53c06faec8441f4fb48d97da..1b38ffee84358642b936f8132cf1cc0417c217a6 100644 (file)
@@ -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:
index 99dc5b03af1e998100b0395eba6b0e28f1219281..a639aee3a36545241b2d3bcd3683fbd7164eb032 100644 (file)
@@ -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()
index 0801fb3ed91d76587e4f6569a4642ac94dbc6add..62bcf8b6f9e5d789f74cf039f817f4cb26b672e3 100644 (file)
@@ -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
         """
index bda3a482ff0d69eb26ae242dfa470e55fd126e04..42be5b129b3f7f049ba6f53ee13739ac3b175e77 100644 (file)
@@ -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:
index d14b22ac9c3dcdba37fc0acc54f88ff9e111e1b3..5aa508ada6d0057828e9e2e69a5dc8b1ec0a87dd 100644 (file)
@@ -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):
     """
     """
index a892e18b5672bc37253490af26ccc4b0075d81bb..22378bcfbc81239ae014ec3b5ed2fa5993dc9755 100644 (file)
@@ -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():
index aeffe2df5f1ea068b1062156aabdf3b6f04f3296..1d9b851eb2274f089a2804cc4fefe4c4d14e9e6f 100644 (file)
@@ -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()
index 73339859bbda6ffb4ee3baceef9478f6a32ce7b0..83798b3d600c660a2d4d59db7267c24ef4d34007 100644 (file)
@@ -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.
index 675167e4f730daf6130beb24f57c110c0eb5378d..1d4e9f70d82d1e26b10325ff4498f480f3267739 100644 (file)
@@ -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:
index 6188098735f688921531bc85f9acfd4be30b3f73..148d9df8f92809e8eb5f0655384f955474567523 100644 (file)
@@ -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():
index c57e7f707cfad051ba618f7745ad7b01b4f4e8de..2ca522b82fd71e37c18153d8d88e0002c13412ef 100644 (file)
@@ -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",
index 73f96e2e0cc274806dd8ca86d26235281090199a..2c1811280c428e76bff3bf26b091e7412e210a35 100644 (file)
@@ -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:
index f932d309dd1a1ea6c64b086cc67b632b0c108df4..dc896a00eb0e50fe0a54a532e812ecff8e070028 100644 (file)
@@ -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
index 5a267a5209c19e3d650aab439dd37906d0184fc7..1b1b4b3abe035fc190d46bf2cb584586cad7f176 100644 (file)
@@ -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('')
index b694a58c2e97bd23518cd2ca4840ae8ee5d376dd..b83e7d3b34f94bf2dd9e842128f30f898755d0e3 100644 (file)
@@ -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)
 
index 1be665a9cce4992ec2605d296f5ccd9160e1074a..ad02e0deb52b49973bf9a12a2ace825228abc92f 100644 (file)
@@ -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')
index 5765e25863729e4edf4cff50acae6cb86cf68755..d679b53efbfea06d9450833258dc472bdeedb882 100644 (file)
@@ -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']        = ''
index 58cfb1d79eed5f7883e2a8f21453ea61a854890b..6499cfee0e182c6d0def464471068e1fa60e8699 100644 (file)
@@ -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>
 
index 86cde784db916964f1f36de5c75259585b1287e8..80b59263265d3e005e5d037ca25886ac6c73a9c0 100644 (file)
@@ -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)
 
index 252d9628812856b3c6d70556a732e3dd07713e31..1c0f3fa236fdc937c4db00878d8b4f1a875e5219 100644 (file)
@@ -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
index e8aaf8341f0f1d39d8f9f4b8b2889ab5912d29db..e35c92abff0e26fee2a6dd0a049409b1645aefc0 100644 (file)
@@ -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():
     """
index 6095dff6e648f35a030d730bb685bc5696aea4a9..b1125e7164acff7b1a8771ee41eea629e94a80bb 100644 (file)
@@ -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 (file)
index 0000000..9bf5779
--- /dev/null
@@ -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 (file)
index 0000000..0959e2c
--- /dev/null
@@ -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)
+
index 195649bf5c80ce1df15d23e6c2d70d85326955fa..3f7d1c9ad39741d4ffdbb377fb4242bfef038934 100644 (file)
@@ -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 (file)
index 0000000..1424c62
--- /dev/null
@@ -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()
index d6128972fd17e9bcb3a65afa11cba6b22fcfc5c8..e2bb48b81cc5ec5743a89acf8e0531417b592ad3 100644 (file)
@@ -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,
index 32419fa0b608c0c7d31368262cb258759bcebc39..cb11175b59285e67213cc18d9faca3767c290376 100644 (file)
@@ -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[])
 {
index c8ac1d87026662cc23f21eaa0510dfc6211204cd..73c36fc754b71992506391fe9568aa308f2eb362 100644 (file)
@@ -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")
index ae63ea06981abcbf6522b887c99d544aa3b68366..914031b5a4b303e4324d3c69d8169750122c90b0 100644 (file)
@@ -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")
index 399170eaee387098fb7b34a933da7855220aac37..d4d122e2d3c6c66830bf25c8352e08a50e1d59a0 100644 (file)
@@ -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[])
 {
index 0543a0ccee5951283740b5bf1290278ee9bc31ae..2c9e624d257d503cf28622d8ad4ab585df4320f8 100644 (file)
@@ -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', 
 """
index da66bcae0af195546074213c4933dc1d6eb55337..42925814317df496dedfcc8c82415d52e747f2fa 100644 (file)
@@ -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")
 
 
 
index c8eed62d0a12e5ab1c930fea6c4797ed891938ce..287da160da87ba832b5a096e2918391fc5a2ce11 100644 (file)
@@ -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')
index 6396c45deff40cf5560351c137d79794c59c6e96..a0da9ffbf58bd9e58dd176d2542f11c03098f25d 100644 (file)
@@ -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
index da4761830a6a45523b274c85f13a13ea72792eeb..2045a3d64ac613521b7e454601b7e1e831b2ffdc 100644 (file)
@@ -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
index e87735435c78d93030cfd7894c7bc17664bf098b..bb330dcd2a26c56cbb3c9176dd0218990f3f6d45 100644 (file)
@@ -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")
 
 
 
index 21e8033b1a9c2552e784098172f18267d6f1df88..1956154c2cc4111632fcac8b34fe73a92c3ced2e 100644 (file)
@@ -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')
index cbd433927fa50f95a832f92000f9029894f3e4be..27858bdbe03cb2616fb43178d5af6e1aa82a98b9 100644 (file)
@@ -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())
index 7ae951a34e34e053467b566a41a80e98eebc5387..61c3c7d06c3ccaf2fc959ed01703c3cf6741c6f4 100644 (file)
@@ -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 = '.')
 
index e25def50ef0825a97ca46923f5d796811507134d..e076f24f7332587095361925435a12750e0835bb 100644 (file)
@@ -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())
index 56efafdc3d76316848507b319f3522c2f1567132..b53b8ce451ee2085512ca4199a6d96ce65ad0d52 100644 (file)
@@ -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')
 
index 4667a2189746c923ace3c535bcd3a5931f45cb6f..8c28ea57e19e312249176edc734cb9614ebf7aa4 100644 (file)
@@ -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()
index 2b76cc30cf07746db64426f7b301da178637ebba..a4bdd90ec0b2044fb8609c2475f86bc74c53072c 100644 (file)
@@ -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()))
index 604642bbda708536c7032d4f83487e39004b70b5..aa9e2a0ac3a01da53e1bf9b4242d0ef97eece972 100644 (file)
@@ -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')
index 0bae185a849d2d218798449e657afc7006d52ba7..f655bf92c0223a4bab345b98944a90926fe80625 100644 (file)
@@ -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[])
 {
index 298eb9bd0734a014c43eabc61da13d16e5a79192..685011d961d02990d5e11b964cf9cd526f440078 100644 (file)
@@ -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();
index 285b996c17c62e700d564d05c2283b921389f2ae..4fcd6257a7a05337d35832e364ae6a2e94755d9d 100644 (file)
@@ -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 (file)
index 0000000..d9e110e
--- /dev/null
@@ -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()
index beb7df0554155b80a5b36dc9cc37545245f8960b..9a25029a667cc4a744a7245167b1cebc144612f1 100644 (file)
@@ -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,
index a790baa04bd155c271df7590c2b7638f61348058..c57b7db948512d02db28e5637e3db1c8b3a920a2 100644 (file)
@@ -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[])
 {
index 1be89a3b00eb9d6daa5a41abc17c408ba17ea5ae..ca13ec81ac062b61a139884b7450611c408e87aa 100644 (file)
@@ -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')
index 1dd6a574c02f43739f97c671ea7e06592d3461e1..50ddb5ad99b1a51faefa9b4e5bf7307a3f54d0ca 100644 (file)
@@ -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')
index d05cdef51d8f3313bc77684f4c60b9bf9c44b8fc..bee24992e54c846d446fe2a8d58a0d1062ff332e 100644 (file)
@@ -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[])
 {
index 3679a9e43a4d76d67b4d3a54e61611af4500e8e7..9a025b157759bcb2b6b02ff5bb36ebc067616fd7 100644 (file)
@@ -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[])
 {
index 13cdaa8ab5e5677257a7aef26a40b7c15514a574..5606fd0393ede241f0d7b185061abbec5d3ebb4e 100644 (file)
@@ -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')
index 27e5cbc3b7fde35cbaf2d4038417eed808e08e57..4d240ae04211d78df89914b51e5b857f2b64145f 100644 (file)
@@ -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')
index 1f4fd3dec42fdaf8dad9d3bf1a8a3f8ec96a52ed..316da0f0acc91e4577017bffc373228a9d537b33 100644 (file)
@@ -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()
 {
index a122fe068261d413b6c42f84ebe8bda7f390dd95..9cbadf24971babe3fe570dedc988f80490c30e9a 100644 (file)
@@ -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
index 7c65401996a070383c76ac4541cf7aea229f5ec1..8639eb27ba7637957ec978c0081f64b412321095 100644 (file)
@@ -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[])
 {
index 72b10b79798707621237e069e9bfdf497eeaf98e..ce8bd775e94d430dacb72b43531be43bd3a429ad 100644 (file)
@@ -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
index a340a4a071e31803f6a7494ab2d3d4fbdb9904a5..305cf044442d4bf16f4aa4223657dce06affc720 100644 (file)
@@ -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
index 3002ee768e43e0af0c0f2b804eedf35c68f4523c..c21d9ad3a965cea921026097c2d9106e1af911ae 100644 (file)
@@ -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')
index f8eaa6a275dacfe5afead6753d90c7f017dff1ea..cbb2f3ff86da79dfce21faa1e08ebb976698b4c7 100644 (file)
@@ -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()))
index 78c40f7e2b37c6432ad07aaaca3fb8f2cf1806c1..acf0647a81ff2d14790789ae9c0bfc12289607fb 100644 (file)
@@ -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')
index 70a9b8270ca794bf374a5ee95f1b51dd5bc048c4..a1b4c2a31cf2dd8d2dcfcce5069a61d4304486b5 100644 (file)
@@ -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>
index c4c419d6846c3c324ef132007c0572c4f583de6b..c98fb8c86ad43d90db0b46fb269b069d30ec1b29 100644 (file)
@@ -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')
index 82f7ace666f58082b067e7a1b5856ec3aac9be4c..23bd3e632deb21cfd37937e363a043ecc4ffb541 100644 (file)
@@ -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')
index 8f4c4fa16b407477ecdc86bafef4f56a104ccea1..62e8cc10b8f99bb2d8db9d51db2dfecafed75d39 100644 (file)
@@ -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
index 5c050d1e276dd2b8709ed24d67e2d05e01ce5254..c02086b4932b671c2e4c4908a45041fa007605f9 100644 (file)
@@ -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>
index 54ef0d5377ccf3e1a9e9789eefec34dfc28b2a6a..600049e15c04a1e1c93cf96b2587143cbd0acea5 100644 (file)
@@ -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')
index ad3a90740f9d9f94100df3fb9bcc8dd708472e23..33beae7c8c00a4ab697dfd5183adcb52e722ce24 100644 (file)
@@ -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')
index 88da443d149d41594e139d38c1370bf33e5741b0..049835c7613be0d168c28fb908aa81d5a0c2ec0f 100644 (file)
@@ -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 (file)
index 67d3ed4..0000000
+++ /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 (file)
index 0000000..d03bfa6
--- /dev/null
@@ -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 (file)
index 0000000..f918707
--- /dev/null
@@ -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 (file)
index 0000000..814a5e3
--- /dev/null
@@ -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 (file)
index 0000000..ebf67f7
--- /dev/null
@@ -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 (file)
index 0000000..0de0331
--- /dev/null
@@ -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 (file)
index 0000000..119a959
--- /dev/null
@@ -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()
index 18fb60a9cf6fc7315022b96d64d610141fab6f88..9b6bb947c0910484549ade56cc38b7725b9ce657 100644 (file)
@@ -40,6 +40,8 @@ Program('main', [
 """)
 
 test.write('main.c', """\
+#include <stdlib.h>
+
 void foo();
 void bar();
 int main() {
index 6563bd9ccfc3177639ab760e47cac0a27cb3c14f..09c51abc392dd887826feeae65a01bb3e55bec86 100644 (file)
@@ -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")
index 4a99be89124664ea3a035d0270e3e834477f88f9..947ad42159bb6ca7e0a32bc3d285a15997cab842 100644 (file)
@@ -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")
 
index 2064886652c612fee90f3d364a81862f9f2d85fe..ae1ea2ba53805ee9c7cee09b6b260acac285c75a 100644 (file)
@@ -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
index 456fcc963df83a8b620634af83f79accca819950..4b6344049fe782b4ed43f13968792bcf423ef633 100644 (file)
@@ -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')
 
index 41c858b1f4efa911b029308a9153f2384c73a3b0..40636993cfe66dbf0aedab925961fc98b4d1cbcb 100644 (file)
@@ -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... ",
index 9a5a55a14991d520ffe47d6d03756df7d6d5722b..a344112ee64901ee37f746fa6314c48b29098096 100644 (file)
@@ -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
index 8db5785031d941bf7cebb7caec7001c91da43e77..8d36e5a7d05871577a925f08ca0bfaa74007499a 100644 (file)
@@ -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.
index 61d5ce701c4c69ff0e356c8cebb4914cf0fb863e..0d9cd8d88686bb089348c8ad1641e62525f99381 100644 (file)
@@ -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")
 
index 6e57adb54790c99323b179144376e4ab3a7598e4..cc0c9095d41b780ec6d9bd9f69014021d5cb0c35 100644 (file)
@@ -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")
 
index e9bd8ba9be8101ae1b7885041ef18f43c97ce1c3..4268705db4507dd4660e493132d4b9ef4b541c77 100644 (file)
@@ -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.
index 2ae856a5154b3cf78e45407faa718f1d358a42de..490ac9534eef0cdcd1d24b7a02138bddb7fef951 100644 (file)
@@ -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.
index 82e57c5953cbbb09f57f58cdf711bcbafc3c162e..635acb0be1d2b0f929160538bab369dee33a92ec 100644 (file)
@@ -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.
index 65e66a29a6edb476768d57f46defa31627561ef5..0d8408ec3501c93769399da18fa5e49c83a2584c 100644 (file)
@@ -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")
 
index 9a565a4a921ec22ec73c376f5b492655fb4dfd58..67f960e5bb75a7e425fe63f852fbb78f3d51a3a7 100644 (file)
@@ -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")
 
index cda34b29e9153c8641846de555cf9cd346badd7c..22fd883f59853f04561202920c79a596f9fd372d 100644 (file)
@@ -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");
 
index 284d6f74fffadc5acd8c53c44fc9bfd1fda5a35f..d0b21991fcc2d095daee18f0641c3d8cfaba1508 100644 (file)
@@ -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")
index 98d04f99f29abe06c8c22dc086aa96a0b54d08c8..9a39f3063f30d2d8f62536bbf49e1e4a80e25315 100644 (file)
@@ -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"""
index bee55bccde6c2ffa9ff4de80e34cfd7728309842..08f4a1a44eb3f74743876ebeec24b9eb5473d74b 100644 (file)
@@ -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")
index 9851db7cc1446c82bb8b98961f08c9c5856999ab..36c72e115fa70d159a0bccbf4b3210ab2323bc9d 100644 (file)
@@ -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
index 2637a6ac9c67e4427898601a6e4f53c03a53c127..44abc735a83ba7e5d8b25ed08865d22b2011e909 100644 (file)
@@ -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")
index 1c27def21288c1be896d171c70511f79e378f753..682cfb030e3e3331cb590dbe66e48cd1971a08d9 100644 (file)
@@ -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
index 9de4d17aa225cf4a1b6c7cdda7784fd04cf4970c..c566d88e52ba1ffd5dfabcce5a2241b9920972b4 100644 (file)
@@ -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")
index 721551d452cbd480a2bb7da65494951d347dc40c..7f6f1a1f7e63b057c869b08cf104814bb6ca2c73 100644 (file)
@@ -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')
index d50eeb91055ec0644656bef769734f8b394dff4d..b1d91426e95a7da94ae0501033f1fcac977b98e8 100644 (file)
@@ -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
index 8f8bc453932ad8f4506a7cb92a80bed1e79f34ff..6b38e8e3281a98fd3dd477d8fafceb4a7c006ebd 100644 (file)
@@ -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
index bb52340a81d64f2ac2ec34f5bb01090f62d3b84e..7a206da8f569e9ab34ae7bb8055d2f742b43e627 100644 (file)
@@ -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")
index bf7451ce684f3e5931f869e9913b2b7afc8c77cd..e2e3cf5ae4396412be307c79f69d7411819e1f6f 100644 (file)
@@ -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')
index 69f1dfa97afe623451dde645d955ff425b5e8c93..9a57eaeac058f33f9c8bd1ae8be61a2bdbfeec82 100644 (file)
@@ -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
index a19c90467ee589ae331a94c991a014cdde849068..1b5fc41086e6735f2e1d874e6bc847f7838eaead 100644 (file)
@@ -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
index 26423f87a89cd0f0e78b6c1df25cbb56167617cc..016230a9b6ea144dbd10cbe872f94ef3d3ee123b 100644 (file)
@@ -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")
index 823ade6a82695de49221ffa7a7bb254c88e68b45..ed7d1e8a660dcc54b8910980cd7831a98c268d6a 100644 (file)
@@ -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')
index 883d9a3915f463c0a47bfe0368f41d316bab9d1c..7ccffed7196c168ef544b72ec8ea2ef2c1670029 100644 (file)
@@ -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
index 47a0a890e2e14091bdbdc7bdf7d0238f00db03e6..1bd44073f066698d6b32cea435b3d3295204000a 100644 (file)
@@ -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
index f79ad6da6b7d33b49292517fdccd13d1f621bb07..3e3fcb2dd17bf95087c35c4eae07da82b4a99556 100644 (file)
@@ -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")
index db75d430093270b08c4b0fa0be969aa495cc0cfa..fd318c3abbabe17b46daf2c921817378fb0e5dbb 100644 (file)
@@ -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')
index 8d77d6300269eda95ffbc9fdcad7f2b217240405..6dd27d7f02d25a9dac64cf0811d73901c4338e5d 100644 (file)
@@ -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
index 4d594a1882004c3076712294b2c7407d6b8b92c4..f0c500ccad5b7ca77bd5c2d8aa6395ef947125c1 100644 (file)
@@ -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())
index c172f7a335412bf160101dc81d97c1f4d260e948..3011fac71339ef55035b51107a5cfccf139b29c5 100644 (file)
@@ -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
index 233921b344732579a70a19fbefd3283e8361bda1..c9569c944fffd3697041e132d9f0151a3d6054e4 100644 (file)
@@ -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
index fa024875d81415413e31f517080434e46b6b9692..75192dfe97b88b9c15e1a2f04ee7f2e25d15bbb4 100644 (file)
@@ -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")
index fdb81c1980271d4a021ba3608ff8913f957fba7f..908557027ae79a09a1c6ad85ddecd52372ea7b1a 100644 (file)
@@ -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')
index 85c1168ff32f1a2dca7b0a4ed5ad02ffe9e31663..5354a576cf998664947d7f9a4493ebfa412204c9 100644 (file)
@@ -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
index 66bd68dc2852ce56ed44fe10133c10215468c471..1696b4a846082f923e48b3ae52e2873e25d79e1d 100644 (file)
@@ -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
index ffc9878915d959f759d0c7b529279ac44216382b..13d9978af1d8d3a39a6a570af2465f15cedc1c81 100644 (file)
@@ -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")
index f0e44d3d80530299c31fb5e360799b7acb988ea4..9633d451d756bd48ccaedc236a6d997d142e30d3 100644 (file)
@@ -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')
index 3997cbb49a622408b947f8188ad427fad4328260..62bb7d0d5a4766be296d77081c9c4f053c6fa4fa 100644 (file)
@@ -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
index d2d92a914bf5383261945f741f1fd45bfcdbde7c..85702df23a54e72265d21ec05fa20af9fcbd609b 100644 (file)
@@ -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
index e28f8630922f9a10b135483fe9887ceb72941a28..b11933a07bacf3b726a515feb35c8d5faf1662f2 100644 (file)
@@ -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")
index 461d7ff68caf6cf7f3bf7266d7e3314a0dd140d0..eaa24ae75914ceefc17e66c0e9bff87fbbcc0df4 100644 (file)
@@ -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')
index 782a495c20b27691e6d8b010ee5b21a2489fdcbf..2288a4a50900c0851e2a74732938ec07eb6e9814 100644 (file)
@@ -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
index 17a58f5d34b397614232164573f60e30806c8ab5..586b54e13753d675f6ef5004159024bf7d352ad6 100644 (file)
@@ -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
index f4d44dc6714e43369f739760a3ccb2188c58fc11..21942cfa01c5c79a9cf681969c87738b10859679 100644 (file)
@@ -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")
index 8ad3b142f4dc4b5e121eb2560a47cea0aa1f5784..69a1eba723fd882718af4e7bce5241486eacc9ab 100644 (file)
@@ -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')
index e96ade9953b5c791c8a5e25bc935c62ffa68e98a..d09a28303fc09f9a1f4ed59f7a716ae97a1a1982 100644 (file)
@@ -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
index 541c45703bdfc24fa3059f1208d5c07a7616c71d..23d0a8942df48c39dab22bbc8624a4729239cc23 100644 (file)
@@ -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 (file)
index 0000000..88d0888
--- /dev/null
@@ -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()
index a836cf651e4f5d5bf8dd1ac43dcc585e052f4c15..6089d60a122413bd8e229c260f50c88bb13b029c 100644 (file)
@@ -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
index acd46f2278945a3669636e5eab4cff1daac67c3d..a41c8005351f299e1ff2bc9ef4d44f32919277b4 100644 (file)
@@ -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")
 
index 9f7aee8f2bc6d13359d4a2c051e8bc6b84e0bd75..923aee39dd8875f127491e9a4a92b587f62bd705 100644 (file)
@@ -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")
 
index 14ce76914536e69e16a6b266d1bd4c4c22e2b2bb..7acb89ec466e50cc6650c06f65f3cd5d4dd7fdfb 100644 (file)
@@ -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.
index d3f64200669e4355a77b8b3e8b629e1343598742..79857d060796b434e6d09219f93a8c1c3436288e 100644 (file)
@@ -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")
 
index 89a6e250fd9cb6915ea68672c6a5403508f2f005..8c3a15a70fd96bb3b7b8fff67dc6b76bb36136b6 100644 (file)
@@ -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")
 
index 1652f605b3bbad2a8f9d5fd65c7d5f66a853ccc7..15cf4f3cb8f2d6b0ff201248069d21ad96e76ed9 100644 (file)
@@ -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")
index 7018466fadaa017a7870a76087a1db7191d86e28..e24641bea318cf1d84981d9ce723e8b78f88eeb4 100644 (file)
@@ -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")
index 4fe4bd0b62ec21e08b73a08025a7370505c48977..7a6c9f6c94e487964c28734614143f73d73bb3d3 100644 (file)
@@ -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 (file)
index 0000000..300ed4d
--- /dev/null
@@ -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()
index 1344fb1785e86a81355969398c915f29c2f51edf..5342a484051a187e4477437fcb6d8ae87dd5cee1 100644 (file)
@@ -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')
index 0d7ebba02fef0e1323c4ff560ddc27ac626dc71e..f03cd9f7636f84489e6b697d0eb608ebf03d78be 100644 (file)
@@ -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())
 
index aa8a6ad5e7d633e85ad1fdceecd44f3caf0bd315..35404ce22b576e231cb2be0c724f92913a6ad92a 100644 (file)
@@ -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())
index 93f0e7ba2723edb30760c8cda1d8e6461d6a5ca9..b5fb3f8685a33f9e02dcc1ec9af2747281ab7453 100644 (file)
@@ -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'],
index 171649c1f3f6cc884825fccd903f5bed7fe3008b..7086a2a2d9c3eb30ba21d8b18de0a3f9be02a7d6 100644 (file)
@@ -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())
 
index 7f59e902485259efa061374b4207ba8d1efc4c33..44b14496514f55367c3c80b09d66869814c07e2c 100644 (file)
@@ -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())
index eb70ac829f91a4774f9509671ab62ad5e19b6a7f..9901764d9659a47960b89f6af82ffabad1a83506 100644 (file)
@@ -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')
index 1cc4208f26ddff7c629b41aa6b6908a4b7fc7bba..73067c6191bd257e92c16c7e1059e6f6a893dedd 100644 (file)
@@ -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')
index 2a14e1ce5d5649fdedde0786f52979386fb7b261..8ee57670b40fb0229c821bb2209c2b56270fdc4b 100644 (file)
@@ -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')
index 7ef1359b72d704dd7dbcac449cbd4436c17964b6..bb098e78e9923409fa2fd93032a1488a355dee74 100644 (file)
@@ -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
index 109c22e7bb20e83daedf5251072efeb54234b135..ed5e0d674972c3a52f5809889efde19997097064 100644 (file)
@@ -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')
index 1bcf300a4ecb14743dadb3e34b4ed1c1d652b823..5a451ebd1c7f94f208034e7b2497b70757e22a61 100644 (file)
@@ -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')
index 5515a3eda78ef1544fde0b6848cf44df5693cb1a..3fd4db3d027ce681145432373b72d7d58086f9cc 100644 (file)
@@ -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"""
 %%%%
index ea4626d3143e9458104a5b247b18059a3ac9c477..7ce8a15c46e84678ee0527812255e491a9444acd 100644 (file)
@@ -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")
index 5b01df7bb141115cbc9124c6ca3699d6c2900f83..a06c20c226707c7803ce4603e937ec1d82fe350f 100644 (file)
@@ -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")
index 87a869faeca13a07f4ea9412e0b3cf296287bf4d..59239349201ff011eb44ddbbe8cc3099461a044e 100644 (file)
@@ -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
index c54d2acf967bc2a04a39616c4d825986550248b3..1ea7ed8fbd4cf50e7a6a5854ec0c8f6fb0dd41af 100644 (file)
@@ -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)
 {
index 753b9b30ca2c8b60791fb2a45298b5a17dc460d7..1e5d6c2bdf83b58f7cc466ab8b9061fb4dcf5a06 100644 (file)
@@ -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[])
index 3ff26e0d3104979425da6e5b2aa2882ae4ca545a..708ce6355bbad77cd7f1c9b51b4174095346be54 100644 (file)
@@ -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)
index c776ce0dfce69a77d2d5b7d2dd8c73b7c5f1f3c9..29cbb18ea2aaa3a673ac047b3b1f6263a97cd592 100644 (file)
@@ -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[])
index 2d89352322b5027a145ac110eda4069d5d33b947..ede03f5c3d48fb3ae50b04c33f311d6f01d616c6 100644 (file)
@@ -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[])
 {
index c94d5e3199f0f818a68805ef2434578962e4066e..d91404901466b9bb503397b39f1efee5a48781ad 100644 (file)
@@ -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'])
index 70b5c0c437b4e531aac06989479f089b27fea506..1a7efbe19bcdbdb5998af798061e962530ffad92 100644 (file)
@@ -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')
index ca1cd1a83dcf29e4d7c5a5364012fa5451c90be5..d80960d197b2a7941ac3792c64107afa314037ec 100644 (file)
@@ -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[])
 {
index 8b9097d18968eab2ba8215345153437fde5ee80f..296845c21038f522e5d490762f51387033daa736 100644 (file)
@@ -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>
index d97c4edbd16fea4610e716c94e0c42aa1e4a70bf..2d2f718463591afba2eb7b67832c5e2d212b5f13 100644 (file)
@@ -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')
index 1ea29b2695f52c0ef8b36812326332c17b71a2b6..cf318133ef0e9e8c8b0a0e0cfaa184bf9462a28a 100644 (file)
@@ -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()))
 
index 709ebc61647384b78866c330dd6e55838d79306d..51a8f7c9dcad9c5d542e621f1a6988701f0a03ed 100644 (file)
@@ -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>
index e4626ab78d73d8eddba0e47c22e3ae13a32b5664..3a04b9c67801fc97684cc9c0ef6f23f0588099ce 100644 (file)
@@ -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)
 {
index bf56e7406d198be65d556218c0ee1c9351a74d5c..859c57ba76abb656b66e7a5faa102aa579c61b9f 100644 (file)
@@ -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())
index d1c53b4b102d224e1d5c346d945c866364ec63dd..8c36d8674a516cb0e0090d051f48ef43417ebc87 100644 (file)
@@ -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")
 
index 0e144952fd51a0faaa38966c58b52cb823f38fd0..a9e91e68debf646160845cf7a7b2f0aa0080ca01 100644 (file)
@@ -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")
 
index 593a1c145d3d226eb7c1bb03bd410c9e5b0b78ad..247339152c0794ba1553defeafd0e06614f80da1 100644 (file)
@@ -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")
 
index c5ab9f52b9f917f7806b7abab3ad4799b76e5958..23322d4a3b5eaab4ff0fafd0cfb54870c7f3b12c 100644 (file)
@@ -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")
 
index 3262f0cfb58edfb08538243ca973655217a3bd8d..e881bb58480fa15d587f458d60b965baaad0876e 100644 (file)
@@ -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())
 
index 33e192b9c7e321a819b52a8cb88b5c0ab09de70a..96ccee09a9419709a5a89a0552ca8c0c02f14ccd 100644 (file)
@@ -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 (file)
index 0000000..0b3c332
--- /dev/null
@@ -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()
index dd0f5ca0990178b51e6e92d4f02fdccea3aea8af..857b6bdae1e35bcfc896f35fcc016da5f0e3581f 100644 (file)
 
 __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()
 
index 6f508c95357631062d2082e2c9ae6e614c64255e..d40060c7da1cf3396873d7082476db2454183d7b 100644 (file)
@@ -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()
index 581de64988662ed99cfe67ad4f46670e57a945a8..5638916ccf16d8178efd088bab9a83edbe69d3ff 100644 (file)
@@ -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}',
index 135bb7faa36ee104a127c50a18bd8b5c1d20778d..ce7ef463ec3fcc07f9649acd11073adce03df4a8 100644 (file)
@@ -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']
index 8c82d1aef074da7c65c931a8d1af081b5f1dedb7..8f98166656c00a872c87b0cc906f8643bf859d64 100644 (file)
@@ -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']
index bbe6f1e9d8c049f77069a9024fa84026d576a960..3ad2e9776f95997e21847e98ed0774fac7cda59d 100644 (file)
@@ -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']
index 878aa3ffc57c79aef7c09456981e35b0b1ee47fa..1d3c469f86ddc54b5b7468cb304d44be0aed7370 100644 (file)
@@ -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']
index 4ddcd91de40ee9d7a7a0b79069988d0ca4d0eee1..2db056328a82080b26bc903828c94e5abdfd1de8 100644 (file)
@@ -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())
 
index e0958473f0b773dadacf4c1e0d24cc15f5ea2a67..96565f14c80dc61d1e159a52be4ad9ca0440222c 100644 (file)
@@ -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())
index 9f548c41ff53103e02927d95b72108e7aaaebac1..ff3e0ca15bcc5894df833bda887525bcf8ebf0a9 100644 (file)
@@ -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"""
index 8b9c5e060b6d12b8c3e972d034c70c73fa1d6809..da945e35fdfb2279e834ea5231726809972885da 100644 (file)
@@ -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)
 {
index ef6491dbecd99d4c83c3b37d01400cfd58ef7d98..7af9bfd4120e721345678008e88639aadced56a7 100644 (file)
@@ -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)
 
 
 
index c47f7d5c4389595f78ef7c6a976da542631de93e..5e29477aef9df240d17b302d84c299ddb618588d 100644 (file)
@@ -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()
index 5dbe0c372e92bcf84ce6e0bc90f100e242d4a362..fddfc5f35cf64c881fc2d089cee5185ec6e09872 100644 (file)
@@ -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
index cc520f78654cc4f341dd1362496e82cfc7a78cb5..81f70032b19c14d3c5d3c8ef7c6e47ac62be8fac 100644 (file)
@@ -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)
 
 
 
index d15f39bc57709b4718b002136133aa0322472f4e..d22071ebe7584b2ddddf5a0ba47ea4f70ed251c7 100644 (file)
@@ -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])
index 55678fea3e0feb7d0b42a0a483b956c7920e8624..668d08aa5b45fb5950b2a4afb48674269312d4da 100644 (file)
@@ -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']
index 9a9910ab6ca362622cc717dd97ded8c02c1c279d..e979b91d4cec88aa24e928c2d751a16631ecd71a 100644 (file)
@@ -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'),
index c33254a4394160842507f8b58ba5e66277d16330..11b28e37fa0fc4c8d2210c51eeed58ca29c98f82 100644 (file)
@@ -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()))
index d9a3bc0fe45c46390426b10c2d1925747deb0aab..72f05b8a13e086b5d1908ef04902c03338c5db40 100644 (file)
@@ -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')
index f813f106586c118bc7deafdbdabbf00d06f39aa8..0133ced1813cf9d2231faa672b43845dd66e157f 100644 (file)
@@ -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')
index 940fab77cbf3d992cea2c91c7829d32f63e3b382..76aa2a46d089417806dd196d1f5812ba78a416de 100644 (file)
@@ -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")
index fe778b338cc17e4ec9929a106a83dcc1c529479e..d8180bb61c361ef54b8dca6cdf48b6cda72485e4 100644 (file)
@@ -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[])
 {
index 5b785a392ed0fbf172c22f37b106b31082ff59c2..cf9814890959f875d81c2b17aa0b6ef745b7b327 100644 (file)
@@ -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[])
 {
index f9cb917a7cd53e2af2918a56fe76539ae314d9d8..ba08739e8ffa584f0ddf25187ee280c5ca6588a6 100644 (file)
@@ -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, """
index 0bf687376256f5036e9354e340c91f2459e6889e..1dbcd0f346a840a01371473ccb7d634c935f5158 100644 (file)
@@ -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
index 7b41360686d50688c2ce9e0b199835fa68955987..0fd3f6638b213a1767032c0118e90f58eb8054db 100644 (file)
@@ -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))
 
index 5002b20e11b388ca9d7e9db7112a7d05022416bd..75e860ab768c357ee360857c46cb6643519381d9 100644 (file)
@@ -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[])
 {
index d60a14ef7980c3ea8889dd3d639fb9468324e5b1..312216b27f0b2560801c9a042ad2c6d1668dc621 100644 (file)
@@ -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")
index 4e0367588ccda40231a93844b28c78f5bc7c64e2..6929ac657039f3dbfe17a82f7d8c399638c7884e 100644 (file)
@@ -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")
 
index 80618ba05324086960c369c6e5d3c40cc696c522..08ee9671c9165230dfaf2090b20f0be3a462fdd7 100644 (file)
@@ -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[])
 {
index a151d698d5daf802eba901064de8dd7a03e1ed84..319a8519636917ccbf245bb822e79301de959e20 100644 (file)
@@ -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()))
index 9e17418e98021c2fd4cb2f6a55a804813af362ab..30a3a57b77e1bda96d3a531f0648e9c76d3bf147 100644 (file)
@@ -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')
index 8af2545d13c2e349f24f45a46a487e3e426f4aac..78120f69b34d55262d44fe5c24f0adea647e4147 100644 (file)
@@ -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)
 
index 362f15aab01c29d565ad98aedc130676926e2edd..3223901b921588d436e1884cdddbb82e425d85b1 100644 (file)
@@ -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[]) {
index 6ab6eb295c6905ab096193a8eece72893ebc1fa8..a0ae8c786e4595da41c9911952f9792a6a89a257 100644 (file)
@@ -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();
index 6ec21f36b1a6f9acf1a1b1cc9adb8cc2665aa494..9db613e3a889442dff5a6fd9fb6f46d5d26d510a 100644 (file)
@@ -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[])
index c4470d211477ddedad010675c9e88b6d785583fb..9216a8b3ce5114b7ba7a2f8cf3645312597e0b8b 100644 (file)
@@ -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[])
 {
index 75fa0de1221f3b65dd00780e7f810f27fe26838a..15d8abb2c493896dc8965aa7180fb95c51224909 100644 (file)
@@ -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
index 93bcb85d350b2739c386011df4bca7628aa1f60b..eda12021685c9b931977ecafa4e692b29451f98f 100644 (file)
@@ -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
index 087fa7e9ecd724caea2665ef38091e4908a81ca3..1cf20c35df7e004db42eed9efd9b1f8d3f21bfe6 100644 (file)
@@ -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
index ed360c7186a771c59f6238df6ded751eaafb033d..378e32119c556503e6f626fcc2407de93dfdf7e5 100644 (file)
@@ -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
index 577442a2ae2a0447ed4541d43cfddf16a6be8b34..4575d994d83a7a341884e23ccd109c4f02c20b5e 100644 (file)
@@ -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[])
index 63c274e0c7a47206f007c2f7dce7059652493e20..679fa7e5ea2b7678a540b2901075808ffa72cf3e 100644 (file)
@@ -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)
 {
index 4532cc3903ea13cbe5539b3ee7fe019ce6939bbc..ab67c9dc8164edbf7539d70606dc7c550a3097f3 100644 (file)
@@ -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[])
index d838605c93577b78deea3b94a20fd10e5dca6f4e..95b1749f3bd98c47a14687f1f7ebb594161b8479 100644 (file)
@@ -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[])
index 6dc9add4b57076daa906788d205d96d85bc14e1b..f9b245e9920955fac03ac1302c7d40a1afe6bc36 100644 (file)
@@ -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
index 8069b606ff77cf00e42d4cdc431db2f912dc29ba..99bc56a7502dbcfab441f3d20d607c0cc72ec6fb 100644 (file)
@@ -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
index 2d4164a6a7c6105e799a2c4c53fc3ce507c9ee34..4dccfd55a45b224e2849473d94964dcb3f2f2336 100644 (file)
@@ -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
index f855636757b59857ad3acf9f730730431aa9c273..cd4c24a8a245bde81a5719c086f474ce9cadf9b1 100644 (file)
@@ -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"
index 1cffe81c4fe12bee3006b5b9e06276ee4b0fa95b..0b7e844b721e082fbc1c6cf3ac955b6028b55c71 100644 (file)
@@ -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
index 162615bd20ce9cbe547782873b24faab4c73fcb7..ea224384101101702f6c5ebd07bc340b487adb4a 100644 (file)
@@ -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
index d8ce2260bf92ccaa6652ec3c30ac662d7f90c48f..66ea6dfedf66bfbf2f28fc830535d6c0c82fd57d 100644 (file)
@@ -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
index 951254f68c8c5b6597ab62881a295dadd5aaa2eb..8f6cfffcdfec0979d6755d3d66f233acdb42af83 100644 (file)
@@ -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
index e8d3cb0f99ea84bc0e7352df9e0769112694b76e..411838d53906be1dbeee091566a889345a9fc12f 100644 (file)
@@ -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
index fbc5c7f46033bbbe90f7cc1da209f993b7688b47..af638ced17c1cb7cc76a5ee5f02b66466acb292d 100644 (file)
@@ -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
index dc428a068de3b1c0f71687bf9b90767bd9f8da11..6ce06091fdd78f108eb82dbe48e74d0d5fe15639 100644 (file)
@@ -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
index 1ba57823554667889734d68bbd85752fb0051064..f7a210c153854842d7e1d6bbc6d7720c10b2b29d 100644 (file)
@@ -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()))
index 858e17b19b97c343a9352374955deb2be3223516..be5d8078e6934e8ad905a73310268034b337d536 100644 (file)
@@ -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')
index 532ad9c827726988499cc81ab929065c3ade4b9a..66566fad024f704bbdc1c14125371d9e437233ab 100644 (file)
@@ -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)
 
similarity index 59%
rename from test/SConscript.py
rename to test/SConscript/SConscript.py
index 08e41a6fc8909a0be5749615689dad30e085d1ac..268c48e20964f79b32b2de1cfb2bc506d647df23 100644 (file)
@@ -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 (file)
index 0000000..3763378
--- /dev/null
@@ -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 (file)
index 0000000..0ad0561
--- /dev/null
@@ -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 (file)
index 0000000..f18066b
--- /dev/null
@@ -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 (file)
index 0000000..34f52a0
--- /dev/null
@@ -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 (file)
index 0000000..87eb701
--- /dev/null
@@ -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()
index 46d0954c9044cbb38753e6d2a47428a9415aefe0..e2b80535df4a5f629fdc3168c19cbe388cfa62ce 100644 (file)
@@ -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")
index 7dda321ca40c7b92074e51be1be50d5f71af920f..915dbce79ec89bc9013f920a5bd94d8c9409a82a 100644 (file)
@@ -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")
index 352f217604ac735022ea9f6427a3492e2a54449f..87b92fae002e4fd91c1c5dd013b37e4826b8d664 100644 (file)
@@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c')
 """)
 
 test.write('foo.c', r"""
+#include <stdio.h>
 void
 foo(void)
 {
index 94c2984c0e467ae58cf3d9d0eea3f7537dd097e7..dc88e3b1e49f2e3d2dce3776daa451da9c1064b6 100644 (file)
@@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c')
 """)
 
 test.write('foo.c', r"""
+#include <stdio.h>
 void
 foo(void)
 {
index e6eb65e37db6a3f974c6f80337c65cb4cd6ed146..f73ab112010886cd70442c0bcb7ba9cea77320c7 100644 (file)
@@ -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())
 
index 65ecf2ba923cf639599faa603d0c588114803ef2..0fb1da4b4be9fde15e54f1310deffa60b34711cf 100644 (file)
@@ -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())
 
index 22e217a64620364100a608e36bdd8334310ca2c2..20d2d5d27b24a8d3da0068762ff9f8e95025d8e9 100644 (file)
@@ -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")
index 3ffcdbf5f64e5d337c42e5b14ee1871ab5b0d8af..b991d774668448d8c60a6dd86be1c74c5d9ffa56 100644 (file)
@@ -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")
similarity index 65%
rename from test/Scanner.py
rename to test/Scanner/Scanner.py
index 6e64c0300b3f72df3e96f738e471e166c0d56c9c..09c5680bb1f2ec938334d64094ae6b21de0548fb 100644 (file)
 
 __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 (file)
index 0000000..2112fd8
--- /dev/null
@@ -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()
similarity index 72%
rename from test/scan-once.py
rename to test/Scanner/generated.py
index 044e26031be43446bb7bf06f89393489cff7239b..36f35f630caedcaeef9b0202dddbecedb031284a 100644 (file)
 # 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 (file)
index 0000000..514fbca
--- /dev/null
@@ -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/Scanner/scan-once.py b/test/Scanner/scan-once.py
new file mode 100644 (file)
index 0000000..7e02dd2
--- /dev/null
@@ -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()
index d9b035099937347764460ee7da857ab45e7da044..f8447ca357812574e7d8524e1ac44bfd625ee2ce 100644 (file)
@@ -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[])
index 9d5a617e162bc09b7eb9d6cc4578179836d3af3f..c82e227a4f16b487fa8a2933f0e3e90333c31658 100644 (file)
@@ -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',
index f6e36e799b4cc06c9581bee147e782c2b4d384d8..a39dd22f091a1f57ec9039cc5bb083091f3b3c14 100644 (file)
@@ -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())
 
index 2bd3813d1ee7f8eaa1b15539b21ea0f29284a669..eee9b16f2df03aa469978fe01c911518ba725aaa 100644 (file)
@@ -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")
 
index 2cda5022a363339ed95d627ece7295c178e55220..c592fe00bf966c1e62b82b89c13d377e1a830936 100644 (file)
@@ -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")
index c599a1608668a60c3c73c5cd3a984ec7703c2687..09f20f09afa41ccd4759974891c68c65c6e2460b 100644 (file)
@@ -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
index 25446961a970af05acbfd2a35148c9c143d515be..0636109a124d3ab549f9cce56e1a014b08a68564 100644 (file)
@@ -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}
index 803d26d2487a950f2102f0a6c694756e746fbcfc..a5044ae9037620466e34c1c2fcad4f2948ff60a3 100644 (file)
@@ -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())
 
index 5e31301e9c390de6609c98a2727735a2ff136cfa..08fcccb9aaeca4536172bcf72b2d431dd2f6d324 100644 (file)
@@ -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())
index fa2348f001b598e1913172bae8e68c1748e82a19..b887038652750c04e529fa1f8bbf6a842dc2ed12 100644 (file)
@@ -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}
index 015db568f564d9348aeb5458c4be7f0e8353ca74..e1cf00e18bcf4d391a048db9277be477dbb61f5b 100644 (file)
@@ -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}
index f46ed37a836cefdec4ff59d0839a2e523ca70ade..1ce2642df97b4a523c6e0402a19f5d9cdd6c817f 100644 (file)
@@ -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())
 
index 94cf12133b599d531f32e9105bcb99bd1e6bac9f..284a52ada4d28766f978b2decab60d03fbafbde0 100644 (file)
@@ -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())
index 0b6a9fcabcaf0dd0a710c7ebd789cda318b62a7e..a3948fe8ba6d0806594d3b9e840d192ac492fb91 100644 (file)
@@ -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}
index 5b99c2307f7206ba82f5fdd05ae33a79bb1f30f5..ad77b8afa4e2ca1971681b6e19eb2acef7ec7e1b 100644 (file)
@@ -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.
index 2a7f06beb43425206e01d335dc5ed67c88d54744..f7601253d543a895226cf4662188d2660589fdc4 100644 (file)
@@ -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())
 
index dbb7b39de32632e5777eee957cfd63ec7567f404..ac32ae1e437afdf260b114396bcd7cb16e78c738 100644 (file)
@@ -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())
index 1a0f8df2f6adba47ec61209d2bc5a9e03f92c2b1..94c54669678a6eb52900102431b7e9c4c2d43987 100644 (file)
@@ -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.
index 4645c7c641a9d58a3e5d86ca11edeb8eda4070da..7ea359b4425c2e8d1359fdc2d14ec82a4bb1eebc 100644 (file)
@@ -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.
index 4957427a2d6e979744d41a703f387f458d9f9c7e..cf887a4f822bfce5f00e426e13a9441829c5f204 100644 (file)
@@ -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())
 
index 81e7123424e9af815ea8105f3610f8893c3e234d..66c26020cd550f857edb55684ec3f94984b300e5 100644 (file)
@@ -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())
index 7bd602fde1fdf5bb54c2a7fbd4c2197a4356da4c..c27ffe52f526101f00d0155fe7daac92e634556c 100644 (file)
@@ -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.
index 46f82322d202738ea4e830afbd7d9af38b0cb19a..85fcbd1969ac8de38fc9266fa5129a1ab0bb831b 100644 (file)
@@ -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()
index 9be1934713b28afea121876b1b3cf35f4122dd67..d3bc679fe4dcf59edbfa7a4c070aadd0bb162f05 100644 (file)
@@ -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"""
 %%{
index 5f7cd380bf57edff437effc1647bd31d84ce443b..1425eb838447db96778a0150657238b5f0a822f9 100644 (file)
@@ -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")
index cfb48b76e6107a932fc761a078169d04604a1e84..b2c128d12b0cd0fcac428181a929ea376c453705 100644 (file)
@@ -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")
index 2779597a1da3cffe6f51adc60ea2c9c621c88bf4..a94bc8f980f4be5fdc67010f877ffb4ca4f2a659 100644 (file)
@@ -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
index 389018fbbe0acafc53d3a485281448b4ed4ada89..231472dfb5e5e82cb39c35a5e620924f5fa70754 100644 (file)
@@ -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")
index b564d5e8e1a9f484e1b045af370cac00c267efcb..182f08b651fae5130775a255704c77b22f6db9ad 100644 (file)
@@ -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")
 
index 33c54dd52d42b88aa9f3226c78feeadc25e38794..646677d15a0d2cf9fb4b8fa6e9c57a0cfc4d7e6d 100644 (file)
@@ -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")
index 42b8cff4dba04a8daddf98ca1d53bd33bdc00fed..460abe42f1fca797225f655224800fb743b77039 100644 (file)
@@ -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())
 
index 0ee90fd8e602c48e96315352d6735fe5b8cecfca..5284d0a0bf890efb3d5b33dfed36a77d93f1a285 100644 (file)
@@ -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")
 
index 59fc184b7003b0fa7d3400d3d5dbc6c79ba06dcc..cb6b357c73c6f2921ba0b8fbd886180253689752 100644 (file)
@@ -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()
index 4eb6bfad2e4907dd6ba26907688fd78a2655f894..8c7c4ab78f36df0c2a00e7e28a5c083276178b80 100644 (file)
@@ -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()
index b46764b337f22cde8de5a95b00a254db5ce074b7..1a1a2d72eef766703be203179dd79c8c0bd97251 100644 (file)
@@ -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())
 
index 8d1275f205264db4c0b6fae36f044907a4b6e047..b2a89743268a88de96001c44ac52be25b757e9d3 100644 (file)
@@ -40,6 +40,7 @@ env.Depends(foo3, foo1)
 """)
 
 test.write('f1.c', r"""
+#include <stdio.h>
 void
 f1(void)
 {
index 120ea3a0fd15c91ee749bfb4f3ee83c7bdaa56b4..6e0a05f9ab7c6b161f09a743d6f76c0084a5e422 100644 (file)
@@ -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")
 
index 584d4f19415121b6d7c1dcc90cd6f5e9c0092257..01a28552256ae0b73f8ab29f6d50b8eea9a2852e 100644 (file)
 __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')
index 2c22291bbe3944965b72e25ea972655d4598ccb2..0f7213459435a6c975598bcb0e740a4586490f91 100644 (file)
@@ -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[])
 {
index 7f0fbb54975a13088f8d158f0eea9f4a4b7c0d55..f69b00f1154610d5e939d05091abcf9f513f46d5 100644 (file)
@@ -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")
index 82c83ef6abecb0a980e9eb30c0734470fe0efeb2..4bcea00c3f5bffc8c509878635bb329103160fba 100644 (file)
@@ -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')
 
index 201c488a20c96d84a7ff3715cc7647d0e4a8494f..d4de8d3acbf9fa42425918f0151932abda1f2926 100644 (file)
@@ -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 (file)
index 0000000..5915cca
--- /dev/null
@@ -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 (file)
index 0000000..ee2afa5
--- /dev/null
@@ -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()
similarity index 71%
rename from test/option--implicit-cache.py
rename to test/implicit-cache/basic.py
index 2508cf244e9664263be9c9522e13c983c78c648e..0c9196cfcb2a9d8145817dd3f8a9f023fcdc84ba 100644 (file)
 
 __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
@@ -258,117 +253,65 @@ 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()
index 3663f535f0f79e3042fd1e8b8ffeea1cacca0f49..bb070ab3cd85f9c8a6ccce826ad32a9efa14e61d 100644 (file)
@@ -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,
index afa845525a13c75d8a19a9d7d809838382f5ac18..1c501e3576c06c55143ec289dd17abcaf31278f0 100644 (file)
@@ -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[])
 {
index 5a5d667b614c29a2063c3a8ff6234149e397f7df..c8b8df453cda1a1b3cdd84aa049f23cb32fa042b 100644 (file)
@@ -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=("""
index 302e17dbefd8a8e128a0be299f17acc19116c1e2..59eba6047b77f3e08fd9e3edd9f9d3375d60d668 100644 (file)
@@ -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")
 
index 5f7076954b3a7eeb4e728c5afe0ea6e92b79f3e2..954039730adca5d106851c4498558ed79b12f3ae 100644 (file)
@@ -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)
 
index d1a118ee0375a148ceddff522d2127b9fa17527a..cca8ed17d8e52e2949957be73244295517ea7a78 100644 (file)
@@ -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')
index 4d1a0058bb5b75f114bddc9f997d7cfaa64de76f..f99031ce980d28159e981ae72824d9e82189263a 100644 (file)
@@ -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')))
 
index db6532e4f6c6c6959cd3a1a7919508de706a8129..3b0cc0de86a0bcee1f98ede63582bc4c76834678 100644 (file)
@@ -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')
index 62d8b7a11d4df4cad6f42767515fbf603c9790d6..99d6939823e1200c36a8b83e63b8404b36197785 100644 (file)
@@ -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[])
 {
index 16a3a73d270af9ed7f4b9a33b16c545c78216586..1e62c491d1233499d1add7c67ba6ddd53448de1b 100644 (file)
@@ -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[])
 {
index f60710d2e75fafcf1abc6f70e4f1c4299863da8f..a56f261b9e5c8cba13e1593e9c06cceb69af5c52 100644 (file)
 
 __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")
index bc26f33b57be04ac9e2453660f7be9861ef7aab0..1ac077a6fe2a91d88d256b22188325dcdc8a8bd6 100644 (file)
@@ -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')
 
index 88148277fcc38cc86f8821814407684f08fb1520..7ab4129ae0d744fd7e0d1186a460280302be93e8 100644 (file)
@@ -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'))
index b0a84f86eb347a72abec5e5c0a0e431c484c17c1..a4ea4ac52f71278e1528144a9899a7b8737c9f13 100644 (file)
@@ -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")
index fdf7b8392b5d39b26461c5dccb43676e5bbdcf77..8f4c19005863cedcc3c50be1bd9395dad74812fc 100644 (file)
@@ -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")
index 45c31d2bf05fea24d125918aab9d59b2ffbb945f..0a46606a81b9762d0b1a4df0e473e1e65263d9a6 100644 (file)
@@ -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'])
index 769c4dd114a74ab1c4ab2f39adf06716f1af4f99..2e7694b7abd90c626aa3966a6d077fa7aecfe03e 100644 (file)
@@ -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)
index e8460f09d3cde1416f352938dd3ff5ebed213ccd..9b67d0a552c03387951903dcbc9a2cab0b27259b 100644 (file)
@@ -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")
index c1061ba80808b27e99763bca33038307a9781150..b3bde5f209c7a9c858645611698d9af27d28b81e 100644 (file)
@@ -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")
index 0a7f4d2de4396de3bf8f3a57f270442c99099f1c..06296b91d4ed15c821ac8732df9942a6634ce61f 100644 (file)
@@ -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[])
 {
index b18841bd01e4f1460e3b9de7845d5d86170410cb..42204027bdc5f4b9a39e284165913f7dfc360b59 100644 (file)
 
 __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")
 
index eb7f818c218f3adc337a28e94d5526b4e02ab4d4..52d64a9d5649e1832b14c7575192eac2167dced5 100644 (file)
@@ -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[])
 {
index 1a3052ad05db2e7189a2f304ebb678d549d99e7e..aff25f249f8fabf3b8d85c1bb7b4245fa9b7bb4b 100644 (file)
@@ -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()
index 69aab066aa7521825710e0d5a13a8633f6d063fb..8ffadc6d46e09067a3cd12432f9ac8e3349f691b 100644 (file)
@@ -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[])
 {
index 5766cff82af808d278bb5e8a072289253197e75e..b1471badf3a61470d02e995711771997d9aa052f 100644 (file)
@@ -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[])
 {
index faf85d971648ad98157ba4e928ec8cf2f247beb7..4f025c2864b1e7096511be195b34f6fe6ea6f945 100644 (file)
@@ -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[])
 {
index b6a0027946feb45270265efd183e4f618e04aa3e..920706671554a6cc1ccf9d8fc250fd289f2af9e7 100644 (file)
@@ -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)
 
index 69f7440d7a709d653d2f1fb54d8da87acff979d3..dabf689bececa7168033d0de0ca235a1fcd2e4eb 100644 (file)
@@ -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")
 
index 5aac517678d3cc4aee6c12ed1e7b4cac8a18de0a..cededdbf7aaffb78227d88f796f301130eec3823 100644 (file)
@@ -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 (file)
index 0000000..4020239
--- /dev/null
@@ -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()
index 6382cb184fdfc0b5684e7690da134e275a4bc5fb..ab91e8771d2df6b86c8279d7512272d13f1854e3 100644 (file)
@@ -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()
index b650a8c347464a2a789c5b78a33094798621c8a2..b61e5dad6fbc476cff072db66a819e6c0e2dae0b 100644 (file)
@@ -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()
index dc2586d954c819c371b5aefb94d389a224b9cf12..9ef815d8516b6308132405b4bba0560e569a866d 100644 (file)
@@ -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()
index b32ecbe4a936a4c4f9275eb396c6beab81b8a504..f574e573fbf1e920493c41c404fa310666c85ffc 100644 (file)
@@ -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 (file)
index 0000000..90cd4f2
--- /dev/null
@@ -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 (file)
index 0000000..c442125
--- /dev/null
@@ -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()
index 1d86baad5191fca4ebc9a5595139a4a21799404f..39bf810afb3cabc7eb08587840dee65be1f6a245 100644 (file)
@@ -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()
index 76eec7dca8e96572c6f3411a9e1fc4ae93c36668..1af32ddd4532d31703d9a6bca46b595ecfa33ba6 100644 (file)
@@ -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()
index 1640d94d9a56370462fb0f093f783c4d8712089a..58d2f27d127bb9058829fa312221b9f1f973c7c8 100644 (file)
@@ -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()
index ba2cc97acd4a661dd710ec56fa6c92d26c7340d2..ec9f53234101c6fb1e6881b7afb25b6e37020d09 100644 (file)
@@ -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()
index 7c9687e4a3509d6cbf35afe5d30db95a375ba42f..4ec6e78bfebc35d695310728146e0e676012750a 100644 (file)
@@ -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()
index 8dfc99644e9fb85825c09af21f04ccc4b6d0efbe..c3a8b02be0f5a7548426f0fd001340f0678e93e5 100644 (file)
@@ -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()
index 2f723b453257fd923f114b876264331274754906..3063a4eb49cf9356189c88954ae71229924f3109 100644 (file)
@@ -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 (file)
index 0000000..d738530
--- /dev/null
@@ -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 (file)
index 0000000..e1c14cf
--- /dev/null
@@ -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">
+   &quot;1&quot;
+  </annotation>
+  <annotation name="Test\\.stderr">
+   &quot;&lt;pre&gt;FAILING TEST STDERR%(cr)s
+&lt;/pre&gt;&quot;
+  </annotation>
+  <annotation name="Test\\.stdout">
+   &quot;&lt;pre&gt;FAILING TEST STDOUT%(cr)s
+&lt;/pre&gt;&quot;
+  </annotation>
+  <annotation name="qmtest\\.cause">
+   &quot;Non-zero exit_code\\.&quot;
+  </annotation>
+  <annotation name="qmtest\\.end_time">
+   &quot;[\\d.]+&quot;
+  </annotation>
+  <annotation name="qmtest\\.start_time">
+   &quot;[\\d.]+&quot;
+  </annotation>
+  <annotation name="qmtest\\.target">
+   &quot;local&quot;
+  </annotation>
+ </result>
+""" % locals()
+
+expect_no_result = """\
+ <result id="%(test_no_result_py)s" kind="test" outcome="FAIL">
+  <annotation name="Test.exit_code">
+   &quot;2&quot;
+  </annotation>
+  <annotation name="Test\\.stderr">
+   &quot;&lt;pre&gt;NO RESULT TEST STDERR%(cr)s
+&lt;/pre&gt;&quot;
+  </annotation>
+  <annotation name="Test\\.stdout">
+   &quot;&lt;pre&gt;NO RESULT TEST STDOUT%(cr)s
+&lt;/pre&gt;&quot;
+  </annotation>
+  <annotation name="qmtest\\.cause">
+   &quot;Non-zero exit_code\\.&quot;
+  </annotation>
+  <annotation name="qmtest\\.end_time">
+   &quot;[\\d.]+&quot;
+  </annotation>
+  <annotation name="qmtest\\.start_time">
+   &quot;[\\d.]+&quot;
+  </annotation>
+  <annotation name="qmtest\\.target">
+   &quot;local&quot;
+  </annotation>
+ </result>
+""" % locals()
+
+expect_pass = """\
+ <result id="%(test_pass_py)s" kind="test" outcome="PASS">
+  <annotation name="qmtest\\.end_time">
+   &quot;[\\d.]+&quot;
+  </annotation>
+  <annotation name="qmtest\\.start_time">
+   &quot;[\\d.]+&quot;
+  </annotation>
+  <annotation name="qmtest\\.target">
+   &quot;local&quot;
+  </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()
index 99a0ea5bbfbd11d3598a8d5624e689cea3f65652..8f71ac7c24a7dbb7e87d822e19b263cda86d446f 100644 (file)
@@ -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)
 {
index 9e0caa5050b8dbe311ef669ef245539c8e7de6db..d94a956ea066cc6a32a2b36ccf978048bf47cf5a 100644 (file)
@@ -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
index 8fb15bf55e6f91760f0dd29512f36a12b23dab68..6ec839d8f0cd203ae3fe1adbcfbd2f9466d23ba8 100644 (file)
@@ -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
index a5da7a81bb2979d21add06e5a155dfe5e3ee5dfd..91880bd32df89920ed3cd2068de76311719d835b 100644 (file)
@@ -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)
index 98096b7ad1148c0e5477dfd08d442ec0d1ef7901..11930e51a8a5b7af9f5a03f0f8be1e1d734b510e 100644 (file)
@@ -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='.')
 
index ef92aeaaee68d313a908fabaf9b8b0010de37ffe..ac549f6c9ee4082089d015821025ace636b5d2b8 100644 (file)
@@ -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)
index a0b234475cb9b3c17c5c06886d4078d26d82d9db..62240ee4ed96ec3a544db37aaf4e269b5d427bdf 100644 (file)
@@ -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
index a040dd42a4ef4561cfcc3d5d3321dc8912ff80cc..18be1bccb909ad148e1927e09ef790c8240d097d 100644 (file)
@@ -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");
index 03cbed34fa837b5f5531df5693698514b7232a1b..991eb233458e0bc99e5fe9fdcca570cbef17b393 100644 (file)
@@ -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")
index 18219bf3013375064b0758a6828676d220ddfbe6..a81695753b192ea21818cc694330d1fb2c50e5ef 100644 (file)
@@ -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 (file)
index 0000000..eee0e4d
--- /dev/null
@@ -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()
similarity index 79%
rename from test/symlink.py
rename to test/symlink/dangling-include.py
index ef7a55c55f821fe16f7acd725b8c89ba4ef27c4d..b5ea1e0cb514173a45690bfd9cbeb3b054de371b 100644 (file)
 __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 (file)
index 0000000..e242e61
--- /dev/null
@@ -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()
index 460401a13e64e42f722c282f23b4c68374c2140f..cec59525ef29ee71720983412f7df011baee9c1b 100644 (file)
@@ -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()