From 5aa67020bdf6d9ea168992f1ba755b653219983b Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Thu, 2 Nov 2006 16:21:36 +0000 Subject: Merged revisions 1582-1665 via svnmerge from 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 ........ --- HOWTO/release.txt | 4 +- HOWTO/subrelease.txt | 4 +- QMTest/TestRuntest.py | 74 +++- QMTest/TestSCons.py | 18 +- QMTest/classes.qmc | 1 + QMTest/scons_tdb.py | 219 +++++++---- SConstruct | 10 +- bin/ae-cvs-ci | 190 +++++++++ bin/ae-svn-ci | 226 +++++++++++ bin/caller-tree.py | 90 +++++ bin/scons-cdist | 214 +++++++---- bin/scons-diff.py | 189 +++++++++ config | 17 +- doc/SConscript | 6 +- doc/man/scons.1 | 108 +++++- runtest.py | 264 +++++++------ src/CHANGES.txt | 92 ++++- src/engine/MANIFEST.in | 1 + src/engine/SCons/ActionTests.py | 36 +- src/engine/SCons/Debug.py | 28 +- src/engine/SCons/Defaults.py | 39 +- src/engine/SCons/Environment.py | 128 +++++-- src/engine/SCons/EnvironmentTests.py | 186 +++++++-- src/engine/SCons/Memoize.py | 7 +- src/engine/SCons/Node/FS.py | 98 +++-- src/engine/SCons/Node/FSTests.py | 73 ++-- src/engine/SCons/Node/Python.py | 28 +- src/engine/SCons/Node/PythonTests.py | 38 ++ src/engine/SCons/Node/__init__.py | 3 +- src/engine/SCons/Options/ListOption.py | 4 +- src/engine/SCons/Options/ListOptionTests.py | 3 - src/engine/SCons/Options/OptionsTests.py | 13 + src/engine/SCons/Options/__init__.py | 6 +- src/engine/SCons/Platform/posix.py | 6 +- src/engine/SCons/Platform/win32.py | 33 +- src/engine/SCons/Scanner/CTests.py | 14 + src/engine/SCons/Script/Main.py | 46 ++- src/engine/SCons/Script/SConscript.py | 40 +- src/engine/SCons/Tool/as.py | 4 + src/engine/SCons/Tool/fortran.py | 2 +- src/engine/SCons/Tool/gcc.py | 2 +- src/engine/SCons/Tool/mingw.py | 3 +- src/engine/SCons/Tool/mslink.xml | 14 + src/engine/SCons/Tool/msvc.py | 12 +- src/engine/SCons/Tool/msvc.xml | 47 +++ src/engine/SCons/Tool/msvs.py | 104 +++-- src/engine/SCons/Tool/msvsTests.py | 12 + src/engine/SCons/cpp.py | 561 +++++++++++++++++++++++++++ src/engine/SCons/cppTests.py | 573 ++++++++++++++++++++++++++++ src/test_copyrights.py | 9 +- src/test_files.py | 100 +++++ src/test_setup.py | 15 +- test/AR/AR.py | 13 +- test/AR/ARCOM.py | 8 +- test/AR/ARCOMSTR.py | 8 +- test/AR/ARFLAGS.py | 12 +- test/AS/AS.py | 34 +- test/AS/ASCOM.py | 19 +- test/AS/ASCOMSTR.py | 4 +- test/AS/ASFLAGS.py | 10 +- test/AS/ASPP.py | 10 +- test/AS/ASPPCOM.py | 13 +- test/AS/ASPPCOMSTR.py | 4 +- test/AS/ASPPFLAGS.py | 8 +- test/Actions/actions.py | 18 +- test/Actions/pre-post.py | 4 +- test/Alias/Alias.py | 22 +- test/BadBuilder.py | 38 +- test/BitKeeper/BITKEEPERCOM.py | 14 +- test/BitKeeper/BITKEEPERCOMSTR.py | 4 +- test/BuildDir/BuildDir.py | 15 + test/BuildDir/Sconscript-build_dir.py | 6 + test/BuildDir/errors.py | 15 +- test/BuildDir/nested-sconscripts.py | 64 ++++ test/BuildDir/reflect.py | 28 +- test/CC/CC.py | 24 +- test/CC/CCCOM.py | 4 +- test/CC/CCCOMSTR.py | 4 +- test/CC/CCFLAGS.py | 3 + test/CC/SHCC.py | 12 +- test/CC/SHCCCOM.py | 4 +- test/CC/SHCCCOMSTR.py | 4 +- test/CC/SHCCFLAGS.py | 13 +- test/CFILESUFFIX.py | 6 +- test/CPPDEFINES.py | 3 + test/CPPFLAGS.py | 22 +- test/CPPSUFFIXES.py | 38 +- test/CVS.py | 9 +- test/CVSCOM.py | 14 +- test/CVSCOMSTR.py | 4 +- test/CXX/CXX.py | 18 +- test/CXX/CXXCOM.py | 4 +- test/CXX/CXXCOMSTR.py | 4 +- test/CXX/CXXFILESUFFIX.py | 6 +- test/CXX/SHCXX.py | 6 +- test/CXX/SHCXXCOM.py | 4 +- test/CXX/SHCXXCOMSTR.py | 4 +- test/CXX/SHCXXFLAGS.py | 15 +- test/CacheDir.py | 324 ---------------- test/CacheDir/BuildDir.py | 153 ++++++++ test/CacheDir/CacheDir.py | 157 ++++++++ test/CacheDir/SideEffect.py | 107 ++++++ test/CacheDir/debug.py | 177 +++++++++ test/CacheDir/multi-targets.py | 70 ++++ test/CacheDir/source-scanner.py | 84 ++++ test/Case.py | 2 + test/Command.py | 21 +- test/CommandGenerator.py | 4 +- test/Configure/CONFIGUREDIR.py | 4 +- test/Configure/CONFIGURELOG.py | 8 +- test/Configure/Configure.py | 36 +- test/DSUFFIXES.py | 38 +- test/DVIPDF/DVIPDF.py | 14 +- test/DVIPDF/DVIPDFCOM.py | 6 +- test/DVIPDF/DVIPDFCOMSTR.py | 6 +- test/DVIPDF/DVIPDFFLAGS.py | 14 +- test/DVIPS/DVIPS.py | 14 +- test/DVIPS/DVIPSFLAGS.py | 14 +- test/DVIPS/PSCOM.py | 6 +- test/DVIPS/PSCOMSTR.py | 6 +- test/Default.py | 54 +-- test/Depends.py | 18 +- test/ENV.py | 10 +- test/ESCAPE.py | 4 +- test/Environment.py | 6 +- test/Execute.py | 20 +- test/Fortran/F77.py | 20 +- test/Fortran/F77COM.py | 20 +- test/Fortran/F77COMSTR.py | 6 +- test/Fortran/F77FLAGS.py | 14 +- test/Fortran/F90.py | 16 +- test/Fortran/F90COM.py | 20 +- test/Fortran/F90COMSTR.py | 6 +- test/Fortran/F90FLAGS.py | 16 +- test/Fortran/F95.py | 16 +- test/Fortran/F95COM.py | 20 +- test/Fortran/F95COMSTR.py | 6 +- test/Fortran/F95FLAGS.py | 16 +- test/Fortran/FORTRAN.py | 14 +- test/Fortran/FORTRANCOM.py | 10 +- test/Fortran/FORTRANCOMSTR.py | 6 +- test/Fortran/FORTRANFLAGS.py | 14 +- test/Fortran/FORTRANMODDIR.py | 4 +- test/Fortran/FORTRANSUFFIXES.py | 38 +- test/Fortran/SHF77.py | 14 +- test/Fortran/SHF77COM.py | 16 +- test/Fortran/SHF77COMSTR.py | 6 +- test/Fortran/SHF77FLAGS.py | 12 +- test/Fortran/SHF90.py | 12 +- test/Fortran/SHF90COM.py | 16 +- test/Fortran/SHF90COMSTR.py | 6 +- test/Fortran/SHF90FLAGS.py | 14 +- test/Fortran/SHF95.py | 12 +- test/Fortran/SHF95COM.py | 16 +- test/Fortran/SHF95COMSTR.py | 6 +- test/Fortran/SHF95FLAGS.py | 14 +- test/Fortran/SHFORTRAN.py | 10 +- test/Fortran/SHFORTRANCOM.py | 8 +- test/Fortran/SHFORTRANCOMSTR.py | 6 +- test/Fortran/SHFORTRANFLAGS.py | 12 +- test/Fortran/USE-MODULE.py | 4 +- test/Fortran/module-subdir.py | 115 ++++++ test/Ghostscript/GS.py | 10 +- test/Ghostscript/GSCOM.py | 6 +- test/Ghostscript/GSCOMSTR.py | 6 +- test/Ghostscript/GSFLAGS.py | 6 +- test/IDL/MIDLCOM.py | 6 +- test/IDL/MIDLCOMSTR.py | 6 +- test/Ignore.py | 16 +- test/Install/Install.py | 18 +- test/Install/InstallAs.py | 16 +- test/Install/directories.py | 95 +++++ test/Java/JAR.py | 16 +- test/Java/JARCOM.py | 4 +- test/Java/JARCOMSTR.py | 4 +- test/Java/JAVAC.py | 16 +- test/Java/JAVACCOM.py | 4 +- test/Java/JAVACCOMSTR.py | 4 +- test/Java/JAVAH.py | 12 +- test/Java/JAVAHCOM.py | 4 +- test/Java/JAVAHCOMSTR.py | 4 +- test/Java/RMIC.py | 12 +- test/Java/RMICCOM.py | 4 +- test/Java/RMICCOMSTR.py | 4 +- test/LEX/LEX.py | 10 +- test/LEX/LEXCOM.py | 6 +- test/LEX/LEXCOMSTR.py | 6 +- test/LEX/LEXFLAGS.py | 8 +- test/LIBPATH.py | 8 + test/LIBPREFIXES.py | 4 + test/LIBS.py | 4 +- test/LIBSUFFIXES.py | 4 + test/LINK/LINK.py | 10 +- test/LINK/LINKCOM.py | 4 +- test/LINK/LINKCOMSTR.py | 4 +- test/LINK/LINKFLAGS.py | 10 +- test/LINK/SHLINK.py | 6 +- test/LINK/SHLINKCOM.py | 6 +- test/LINK/SHLINKCOMSTR.py | 10 +- test/LINK/SHLINKFLAGS.py | 6 +- test/Library.py | 6 + test/M4/M4.py | 8 +- test/M4/M4COM.py | 6 +- test/M4/M4COMSTR.py | 6 +- test/MSVC/PCHCOM.py | 6 +- test/MSVC/PCHCOMSTR.py | 6 +- test/MSVC/RCCOM.py | 4 +- test/MSVC/RCCOMSTR.py | 4 +- test/MSVC/generate-rc.py | 70 ++++ test/MSVC/msvc.py | 36 +- test/MSVS/common-prefix.py | 82 +++- test/MSVS/runfile.py | 2 +- test/MSVS/vs-6.0-files.py | 4 +- test/MSVS/vs-7.0-files.py | 6 +- test/MSVS/vs-7.1-files.py | 6 +- test/MSVS/vs-8.0-files.py | 6 +- test/MinGW/RCCOM.py | 4 +- test/MinGW/RCCOMSTR.py | 4 +- test/NodeOps.py | 11 +- test/Object.py | 4 + test/Options/BoolOption.py | 15 +- test/Options/EnumOption.py | 33 +- test/Options/ListOption.py | 60 +-- test/Options/PackageOption.py | 13 +- test/Options/PathOption.py | 107 +++--- test/ParseConfig.py | 10 +- test/ParseDepends.py | 8 +- test/Perforce/P4COM.py | 14 +- test/Perforce/P4COMSTR.py | 4 +- test/Perforce/Perforce.py | 17 +- test/Precious.py | 11 +- test/Program-j.py | 9 + test/Program.py | 38 ++ test/QT/QTFLAGS.py | 6 +- test/QT/moc-from-header.py | 6 + test/QT/warnings.py | 17 +- test/RANLIB/RANLIB.py | 10 +- test/RANLIB/RANLIBCOM.py | 8 +- test/RANLIB/RANLIBCOMSTR.py | 16 +- test/RANLIB/RANLIBFLAGS.py | 13 +- test/RCS/RCS_COCOM.py | 14 +- test/RCS/RCS_COCOMSTR.py | 4 +- test/RCS/diskcheck.py | 5 +- test/RCS/implicit.py | 2 + test/RPATH.py | 1 + test/Repository/CPPPATH.py | 2 + test/Repository/LIBPATH.py | 4 + test/Repository/M4.py | 7 +- test/Repository/Program.py | 21 + test/Repository/StaticLibrary.py | 12 + test/Repository/absolute-path.py | 6 + test/Repository/include.py | 4 + test/Repository/link-object.py | 8 + test/Repository/multi-dir.py | 2 + test/Repository/no-SConsignFile.py | 1 + test/Repository/no-repository.py | 6 + test/Repository/signature-order.py | 2 + test/Repository/top-level-path.py | 6 + test/Repository/variants.py | 8 + test/Repository/within-repository.py | 12 + test/Rpcgen/RPCGEN.py | 7 +- test/Rpcgen/RPCGENCLIENTFLAGS.py | 6 +- test/Rpcgen/RPCGENFLAGS.py | 6 +- test/Rpcgen/RPCGENHEADERFLAGS.py | 6 +- test/Rpcgen/RPCGENSERVICEFLAGS.py | 6 +- test/Rpcgen/RPCGENXDRFLAGS.py | 6 +- test/SCCS/SCCSCOM.py | 14 +- test/SCCS/SCCSCOMSTR.py | 4 +- test/SCCS/diskcheck.py | 7 +- test/SConscript.py | 422 -------------------- test/SConscript/SConscript.py | 219 +++++++++++ test/SConscript/SConscriptChdir.py | 85 +++++ test/SConscript/env.py | 90 +++++ test/SConscript/src_dir.py | 97 +++++ test/SConscript/variables.py | 169 ++++++++ test/SConscript/white-space.py | 50 +++ test/SConsignFile.py | 10 +- test/SHELL.py | 4 +- test/SHLIBPREFIX.py | 1 + test/SHLIBSUFFIX.py | 1 + test/SPAWN.py | 10 +- test/SWIG/SWIG.py | 13 +- test/SWIG/SWIGCOM.py | 6 +- test/SWIG/SWIGCOMSTR.py | 6 +- test/Scanner-exception.py | 115 ------ test/Scanner.py | 315 --------------- test/Scanner/Scanner.py | 240 ++++++++++++ test/Scanner/empty-implicit.py | 81 ++++ test/Scanner/exception.py | 115 ++++++ test/Scanner/generated.py | 427 +++++++++++++++++++++ test/Scanner/multi-env.py | 116 ++++++ test/Scanner/parallel-rescan.py | 72 ++++ test/Scanner/scan-once.py | 94 +++++ test/SharedLibrary.py | 7 + test/TAR/TAR.py | 10 +- test/TAR/TARCOM.py | 4 +- test/TAR/TARCOMSTR.py | 6 +- test/TAR/TARFLAGS.py | 12 +- test/TARGET-dir.py | 3 + test/TEX/LATEX.py | 10 +- test/TEX/LATEXCOM.py | 4 +- test/TEX/LATEXCOMSTR.py | 4 +- test/TEX/LATEXFLAGS.py | 12 +- test/TEX/PDFLATEX.py | 10 +- test/TEX/PDFLATEXCOM.py | 4 +- test/TEX/PDFLATEXCOMSTR.py | 4 +- test/TEX/PDFLATEXFLAGS.py | 12 +- test/TEX/PDFTEX.py | 10 +- test/TEX/PDFTEXCOM.py | 4 +- test/TEX/PDFTEXCOMSTR.py | 4 +- test/TEX/PDFTEXFLAGS.py | 12 +- test/TEX/TEX.py | 10 +- test/TEX/TEXCOM.py | 4 +- test/TEX/TEXCOMSTR.py | 4 +- test/TEX/TEXFLAGS.py | 12 +- test/Value.py | 30 +- test/YACC/YACC.py | 10 +- test/YACC/YACCCOM.py | 6 +- test/YACC/YACCCOMSTR.py | 6 +- test/YACC/YACCFLAGS.py | 8 +- test/YACC/YACCHFILESUFFIX.py | 6 +- test/YACC/YACCHXXFILESUFFIX.py | 6 +- test/ZIP/ZIP.py | 6 +- test/ZIP/ZIPCOM.py | 4 +- test/ZIP/ZIPCOMSTR.py | 6 +- test/bad-variables.py | 25 +- test/builderrors.py | 78 +++- test/chdir.py | 16 +- test/dependency-cycle.py | 1 + test/errors.py | 20 +- test/exceptions.py | 23 +- test/expansion.py | 8 + test/explain.py | 144 ++++--- test/gnutools.py | 12 +- test/ignore-command.py | 16 +- test/implicit-cache/GetOption.py | 53 +++ test/implicit-cache/SetOption.py | 70 ++++ test/implicit-cache/basic.py | 317 +++++++++++++++ test/import.py | 45 ++- test/long-lines.py | 6 + test/multi.py | 11 +- test/multiline.py | 9 +- test/option--.py | 8 +- test/option--D.py | 6 +- test/option--Q.py | 12 +- test/option--U.py | 6 +- test/option--Y.py | 20 + test/option--cs.py | 36 +- test/option--debug.py | 55 +-- test/option--implicit-cache.py | 374 ------------------ test/option--max-drift.py | 23 +- test/option-c.py | 26 +- test/option-i.py | 8 +- test/option-j.py | 20 +- test/option-k.py | 22 +- test/option-n.py | 16 +- test/option-q.py | 6 +- test/option-s.py | 6 +- test/option/debug-dtree.py | 2 + test/option/debug-findlibs.py | 13 +- test/option/debug-includes.py | 2 + test/option/debug-stacktrace.py | 21 + test/option/debug-stree.py | 2 + test/option/debug-time.py | 2 + test/option/debug-tree.py | 2 + test/option/profile.py | 24 +- test/overrides.py | 14 +- test/parallel-rescan.py | 72 ---- test/redirection.py | 12 +- test/runtest/aegis/batch-output.py | 60 +++ test/runtest/baseline/combined.py | 28 +- test/runtest/baseline/fail.py | 4 +- test/runtest/baseline/no_result.py | 4 +- test/runtest/baseline/pass.py | 4 +- test/runtest/fallback.py | 104 +++++ test/runtest/noqmtest.py | 94 +++++ test/runtest/print_time.py | 29 +- test/runtest/python.py | 42 +- test/runtest/simple/combined.py | 28 +- test/runtest/simple/fail.py | 4 +- test/runtest/simple/no_result.py | 4 +- test/runtest/simple/pass.py | 4 +- test/runtest/src.py | 21 +- test/runtest/testlistfile.py | 77 ++++ test/runtest/xml/output.py | 191 ++++++++++ test/same-name.py | 3 + test/scan-once.py | 497 ------------------------ test/sconsign/script.py | 8 + test/signature-order.py | 4 + test/silent-command.py | 18 +- test/special-filenames.py | 10 +- test/srcchange.py | 12 +- test/strfunction.py | 26 +- test/subclassing.py | 2 + test/subdir.py | 6 +- test/subdivide.py | 6 + test/symlink.py | 72 ---- test/symlink/BuildDir.py | 64 ++++ test/symlink/dangling-include.py | 59 +++ test/symlink/dangling-source.py | 53 +++ test/up-to-date.py | 17 +- 401 files changed, 9755 insertions(+), 4284 deletions(-) create mode 100755 bin/ae-cvs-ci create mode 100755 bin/ae-svn-ci create mode 100644 bin/caller-tree.py create mode 100644 bin/scons-diff.py create mode 100644 src/engine/SCons/cpp.py create mode 100644 src/engine/SCons/cppTests.py create mode 100644 src/test_files.py create mode 100644 test/BuildDir/nested-sconscripts.py delete mode 100644 test/CacheDir.py create mode 100644 test/CacheDir/BuildDir.py create mode 100644 test/CacheDir/CacheDir.py create mode 100644 test/CacheDir/SideEffect.py create mode 100644 test/CacheDir/debug.py create mode 100644 test/CacheDir/multi-targets.py create mode 100644 test/CacheDir/source-scanner.py create mode 100644 test/Fortran/module-subdir.py create mode 100644 test/Install/directories.py create mode 100644 test/MSVC/generate-rc.py delete mode 100644 test/SConscript.py create mode 100644 test/SConscript/SConscript.py create mode 100644 test/SConscript/SConscriptChdir.py create mode 100644 test/SConscript/env.py create mode 100644 test/SConscript/src_dir.py create mode 100644 test/SConscript/variables.py create mode 100644 test/SConscript/white-space.py delete mode 100644 test/Scanner-exception.py delete mode 100644 test/Scanner.py create mode 100644 test/Scanner/Scanner.py create mode 100644 test/Scanner/empty-implicit.py create mode 100644 test/Scanner/exception.py create mode 100644 test/Scanner/generated.py create mode 100644 test/Scanner/multi-env.py create mode 100644 test/Scanner/parallel-rescan.py create mode 100644 test/Scanner/scan-once.py create mode 100644 test/implicit-cache/GetOption.py create mode 100644 test/implicit-cache/SetOption.py create mode 100644 test/implicit-cache/basic.py delete mode 100644 test/option--implicit-cache.py delete mode 100644 test/parallel-rescan.py create mode 100644 test/runtest/aegis/batch-output.py create mode 100644 test/runtest/fallback.py create mode 100644 test/runtest/noqmtest.py create mode 100644 test/runtest/testlistfile.py create mode 100644 test/runtest/xml/output.py delete mode 100644 test/scan-once.py delete mode 100644 test/symlink.py create mode 100644 test/symlink/BuildDir.py create mode 100644 test/symlink/dangling-include.py create mode 100644 test/symlink/dangling-source.py diff --git a/HOWTO/release.txt b/HOWTO/release.txt index 397033a..88f9352 100644 --- a/HOWTO/release.txt +++ b/HOWTO/release.txt @@ -93,8 +93,8 @@ Things to do to release a new X.Y version of SCons: aecp rpm/scons.spec.in vi rpm/scons.spec.in - aecp src/test_setup.py - vi src/test_setup.py + aecp QMTest/TestSCons.py + vi QMTest/TestSCons.py # Read through and update the README files if necessary [optional] aecp README diff --git a/HOWTO/subrelease.txt b/HOWTO/subrelease.txt index fb799e6..6826c81 100644 --- a/HOWTO/subrelease.txt +++ b/HOWTO/subrelease.txt @@ -39,8 +39,8 @@ Things to do to release a new X.Y.Z version of SCons: aecp src/setup.py vi src/setup.py - aecp src/test_setup.py - vi src/test_setup.py + aecp QMTest/TestSCons.py + vi QMTest/TestSCons.py # Read through and update the README files if necessary [optional] aecp README diff --git a/QMTest/TestRuntest.py b/QMTest/TestRuntest.py index a4bcd05..9452746 100644 --- a/QMTest/TestRuntest.py +++ b/QMTest/TestRuntest.py @@ -27,9 +27,11 @@ from TestCommon import __all__ __all__.extend([ 'TestRuntest', 'python', + '_python_', ]) python = python_executable +_python_ = '"' + python_executable + '"' failing_test_template = """\ @@ -53,6 +55,22 @@ sys.stderr.write('PASSING TEST STDERR\\n') sys.exit(0) """ +fake_scons_py = """ +__version__ = '1.2.3' +__build__ = 'D123' +__buildsys__ = 'fake_system' +__date__ = 'Jan 1 1970' +__developer__ = 'Anonymous' +""" + +fake___init___py = """ +__version__ = '4.5.6' +__build__ = 'D456' +__buildsys__ = 'another_fake_system' +__date__ = 'Dec 31 1999' +__developer__ = 'John Doe' +""" + class TestRuntest(TestCommon): """Class for testing the runtest.py script. @@ -91,15 +109,28 @@ class TestRuntest(TestCommon): kw['match'] = match_exact if not kw.has_key('workdir'): kw['workdir'] = '' + + try: + noqmtest = kw['noqmtest'] + except KeyError: + noqmtest = 0 + else: + del kw['noqmtest'] + orig_cwd = os.getcwd() apply(TestCommon.__init__, [self], kw) + + if not noqmtest: + qmtest_py = self.where_is('qmtest.py') + if not qmtest_py: + self.skip_test("Could not find 'qmtest.py'; skipping test(s).\n") things_to_copy = [ 'runtest.py', 'QMTest', ] - dirs = [orig_cwd] + dirs = [os.environ.get('SCONS_RUNTEST_DIR', orig_cwd)] spe = os.environ.get('SCONS_SOURCE_PATH_EXECUTABLE', orig_cwd) for d in string.split(spe, os.pathsep): @@ -127,6 +158,47 @@ class TestRuntest(TestCommon): os.environ['PYTHONPATH'] = '' os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = '' + def skip_test(self, message="Skipping test.\n"): + """Skips a test. + + Proper test-skipping behavior is dependent on whether we're being + executed as part of development of a change under Aegis. + + Technically, skipping a test is a NO RESULT, but Aegis will + treat that as a test failure and prevent the change from going + to the next step. We don't want to force anyone using Aegis + to have to install absolutely every tool used by the tests, + so we actually report to Aegis that a skipped test has PASSED + so that the workflow isn't held up. + """ + if message: + sys.stdout.write(message) + sys.stdout.flush() + devdir = os.popen("aesub '$dd' 2>/dev/null", "r").read()[:-1] + intdir = os.popen("aesub '$intd' 2>/dev/null", "r").read()[:-1] + if devdir and self._cwd[:len(devdir)] == devdir or \ + intdir and self._cwd[:len(intdir)] == intdir: + # We're under the development directory for this change, + # so this is an Aegis invocation; pass the test (exit 0). + self.pass_test() + else: + # skip=1 means skip this function when showing where this + # result came from. They only care about the line where the + # script called test.skip_test(), not the line number where + # we call test.no_result(). + self.no_result(skip=1) + + def write_fake_scons_source_tree(self): + os.mkdir('src') + os.mkdir('src/script') + self.write('src/script/scons.py', fake_scons_py) + + os.mkdir('src/engine') + os.mkdir('src/engine/SCons') + self.write('src/engine/SCons/__init__.py', fake___init___py) + os.mkdir('src/engine/SCons/Script') + self.write('src/engine/SCons/Script/__init__.py', fake___init___py) + def write_failing_test(self, name): self.write(name, failing_test_template) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 0904d31..de15526 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -24,6 +24,14 @@ import sys from TestCommon import * from TestCommon import __all__ +# Some tests which verify that SCons has been packaged properly need to +# look for specific version file names. Replicating the version number +# here provides independent verification that what we packaged conforms +# to what we expect. (If we derived the version number from the same +# data driving the build we might miss errors if the logic breaks.) + +SConsVersion = '0.96.92' + __all__.extend([ 'TestSCons', 'python', '_exe', @@ -36,6 +44,7 @@ __all__.extend([ 'TestSCons', ]) python = python_executable +_python_ = '"' + python_executable + '"' _exe = exe_suffix _obj = obj_suffix _shobj = shobj_suffix @@ -105,6 +114,8 @@ class TestSCons(TestCommon): initializations. """ + scons_version = SConsVersion + def __init__(self, **kw): """Initialize an SCons testing object. @@ -398,12 +409,12 @@ void my_qt_symbol(const char *arg) { } """) - self.write(['qt', 'lib', 'SConstruct'], r""" + self.write([dir, 'lib', 'SConstruct'], r""" env = Environment() -env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) +env.SharedLibrary( 'myqt', 'my_qobject.cpp' ) """) - self.run(chdir = self.workpath('qt', 'lib'), + self.run(chdir = self.workpath(dir, 'lib'), arguments = '.', stderr = noisy_ar, match = self.match_re_dotall) @@ -412,6 +423,7 @@ env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) self.QT_LIB = 'myqt' self.QT_MOC = '%s %s' % (python, self.workpath(dir, 'bin', 'mymoc.py')) self.QT_UIC = '%s %s' % (python, self.workpath(dir, 'bin', 'myuic.py')) + self.QT_LIB_DIR = self.workpath(dir, 'lib') def Qt_create_SConstruct(self, place): if type(place) is type([]): diff --git a/QMTest/classes.qmc b/QMTest/classes.qmc index 73e3df3..88de061 100644 --- a/QMTest/classes.qmc +++ b/QMTest/classes.qmc @@ -8,4 +8,5 @@ + diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py index 145c2a7..e0d7683 100644 --- a/QMTest/scons_tdb.py +++ b/QMTest/scons_tdb.py @@ -46,9 +46,13 @@ from qm.test import suite from qm.test.result import Result from qm.test.file_result_stream import FileResultStream from qm.test.classes.text_result_stream import TextResultStream +from qm.test.classes.xml_result_stream import XMLResultStream from qm.test.directory_suite import DirectorySuite from qm.extension import get_extension_class_name, get_class_arguments_as_dictionary -import os, dircache + +import dircache +import os +import imp if sys.platform == 'win32': console = 'con' @@ -128,62 +132,145 @@ def check_exit_status(result, prefix, desc, status): return True -# XXX I'd like to annotate the overall test run with the following -# information about the Python version, SCons version, and environment. -# Not sure how to do that yet; ask Stefan. -# -# sys_keys = ['byteorder', 'exec_prefix', 'executable', 'maxint', 'maxunicode', 'platform', 'prefix', 'version', 'version_info'] - -# " <%s>" % tag -# " %s" % module.__version__ -# " %s" % module.__build__ -# " %s" % module.__buildsys__ -# " %s" % module.__date__ -# " %s" % module.__developer__ -# " " % tag - -# " " -# print_version_info("script", scons) -# print_version_info("engine", 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.") diff --git a/SConstruct b/SConstruct index 49cc6ff..0fdacd5 100644 --- a/SConstruct +++ b/SConstruct @@ -913,12 +913,14 @@ for p in [ scons ]: env.Command(local_targets, build_src_files, commands) scons_LICENSE = os.path.join(local, 'scons-LICENSE') - env.SCons_revision(scons_LICENSE, 'LICENSE-local') - local_targets.append(scons_LICENSE) + l = env.SCons_revision(scons_LICENSE, 'LICENSE-local') + local_targets.append(l) + Local(l) scons_README = os.path.join(local, 'scons-README') - env.SCons_revision(scons_README, 'README-local') - local_targets.append(scons_README) + l = env.SCons_revision(scons_README, 'README-local') + local_targets.append(l) + Local(l) if gzip: env.Command(local_tar_gz, diff --git a/bin/ae-cvs-ci b/bin/ae-cvs-ci new file mode 100755 index 0000000..3dcc287 --- /dev/null +++ b/bin/ae-cvs-ci @@ -0,0 +1,190 @@ +# +# aegis - project change supervisor +# Copyright (C) 2004 Peter Miller; +# All rights reserved. +# +# As a specific exception to the GPL, you are allowed to copy +# this source file into your own project and modify it, without +# releasing your project under the GPL, unless there is some other +# file or condition which would require it. +# +# MANIFEST: shell script to commit changes to CVS +# +# It is assumed that your CVSROOT and CVS_RSH environment variables have +# already been set appropriately. +# +# This script is expected to be run as by integrate_pass_notify_command +# and as such the baseline has already assumed the shape asked for by +# the change. +# +# integrate_pass_notify_command = +# "$bin/ae-cvs-ci $project $change"; +# +# Alternatively, you may wish to tailor this script to the individual +# needs of your project. Make it a source file, e.g. "etc/ae-cvs-ci.sh" +# and then use the following: +# +# integrate_pass_notify_command = +# "$sh ${s etc/ae-cvs-ci} $project $change"; +# + +USAGE="Usage: $0 " + +PRINT="echo" +EXECUTE="eval" + +while getopts "hnq" FLAG +do + case ${FLAG} in + h ) + echo "${USAGE}" + exit 0 + ;; + n ) + EXECUTE=":" + ;; + q ) + PRINT=":" + ;; + * ) + echo "$0: unknown option ${FLAG}" >&2 + exit 1 + ;; + esac +done + +shift `expr ${OPTIND} - 1` + +case $# in +2) + project=$1 + change=$2 + ;; +*) + echo "${USAGE}" 1>&2 + exit 1 + ;; +esac + +here=`pwd` + +AEGIS_PROJECT=$project +export AEGIS_PROJECT +AEGIS_CHANGE=$change +export AEGIS_CHANGE + +module=`echo $project | sed 's|[.].*||'` + +baseline=`aegis -cd -bl` + +if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi + +TMP=${TMPDIR}/ae-cvs-ci.$$ +mkdir ${TMP} +cd ${TMP} + +PWD=`pwd` +if test X${PWD} != X${TMP}; then + echo "$0: ended up in ${PWD}, not ${TMP}" >&2 + exit 1 +fi + +fail() +{ + set +x + cd $here + rm -rf ${TMP} + echo "FAILED" 1>&2 + exit 1 +} +trap "fail" 1 2 3 15 + +Command() +{ + ${PRINT} "$*" + ${EXECUTE} "$*" +} + +# +# Create a new CVS work area. +# +# Note: this assumes the module is checked-out into a directory of the +# same name. Is there a way to ask CVS where is is going to put a +# modules, so we can always get the "cd" right? +# +${PRINT} cvs co $module +${EXECUTE} cvs co $module > LOG 2>&1 +if test $? -ne 0; then cat LOG; fail; fi +${EXECUTE} cd $module + +# +# Now we need to extract the sources from Aegis and drop them into the +# CVS work area. There are two ways to do this. +# +# The first way is to use the generated tarball. +# This has the advantage that it has the Makefile.in file in it, and +# will work immediately. +# +# The second way is to use aetar, which will give exact sources, and +# omit all derived files. This will *not* include the Makefile.in, +# and so will not be readily compilable. +# +# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - +aetar -send -o - | tar xzf - + +# +# If any new directories have been created we will need to add them +# to CVS before we can add the new files which we know are in them, +# or they would not have been created. Do this only if the -n option +# isn't used, because if it is, we won't have actually checked out the +# source and we'd erroneously report that all of them need to be added. +# +if test "X${EXECUTE}" != "X:" +then + find . \( -name CVS -o -name Attic \) -prune -o -type d -print | + xargs --max-args=1 | + while read dir + do + if [ ! -d $dir/CVS ] + then + Command cvs add $dir + fi + done +fi + +# +# Use the Aegis meta-data to perform some CVS commands that CVS can't +# figure out for itself. +# +aegis -l cf -unf | sed 's| -> [0-9][0-9.]*||' | +while read usage action rev filename +do + if test "x$filename" = "x" + then + filename="$rev" + fi + case $action in + create) + Command cvs add $filename + ;; + remove) + Command rm -f $filename + Command cvs remove $filename + ;; + *) + ;; + esac +done + +# +# Now commit all the changes. +# +message=`aesub '${version} - ${change description}'` +Command cvs -q commit -m \"$message\" + +# +# All done. Clean up and go home. +# +cd $here +rm -rf ${TMP} +exit 0 diff --git a/bin/ae-svn-ci b/bin/ae-svn-ci new file mode 100755 index 0000000..e5b81a4 --- /dev/null +++ b/bin/ae-svn-ci @@ -0,0 +1,226 @@ +# +# aegis - project change supervisor +# Copyright (C) 2004 Peter Miller; +# All rights reserved. +# +# As a specific exception to the GPL, you are allowed to copy +# this source file into your own project and modify it, without +# releasing your project under the GPL, unless there is some other +# file or condition which would require it. +# +# MANIFEST: shell script to commit changes to Subversion +# +# This script is expected to be run by the integrate_pass_notify_command +# and as such the baseline has already assumed the shape asked for by +# the change. +# +# integrate_pass_notify_command = +# "$bin/ae-svn-ci $project $change http://svn.site.com/svn/trunk --username svn_user"; +# +# Alternatively, you may wish to tailor this script to the individual +# needs of your project. Make it a source file, e.g. "etc/ae-svn-ci.sh" +# and then use the following: +# +# integrate_pass_notify_command = +# "$sh ${s etc/ae-svn-ci} $project $change http://svn.site.com/svn/trunk --username svn_user"; +# + +USAGE="Usage: $0 [-hnq] []" + +PRINT="echo" +EXECUTE="eval" + +while getopts "hnq" FLAG +do + case ${FLAG} in + h ) + echo "${USAGE}" + exit 0 + ;; + n ) + EXECUTE=":" + ;; + q ) + PRINT=":" + ;; + * ) + echo "$0: unknown option ${FLAG}" >&2 + exit 1 + ;; + esac +done + +shift `expr ${OPTIND} - 1` + +case $# in +[012]) + echo "${USAGE}" 1>&2 + exit 1 + ;; +*) + project=$1 + change=$2 + svn_url=$3 + shift 3 + svn_co_flags=$* + ;; +esac + +here=`pwd` + +AEGIS_PROJECT=$project +export AEGIS_PROJECT +AEGIS_CHANGE=$change +export AEGIS_CHANGE + +module=`echo $project | sed 's|[.].*||'` + +baseline=`aegis -cd -bl` + +if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi + +TMP=${TMPDIR}/ae-svn-ci.$$ +mkdir ${TMP} +cd ${TMP} + +PWD=`pwd` +if test X${PWD} != X${TMP}; then + echo "$0: ended up in ${PWD}, not ${TMP}" >&2 + exit 1 +fi + +fail() +{ + set +x + cd $here + rm -rf ${TMP} + echo "FAILED" 1>&2 + exit 1 +} +trap "fail" 1 2 3 15 + +Command() +{ + ${PRINT} "$*" + ${EXECUTE} "$*" +} + +# +# Create a new Subversion work area. +# +# Note: this assumes the module is checked-out into a directory of the +# same name. Is there a way to ask Subversion where it is going to put a +# module, so we can always get the "cd" right? +# +${PRINT} svn co $svn_url $module $svn_co_flags +${EXECUTE} svn co $svn_url $module $svn_co_flags > LOG 2>&1 +if test $? -ne 0; then cat LOG; fail; fi +${EXECUTE} cd $module + +# +# Now we need to extract the sources from Aegis and drop them into the +# Subversion work area. There are two ways to do this. +# +# The first way is to use the generated tarball. +# This has the advantage that it has the Makefile.in file in it, and +# will work immediately. +# +# The second way is to use aetar, which will give exact sources, and +# omit all derived files. This will *not* include the Makefile.in, +# and so will not be readily compilable. +# +# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf - +aetar -send -o - | tar xzf - + +# +# If any new directories have been created we will need to add them +# to Subversion before we can add the new files which we know are in them, +# or they would not have been created. Do this only if the -n option +# isn't used, because if it is, we won't have actually checked out the +# source and we'd erroneously report that all of them need to be added. +# +if test "X${EXECUTE}" != "X:" +then + find . -name .svn -prune -o -type d -print | + xargs --max-args=1 | + while read dir + do + if [ ! -d $dir/.svn ] + then + Command svn add -N $dir + fi + done +fi + +# +# Use the Aegis meta-data to perform some commands that Subversion can't +# figure out for itself. We use an inline "aer" report script to identify +# when a remove-create pair are actually due to a move. +# +aegis -rpt -nph -f - <<_EOF_ | +auto cs; +cs = project[project_name()].state.branch.change[change_number()]; + +columns({width = 1000;}); + +auto file, moved; +for (file in cs.src) +{ + if (file.move != "") + moved[file.move] = 1; +} + +auto action; +for (file in cs.src) +{ + if (file.action == "remove" && file.move != "") + action = "move"; + else + action = file.action; + /* + * Suppress printing of any files created as the result of a move. + * These are printed as the destination when printing the line for + * the file that was *removed* as a result of the move. + */ + if (action != "create" || ! moved[file.file_name]) + print(sprintf("%s %s \\"%s\\" \\"%s\\"", file.usage, action, file.file_name, file.move)); +} +_EOF_ +while read line +do + eval set -- "$line" + usage="$1" + action="$2" + srcfile="$3" + dstfile="$4" + case $action in + create) + Command svn add $srcfile + ;; + remove) + Command rm -f $srcfile + Command svn remove $srcfile + ;; + move) + Command mv $dstfile $dstfile.move + Command svn move $srcfile $dstfile + Command cp $dstfile.move $dstfile + Command rm -f $dstfile.move + ;; + *) + ;; + esac +done + +# +# Now commit all the changes. +# +message=`aesub '${version} - ${change description}'` +Command svn commit -m \"$message\" + +# +# All done. Clean up and go home. +# +cd $here +rm -rf ${TMP} +exit 0 diff --git a/bin/caller-tree.py b/bin/caller-tree.py new file mode 100644 index 0000000..5d907b8 --- /dev/null +++ b/bin/caller-tree.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# +# Quick script to process the *summary* output from SCons.Debug.caller() +# and print indented calling trees with call counts. +# +# The way to use this is to add something like the following to a function +# for which you want information about who calls it and how many times: +# +# from SCons.Debug import caller +# caller(0, 1, 2, 3, 4, 5) +# +# Each integer represents how many stack frames back SCons will go +# and capture the calling information, so in the above example it will +# capture the calls six levels up the stack in a central dictionary. +# +# At the end of any run where SCons.Debug.caller() is used, SCons will +# print a summary of the calls and counts that looks like the following: +# +# Callers of Node/__init__.py:629(calc_signature): +# 1 Node/__init__.py:683(calc_signature) +# Callers of Node/__init__.py:676(gen_binfo): +# 6 Node/FS.py:2035(current) +# 1 Node/__init__.py:722(get_bsig) +# +# If you cut-and-paste that summary output and feed it to this script +# on standard input, it will figure out how these entries hook up and +# print a calling tree for each one looking something like: +# +# Node/__init__.py:676(gen_binfo) +# Node/FS.py:2035(current) 6 +# Taskmaster.py:253(make_ready_current) 18 +# Script/Main.py:201(make_ready) 18 +# +# Note that you should *not* look at the call-count numbers in the right +# hand column as the actual number of times each line *was called by* +# the function on the next line. Rather, it's the *total* number +# of times each function was found in the call chain for any of the +# calls to SCons.Debug.caller(). If you're looking at more than one +# function at the same time, for example, their counts will intermix. +# So use this to get a *general* idea of who's calling what, not for +# fine-grained performance tuning. + +import sys + +class Entry: + def __init__(self, file_line_func): + self.file_line_func = file_line_func + self.called_by = [] + self.calls = [] + +AllCalls = {} + +def get_call(flf): + try: + e = AllCalls[flf] + except KeyError: + e = AllCalls[flf] = Entry(flf) + return e + +prefix = 'Callers of ' + +c = None +for line in sys.stdin.readlines(): + if line[0] == '#': + pass + elif line[:len(prefix)] == prefix: + c = get_call(line[len(prefix):-2]) + else: + num_calls, flf = line.strip().split() + e = get_call(flf) + c.called_by.append((e, num_calls)) + e.calls.append(c) + +stack = [] + +def print_entry(e, level, calls): + print '%-72s%6s' % ((' '*2*level) + e.file_line_func, calls) + if e in stack: + print (' '*2*(level+1))+'RECURSION' + print + elif e.called_by: + stack.append(e) + for c in e.called_by: + print_entry(c[0], level+1, c[1]) + stack.pop() + else: + print + +for e in [ e for e in AllCalls.values() if not e.calls ]: + print_entry(e, 0, '') diff --git a/bin/scons-cdist b/bin/scons-cdist index 425e430..58b1bae 100644 --- a/bin/scons-cdist +++ b/bin/scons-cdist @@ -22,45 +22,58 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PROG=`basename $0` -FLAGS="ahnqrstz" -USAGE="Usage: ${PROG} [-${FLAGS}] change" +NOARGFLAGS="afhlnqrstz" +ARGFLAGS="p:" +ALLFLAGS="${NOARGFLAGS}${ARGFLAGS}" +USAGE="Usage: ${PROG} [-${NOARGFLAGS}] [-p project] change" HELP="$USAGE - -a Update the latest Aegis baseline (aedist) file. - -h Print this help message and exit. - -n Don't execute, just echo commands. - -q Quiet, don't print commands before executing them. - -r Rsync the Aegis repository to SourceForge. - -s Update the sourceforge.net CVS repository. - -t Update the tigris.org CVS repository. - -z Update the latest .zip file. + -a Update the latest Aegis baseline (aedist) file. + -f Force update, skipping up-front sanity check. + -h Print this help message and exit. + -l Update the local CVS repository. + -n Don't execute, just echo commands. + -p project Set the Aegis project. + -q Quiet, don't print commands before executing them. + -r Rsync the Aegis repository to SourceForge. + -s Update the sourceforge.net CVS repository. + -t Update the tigris.org CVS repository. + -z Update the latest .tar.gz and .zip files. " DO="" PRINT="echo" EXECUTE="eval" +SANITY_CHECK="yes" -while getopts $FLAGS FLAG; do - case $FLAG in - a | r | s | t | z ) - DO="${DO}${FLAG}" - ;; - h ) - echo "${HELP}" - exit 0 - ;; - n ) - EXECUTE=":" - ;; - q ) - PRINT=":" - ;; - * ) - echo "${USAGE}" >&2 - exit 1 - ;; - esac +while getopts $ALLFLAGS FLAG; do + case $FLAG in + a | l | r | s | t | z ) + DO="${DO}${FLAG}" + ;; + f ) + SANITY_CHECK="no" + ;; + h ) + echo "${HELP}" + exit 0 + ;; + n ) + EXECUTE=":" + ;; + p ) + AEGIS_PROJECT="${OPTARG}" + ;; + q ) + PRINT=":" + ;; + * ) + echo "FLAG = ${FLAG}" >&2 + echo "${USAGE}" >&2 + exit 1 + ;; + esac done shift `expr ${OPTIND} - 1` @@ -70,8 +83,14 @@ if test "X$1" = "X"; then exit 1 fi +if test "X${AEGIS_PROJECT}" = "X"; then + echo "$PROG: No AEGIS_PROJECT set." >&2 + echo "${USAGE}" >&2 + exit 1 +fi + if test "X$DO" = "X"; then - DO="arstz" + DO="alrstz" fi cmd() @@ -82,6 +101,27 @@ cmd() CHANGE=$1 +if test "X${SANITY_CHECK}" = "Xyes"; then + SCM="cvs" + SCMROOT="/home/scons/CVSROOT/scons" + DELTA=`aegis -l -ter cd ${CHANGE} | sed -n 's/.*, Delta \([0-9]*\)\./\1/p'` + if test "x${DELTA}" = "x"; then + echo "${PROG}: Could not find delta for change ${CHANGE}." >&2 + echo "Has this finished integrating? Change ${CHANGE} not distributed." >&2 + exit 1 + fi + PREV_DELTA=`expr ${DELTA} - 1` + COMMAND="scons-scmcheck -D ${PREV_DELTA} -d q -p ${AEGIS_PROJECT} -s ${SCM} ${SCMROOT}" + $PRINT "${COMMAND}" + OUTPUT=`${COMMAND}` + if test "X${OUTPUT}" != "X"; then + echo "${PROG}: ${SCMROOT} is not up to date:" >&2 + echo "${OUTPUT}" >& 2 + echo "Did you skip any changes? Change ${CHANGE} not distributed." >&2 + exit 1 + fi +fi + if test X$EXECUTE != "X:" -a "X$SSH_AGENT_PID" = "X"; then eval `ssh-agent` ssh-add @@ -95,29 +135,38 @@ BASELINE=`aesub -p ${AEGIS_PROJECT} -c ${CHANGE} '${Project trunk_name}'` TMPBLAE="/tmp/${BASELINE}.ae" TMPCAE="/tmp/${AEGIS_PROJECT}.C${CHANGE}.ae" -SFLOGIN="stevenknight" -SFHOST="scons.sourceforge.net" -SFDEST="/home/groups/s/sc/scons/htdocs" +# Original values for SourceForge. +#SFLOGIN="stevenknight" +#SFHOST="scons.sourceforge.net" +#SFDEST="/home/groups/s/sc/scons/htdocs" + +SCONSLOGIN="scons" +SCONSHOST="manam.pair.com" +#SCONSDEST="public_html/production" +SCONSDEST="public_ftp" # # Copy the baseline .ae to the constant location on SourceForge. # case "${DO}" in - *a* ) - cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}" - cmd "scp ${TMPBLAE} ${SFLOGIN}@${SFHOST}:${SFDEST}/${BASELINE}.ae" - cmd "rm ${TMPBLAE}" - ;; +*a* ) + cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}" + cmd "scp ${TMPBLAE} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/${BASELINE}.ae" + cmd "rm ${TMPBLAE}" + ;; esac # -# Copy the latest .zip file to the constant location on SourceForge. +# Copy the latest .tar.gz and .zip files to the constant location on +# SourceForge. # case "${DO}" in - *z* ) - BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist - SCONS_SRC=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`.zip - cmd "scp ${BUILD_DIST}/${SCONS_SRC} ${SFLOGIN}@${SFHOST}:${SFDEST}/scons-src-latest.zip" +*z* ) + BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist + SCONS_SRC_TAR_GZ=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.tar.gz + SCONS_SRC_ZIP=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.zip + cmd "scp ${BUILD_DIST}/${SCONS_SRC_TAR_GZ} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.tar.gz" + cmd "scp ${BUILD_DIST}/${SCONS_SRC_ZIP} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.zip" esac # @@ -144,38 +193,73 @@ esac # We no longer use the --stats option. # case "${DO}" in - *r* ) - LOCAL=/home/scons/scons - REMOTE=/home/groups/s/sc/scons/scons - cmd "/usr/bin/rsync --rsh=ssh -l -p -r -t -z \ - --exclude build \ - --exclude '*,D' \ - --exclude '*.pyc' \ - --exclude aegis.log \ - --exclude '.sconsign*' \ - --delete --delete-excluded \ - --progress -v \ - ${LOCAL}/. scons.sourceforge.net:${REMOTE}/." - ;; +*r* ) + LOCAL=/home/scons/scons + REMOTE=/home/groups/s/sc/scons/scons + cmd "/usr/bin/rsync --rsh='ssh -l stevenknight' \ + -l -p -r -t -z \ + --exclude build \ + --exclude '*,D' \ + --exclude '*.pyc' \ + --exclude aegis.log \ + --exclude '.sconsign*' \ + --delete --delete-excluded \ + --progress -v \ + ${LOCAL}/. scons.sourceforge.net:${REMOTE}/." + ;; esac # -# Sync the CVS tree with Tigris.org. +# Sync the CVS tree with the local repository. # case "${DO}" in - *t* ) - cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons" - ;; +*l* ) + ( + export CVSROOT=/home/scons/CVSROOT/scons + #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/baldmt.com/scons" + cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}" + ) + ;; +esac + +# +# Sync the Subversion tree with Tigris.org. +# +case "${DO}" in +*t* ) + ( + SVN=http://scons.tigris.org/svn/scons + case ${AEGIS_PROJECT} in + scons.0.96 ) + SVN_URL=${SVN}/branches/core + ;; + scons.0.96.513 ) + SVN_URL=${SVN}/branches/sigrefactor + ;; + * ) + echo "$PROG: Don't know SVN branch for '${AEGIS_PROJECT}'" >&2 + exit 1 + ;; + esac + SVN_CO_FLAGS="--username stevenknight" + #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons" + cmd "ae-svn-ci ${AEGIS_PROJECT} ${CHANGE} ${SVN_URL} ${SVN_CO_FLAGS}" + ) + ;; esac # # Sync the CVS tree with SourceForge. # case "${DO}" in - *s* ) +*s* ) + ( export CVS_RSH=ssh - cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons" - ;; + export CVSROOT=:ext:stevenknight@scons.cvs.sourceforge.net:/cvsroot/scons + #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons" + cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}" + ) + ;; esac # @@ -185,4 +269,4 @@ esac # #aedist -s -p ${AEGIS_PROJECT} ${CHANGE} > ${TMPCAE} #aegis -l -p ${AEGIS_PROJECT} -c ${CHANGE} cd | -# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net +# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net diff --git a/bin/scons-diff.py b/bin/scons-diff.py new file mode 100644 index 0000000..6cfe25a --- /dev/null +++ b/bin/scons-diff.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +# +# scons-diff.py - diff-like utility for comparing SCons trees +# +# This supports most common diff options (with some quirks, like you can't +# just say -c and have it use a default value), but canonicalizes the +# various version strings within the file like __revision__, __build__, +# etc. so that you can diff trees without having to ignore changes in +# version lines. +# + +import difflib +import getopt +import os.path +import re +import sys + +Usage = """\ +Usage: scons-diff.py [OPTIONS] dir1 dir2 +Options: + -c NUM, --context=NUM Print NUM lines of copied context. + -h, --help Print this message and exit. + -n Don't canonicalize SCons lines. + -q, --quiet Print only whether files differ. + -r, --recursive Recursively compare found subdirectories. + -s Report when two files are the same. + -u NUM, --unified=NUM Print NUM lines of unified context. +""" + +opts, args = getopt.getopt(sys.argv[1:], + 'c:dhnqrsu:', + ['context=', 'help', 'recursive', 'unified=']) + +diff_type = None +edit_type = None +context = 2 +recursive = False +report_same = False +diff_options = [] + +def diff_line(left, right): + if diff_options: + opts = ' ' + ' '.join(diff_options) + else: + opts = '' + print 'diff%s %s %s' % (opts, left, right) + +for o, a in opts: + if o in ('-c', '-u'): + diff_type = o + context = int(a) + diff_options.append(o) + elif o in ('-h', '--help'): + print Usage + sys.exit(0) + elif o in ('-n'): + diff_options.append(o) + edit_type = o + elif o in ('-q'): + diff_type = o + diff_line = lambda l, r: None + elif o in ('-r', '--recursive'): + recursive = True + diff_options.append(o) + elif o in ('-s'): + report_same = True + +try: + left, right = args +except ValueError: + sys.stderr.write(Usage) + sys.exit(1) + +def quiet_diff(a, b, fromfile='', tofile='', + fromfiledate='', tofiledate='', n=3, lineterm='\n'): + """ + A function with the same calling signature as difflib.context_diff + (diff -c) and difflib.unified_diff (diff -u) but which prints + output like the simple, unadorned 'diff" command. + """ + if a == b: + return [] + else: + return ['Files %s and %s differ\n' % (fromfile, tofile)] + +def simple_diff(a, b, fromfile='', tofile='', + fromfiledate='', tofiledate='', n=3, lineterm='\n'): + """ + A function with the same calling signature as difflib.context_diff + (diff -c) and difflib.unified_diff (diff -u) but which prints + output like the simple, unadorned 'diff" command. + """ + sm = difflib.SequenceMatcher(None, a, b) + def comma(x1, x2): + return x1+1 == x2 and str(x2) or '%s,%s' % (x1+1, x2) + result = [] + for op, a1, a2, b1, b2 in sm.get_opcodes(): + if op == 'delete': + result.append("%sd%d\n" % (comma(a1, a2), b1)) + result.extend(map(lambda l: '< ' + l, a[a1:a2])) + elif op == 'insert': + result.append("%da%s\n" % (a1, comma(b1, b2))) + result.extend(map(lambda l: '> ' + l, b[b1:b2])) + elif op == 'replace': + result.append("%sc%s\n" % (comma(a1, a2), comma(b1, b2))) + result.extend(map(lambda l: '< ' + l, a[a1:a2])) + result.append('---\n') + result.extend(map(lambda l: '> ' + l, b[b1:b2])) + return result + +diff_map = { + '-c' : difflib.context_diff, + '-q' : quiet_diff, + '-u' : difflib.unified_diff, +} + +diff_function = diff_map.get(diff_type, simple_diff) + +baseline_re = re.compile('(# |@REM )/home/\S+/baseline/') +comment_rev_re = re.compile('(# |@REM )(\S+) 0.96.[CD]\d+ \S+ \S+( knight)') +revision_re = re.compile('__revision__ = "[^"]*"') +build_re = re.compile('__build__ = "[^"]*"') +date_re = re.compile('__date__ = "[^"]*"') + +def lines_read(file): + return open(file).readlines() + +def lines_massage(file): + text = open(file).read() + text = baseline_re.sub('\\1', text) + text = comment_rev_re.sub('\\1\\2\\3', text) + text = revision_re.sub('__revision__ = "__FILE__"', text) + text = build_re.sub('__build__ = "0.96.92.DXXX"', text) + text = date_re.sub('__date__ = "2006/08/25 02:59:00"', text) + return text.splitlines(1) + +lines_map = { + '-n' : lines_read, +} + +lines_function = lines_map.get(edit_type, lines_massage) + +def do_diff(left, right, diff_subdirs): + if os.path.isfile(left) and os.path.isfile(right): + diff_file(left, right) + elif not os.path.isdir(left): + diff_file(left, os.path.join(right, os.path.split(left)[1])) + elif not os.path.isdir(right): + diff_file(os.path.join(left, os.path.split(right)[1]), right) + elif diff_subdirs: + diff_dir(left, right) + +def diff_file(left, right): + l = lines_function(left) + r = lines_function(right) + d = diff_function(l, r, left, right, context) + try: + text = ''.join(d) + except IndexError: + sys.stderr.write('IndexError diffing %s and %s\n' % (left, right)) + else: + if text: + diff_line(left, right) + print text, + elif report_same: + print 'Files %s and %s are identical' % (left, right) + +def diff_dir(left, right): + llist = os.listdir(left) + rlist = os.listdir(right) + u = {} + for l in llist: + u[l] = 1 + for r in rlist: + u[r] = 1 + clist = [ x for x in u.keys() if x[-4:] != '.pyc' ] + clist.sort() + for x in clist: + if x in llist: + if x in rlist: + do_diff(os.path.join(left, x), + os.path.join(right, x), + recursive) + else: + print 'Only in %s: %s' % (left, x) + else: + print 'Only in %s: %s' % (right, x) + +do_diff(left, right, True) diff --git a/config b/config index e540484..b055bdb 100644 --- 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"; + * + */ diff --git a/doc/SConscript b/doc/SConscript index 6162f93..6f92fbc 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -169,7 +169,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. variables_gen, variables_mod] b = env.Command(doc_output_files, scons_doc_files, - "python $SCONS_PROC_PY --sgml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)") + "$PYTHON $SCONS_PROC_PY --sgml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)") env.Depends(b, "$SCONS_PROC_PY") env.Local(b) @@ -259,7 +259,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. if build_doc and ext == '.sgml': env.Command(doc_s, base + '.in', - "python $SCONSOUTPUT_PY $SOURCE > $TARGET") + "$PYTHON $SCONSOUTPUT_PY $SOURCE > $TARGET") orig_env.SCons_revision(build_s, doc_s) Local(build_s) @@ -387,7 +387,7 @@ man_i_files = ['builders.man', 'tools.man', 'variables.man'] man_intermediate_files = map(lambda x: os.path.join(build, 'man', x), man_i_files) -cmd = "python $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)" +cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)" man_intermediate_files = env.Command(man_intermediate_files, scons_doc_files, cmd) diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 49f9a30..a12bd68 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -421,6 +421,24 @@ Will not remove any targets specified by the function. .TP +.RI --cache-debug= file +Print debug information about the +.BR CacheDir () +derived-file caching +to the specified +.IR file . +If +.I file +is +.B \- +(a hyphen), +the debug information are printed to the standard output. +The printed messages describe what signature file names are +being looked for in, retrieved from, or written to the +.BR CacheDir () +directory tree. + +.TP --cache-disable, --no-cache Disable the derived-file caching specified by .BR CacheDir (). @@ -1712,6 +1730,24 @@ the specified See the section "Action Objects," below, for a complete explanation of the arguments and behavior. +Note that the +.BR env.Action () +form of the invocation will expand +construction variables in any arguments strings, +including the +.I action +argument, +at the time it is called +using the construction variables in the +.B env +construction environment through which +.BR env.Action () +was called. +The +.BR Action () +form delays all variable expansion +until the Action object is actually used. + '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI AddPostAction( target ", " action ) @@ -1993,6 +2029,24 @@ the specified See the section "Builder Objects," below, for a complete explanation of the arguments and behavior. +Note that the +.BR env.Builder () +form of the invocation will expand +construction variables in any arguments strings, +including the +.I action +argument, +at the time it is called +using the construction variables in the +.B env +construction environment through which +.BR env.Builder () +was called. +The +.BR Builder () +form delays all variable expansion +until after the Builder object is actually called. + '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .RI CacheDir( cache_dir ) @@ -2759,8 +2813,11 @@ Import("*") .RI Install( dir ", " source ) .TP .RI env.Install( dir ", " source ) -Installs one or more files in a destination directory. -The file names remain the same. +Installs one or more source files or directories +in a destination directory +.IR dir . +The names of the specified source files or directories +remain the same within the destination directory. .ES env.Install(dir = '/usr/local/bin', source = ['foo', 'bar']) @@ -2771,11 +2828,15 @@ env.Install(dir = '/usr/local/bin', source = ['foo', 'bar']) .RI InstallAs( target ", " source ) .TP .RI env.InstallAs( target ", " source ) -Installs one or more files as specific file names, -allowing changing a file name as part of the -installation. -It is an error if the target and source -list different numbers of files. +Installs one or more source files or directories +to specific names, +allowing changing a file or directory name +as part of the installation. +It is an error if the +.I target +and +.I source +arguments list different numbers of files or directories. .ES env.InstallAs(target = '/usr/local/bin/foo', @@ -3997,17 +4058,31 @@ env.Tool('opengl', toolpath = ['build/tools']) '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.RI Value( value ) +.RI Value( value ", [" built_value ]) .TP -.RI env.Value( value ) +.RI env.Value( value ", [" built_value ]) Returns a Node object representing the specified Python value. Value -nodes can be used as dependencies of targets. If the result of +Nodes can be used as dependencies of targets. If the result of calling .BR str( value ) changes between SCons runs, any targets depending on .BR Value( value ) -will be rebuilt. When using timestamp source signatures, Value nodes' -timestamps are equal to the system time when the node is created. +will be rebuilt. When using timestamp source signatures, Value Nodes' +timestamps are equal to the system time when the Node is created. + +The returned Value Node object has a +.BR write () +method that can be used to "build" a Value Node +by setting a new value. +The optional +.I built_value +argument can be specified +when the Value Node is created +to indicate the Node should already be considered +"built." +There is a corresponding +.BR read () +method that will return the built value of the Node. .ES def create(target, source, env): @@ -4018,6 +4093,15 @@ prefix = ARGUMENTS.get('prefix', '/usr/local') env = Environment() env['BUILDERS']['Config'] = Builder(action = create) env.Config(target = 'package-config', source = Value(prefix)) + +def build_value(target, source, env): + target[0].write(source[0].get_contents()) + +output = env.Value('before') +input = env.Value('after') + +env['BUILDERS']['UpdateValue'] = Builder(action = build_value) +env.UpdateValue(target = Value(output), source = Value(input)) .EE '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/runtest.py b/runtest.py index 7f5cbc3..5440c10 100644 --- a/runtest.py +++ b/runtest.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation +# __COPYRIGHT__ # # runtest.py - wrapper script for running SCons tests # @@ -96,20 +96,21 @@ import string import sys import time +if not hasattr(os, 'WEXITSTATUS'): + os.WEXITSTATUS = lambda x: x + all = 0 baseline = 0 debug = '' execute_tests = 1 format = None list_only = None -tests = [] printcommand = 1 package = None print_passed_summary = None scons = None scons_exec = None outputfile = None -qmtest = None testlistfile = None version = '' print_times = None @@ -119,13 +120,6 @@ spe = None cwd = os.getcwd() -if sys.platform == 'win32' or os.name == 'java': - lib_dir = os.path.join(sys.exec_prefix, "Lib") -else: - # The hard-coded "python" here is the directory name, - # not an executable, so it's all right. - lib_dir = os.path.join(sys.exec_prefix, "lib", "python" + sys.version[0:3]) - helpstr = """\ Usage: runtest.py [OPTIONS] [TEST ...] Options: @@ -137,6 +131,7 @@ Options: -h, --help Print this message and exit. -l, --list List available tests and exit. -n, --no-exec No execute, just print command lines. + --noqmtest Execute tests directly, not using QMTest. -o FILE, --output FILE Print test results to FILE. -P Python Use the specified Python interpreter. -p PACKAGE, --package PACKAGE @@ -167,7 +162,7 @@ Options: opts, args = getopt.getopt(sys.argv[1:], "ab:df:hlno:P:p:qv:Xx:t", ['all', 'aegis', 'baseline=', 'debug', 'file=', 'help', - 'list', 'no-exec', 'output=', + 'list', 'no-exec', 'noqmtest', 'output=', 'package=', 'passed', 'python=', 'qmtest', 'quiet', 'spe=', 'version=', 'exec=', 'time', @@ -179,7 +174,11 @@ for o, a in opts: elif o in ['-b', '--baseline']: baseline = a elif o in ['-d', '--debug']: - debug = os.path.join(lib_dir, "pdb.py") + for dir in sys.path: + pdb = os.path.join(dir, 'pdb.py') + if os.path.exists(pdb): + debug = pdb + break elif o in ['-f', '--file']: if not os.path.isabs(a): a = os.path.join(cwd, a) @@ -191,6 +190,8 @@ for o, a in opts: list_only = 1 elif o in ['-n', '--no-exec']: execute_tests = None + elif o in ['--noqmtest']: + qmtest = None elif o in ['-o', '--output']: if a != '-' and not os.path.isabs(a): a = os.path.join(cwd, a) @@ -202,7 +203,7 @@ for o, a in opts: elif o in ['-P', '--python']: python = a elif o in ['--qmtest']: - qmtest = 1 + qmtest = 'qmtest.py' elif o in ['-q', '--quiet']: printcommand = 0 elif o in ['--sp']: @@ -222,6 +223,17 @@ for o, a in opts: elif o in ['--aegis', '--xml']: format = o +if not args and not all and not testlistfile: + sys.stderr.write("""\ +runtest.py: No tests were specified. + List one or more tests on the command line, use the + -f option to specify a file containing a list of tests, + or use the -a option to find and run all tests. + +""") + sys.exit(1) + + def whereis(file): for dir in string.split(os.environ['PATH'], os.pathsep): f = os.path.join(dir, file) @@ -234,6 +246,16 @@ def whereis(file): return f return None +try: + qmtest +except NameError: + q = 'qmtest.py' + qmtest = whereis(q) + if qmtest: + qmtest = q + else: + sys.stderr.write('Warning: %s not found on $PATH, assuming --noqmtest option.\n' % q) + aegis = whereis('aegis') if format == '--aegis' and aegis: @@ -277,9 +299,9 @@ except AttributeError: return status >> 8 else: def spawn_it(command_args): + command = command_args[0] command_args = map(escape, command_args) - command_args = map(lambda s: string.replace(s, '\\','\\\\'), command_args) - return os.spawnv(os.P_WAIT, command_args[0], command_args) + return os.spawnv(os.P_WAIT, command, command_args) class Base: def __init__(self, path, spe=None): @@ -352,86 +374,8 @@ format_class = { '--aegis' : Aegis, '--xml' : XML, } -Test = format_class[format] - -if qmtest: - pass -elif args: - if spe: - for a in args: - if os.path.isabs(a): - for g in glob.glob(a): - tests.append(Test(g)) - else: - for dir in spe: - x = os.path.join(dir, a) - globs = glob.glob(x) - if globs: - for g in globs: - tests.append(Test(g)) - break - else: - for a in args: - for g in glob.glob(a): - tests.append(Test(g)) -elif all: - # Find all of the SCons functional tests in the local directory - # tree. This is anything under the 'src' subdirectory that ends - # with 'Tests.py', or any Python script (*.py) under the 'test' - # subdirectory. - # - # Note that there are some tests under 'src' that *begin* with - # 'test_', but they're packaging and installation tests, not - # functional tests, so we don't execute them by default. (They can - # still be executed by hand, though, and are routinely executed - # by the Aegis packaging build to make sure that we're building - # things correctly.) - tdict = {} - - def find_Tests_py(arg, dirname, names, tdict=tdict): - for n in filter(lambda n: n[-8:] == "Tests.py", names): - t = os.path.join(dirname, n) - if not tdict.has_key(t): - tdict[t] = Test(t) - os.path.walk('src', find_Tests_py, 0) - - def find_py(arg, dirname, names, tdict=tdict): - for n in filter(lambda n: n[-3:] == ".py", names): - t = os.path.join(dirname, n) - if not tdict.has_key(t): - tdict[t] = Test(t) - os.path.walk('test', find_py, 0) - - if format == '--aegis' and aegis: - cmd = "aegis -list -unf pf 2>/dev/null" - for line in os.popen(cmd, "r").readlines(): - a = string.split(line) - if a[0] == "test" and not tdict.has_key(a[-1]): - tdict[a[-1]] = Test(a[-1], spe) - cmd = "aegis -list -unf cf 2>/dev/null" - for line in os.popen(cmd, "r").readlines(): - a = string.split(line) - if a[0] == "test": - if a[1] == "remove": - del tdict[a[-1]] - elif not tdict.has_key(a[-1]): - tdict[a[-1]] = Test(a[-1], spe) - - keys = tdict.keys() - keys.sort() - tests = map(tdict.get, keys) -elif testlistfile: - tests = open(testlistfile, 'r').readlines() - tests = filter(lambda x: x[0] != '#', tests) - tests = map(lambda x: x[:-1], tests) - tests = map(Test, tests) -else: - sys.stderr.write("""\ -runtest.py: No tests were specified on the command line. - List one or more tests, or use the -a option - to find and run all tests. -""") +Test = format_class[format] if package: @@ -476,6 +420,8 @@ if package: scons_lib_dir = os.path.join(test_dir, dir[package], 'lib', l) pythonpath_dir = scons_lib_dir + scons_runtest_dir = os.path.join(cwd, 'build') + else: sd = None ld = None @@ -529,6 +475,8 @@ else: else: base = baseline + scons_runtest_dir = base + scons_script_dir = sd or os.path.join(base, 'src', 'script') scons_lib_dir = ld or os.path.join(base, 'src', 'engine') @@ -548,6 +496,7 @@ elif scons_lib_dir: if scons_exec: os.environ['SCONS_EXEC'] = '1' +os.environ['SCONS_RUNTEST_DIR'] = scons_runtest_dir os.environ['SCONS_SCRIPT_DIR'] = scons_script_dir os.environ['SCONS_CWD'] = cwd @@ -573,43 +522,123 @@ if old_pythonpath: os.pathsep + \ old_pythonpath +tests = [] + +if args: + if spe: + for a in args: + if os.path.isabs(a): + tests.extend(glob.glob(a)) + else: + for dir in spe: + x = os.path.join(dir, a) + globs = glob.glob(x) + if globs: + tests.extend(globs) + break + else: + for a in args: + tests.extend(glob.glob(a)) +elif testlistfile: + tests = open(testlistfile, 'r').readlines() + tests = filter(lambda x: x[0] != '#', tests) + tests = map(lambda x: x[:-1], tests) +elif all and not qmtest: + # Find all of the SCons functional tests in the local directory + # tree. This is anything under the 'src' subdirectory that ends + # with 'Tests.py', or any Python script (*.py) under the 'test' + # subdirectory. + # + # Note that there are some tests under 'src' that *begin* with + # 'test_', but they're packaging and installation tests, not + # functional tests, so we don't execute them by default. (They can + # still be executed by hand, though, and are routinely executed + # by the Aegis packaging build to make sure that we're building + # things correctly.) + tdict = {} + + def find_Tests_py(tdict, dirname, names): + for n in filter(lambda n: n[-8:] == "Tests.py", names): + t = os.path.join(dirname, n) + if not tdict.has_key(t): + tdict[t] = 1 + os.path.walk('src', find_Tests_py, tdict) + + def find_py(tdict, dirname, names): + for n in filter(lambda n: n[-3:] == ".py", names): + t = os.path.join(dirname, n) + if not tdict.has_key(t): + tdict[t] = 1 + os.path.walk('test', find_py, tdict) + + if format == '--aegis' and aegis: + cmd = "aegis -list -unf pf 2>/dev/null" + for line in os.popen(cmd, "r").readlines(): + a = string.split(line) + if a[0] == "test" and not tdict.has_key(a[-1]): + tdict[a[-1]] = Test(a[-1], spe) + cmd = "aegis -list -unf cf 2>/dev/null" + for line in os.popen(cmd, "r").readlines(): + a = string.split(line) + if a[0] == "test": + if a[1] == "remove": + del tdict[a[-1]] + elif not tdict.has_key(a[-1]): + tdict[a[-1]] = Test(a[-1], spe) + + tests = tdict.keys() + tests.sort() + if qmtest: if baseline: - result_stream = 'AegisBaselineStream' + aegis_result_stream = 'scons_tdb.AegisBaselineStream' qmr_file = 'baseline.qmr' else: - result_stream = 'AegisChangeStream' + aegis_result_stream = 'scons_tdb.AegisChangeStream' qmr_file = 'results.qmr' - #qmtest = r'D:\Applications\python23\scripts\qmtest.py' - qmtest = 'qmtest.py' - qmtest_args = [ - qmtest, + + if print_times: + aegis_result_stream = aegis_result_stream + "(print_time='1')" + + qmtest_args = [ qmtest, ] + + if format == '--aegis': + dir = os.path.join(cwd, 'build') + if not os.path.isdir(dir): + dir = cwd + qmtest_args.extend(['-D', dir]) + + qmtest_args.extend([ 'run', '--output %s' % qmr_file, '--format none', - '--result-stream=scons_tdb.%s' % result_stream, - ] + '--result-stream="%s"' % aegis_result_stream, + ]) if python: - qmtest_args.append('--context python=%s' % python) - - if print_times: - qmtest_args.append('--context print_time=1') + qmtest_args.append('--context python="%s"' % python) if outputfile: - #rs = '--result-stream=scons_tdb.AegisBatchStream(results_file=\\"%s\\")' % outputfile - rs = '\'--result-stream=scons_tdb.AegisBatchStream(results_file="%s")\'' % outputfile + if format == '--xml': + rsclass = 'scons_tdb.SConsXMLResultStream' + else: + rsclass = 'scons_tdb.AegisBatchStream' + qof = "r'" + outputfile + "'" + rs = '--result-stream="%s(filename=%s)"' % (rsclass, qof) qmtest_args.append(rs) - os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py') + if format == '--aegis': + tests = map(lambda x: string.replace(x, cwd+os.sep, ''), tests) + else: + os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py') - cmd = string.join(qmtest_args + args, ' ') + cmd = string.join(qmtest_args + tests, ' ') if printcommand: sys.stdout.write(cmd + '\n') sys.stdout.flush() status = 0 if execute_tests: - status = os.system(cmd) + status = os.WEXITSTATUS(os.system(cmd)) sys.exit(status) #try: @@ -617,6 +646,8 @@ if qmtest: #except OSError: # pass +tests = map(Test, tests) + class Unbuffered: def __init__(self, file): self.file = file @@ -644,20 +675,15 @@ if not python: # but time.time() does a better job on Linux systems, so let that be # the non-Windows default. -if print_times: - print_time_func = lambda fmt, time: sys.stdout.write(fmt % time) -else: - print_time_func = lambda fmt, time: None - if sys.platform == 'win32': time_func = time.clock else: time_func = time.time -if sys.platform == 'win32': - time_func = time.clock +if print_times: + print_time_func = lambda fmt, time: sys.stdout.write(fmt % time) else: - time_func = time.time + print_time_func = lambda fmt, time: None total_start_time = time_func() for t in tests: diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ccbc3af..88e70dc 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -10,10 +10,29 @@ RELEASE 0.97 - XXX + From Anonymous: + + - Allow Python Value Nodes to be Builder targets. + + From Matthias: + + - Only filter Visual Studio common filename prefixes on complete + directory names. + + From Chad Austin: + + - Fix the build of the SCons documentation on systems that don't + have "python" in the $PATH. + From Ken Boortz: - Enhance ParseConfig() to recognize options that begin with '+'. + From John Calcote, Elliot Murphy: + + - Document ways to override the CCPDBFLAGS variable to use the + Microsoft linker's /Zi option instead of the default /Z7. + From Christopher Drexler: - Make SCons aware bibtex must be called if any \include files @@ -29,6 +48,10 @@ RELEASE 0.97 - XXX - Preserve white space in display Action strfunction strings. + From James Y. Knight and Gerard Patel: + + - Support creation of shared object files from assembly language. + From Steven Knight: - Speed up the Taskmaster significantly by avoiding unnecessary @@ -47,16 +70,44 @@ RELEASE 0.97 - XXX This will become the default behavior as we add more functionality to the QMTest side. + - Let linking on mingw use the default function that chooses $CC (gcc) + or $CXX (g++) depending on whether there are any C++ source files. + + - Work around a bug in early versions of the Python 2.4 profile module + that caused the --profile= option to fail. + + - Only call Options validators and converters once when initializing a + construction environment. + + - Fix the ability of env.Append() and env.Prepend(), in all known Python + versions, to handle different input value types when the construction + variable being updated is a dictionary. + + - Add a --cache-debug option for information about what files it's + looking for in a CacheDir(). + + - Document the difference in construction variable expansion between + {Action,Builder}() and env.{Action,Builder}(). + From Arve Knudsen: - Support cleaning and scanning SWIG-generated files. - From Baptiste Lepilleur: + From Carsten Koch: + + - Allow selection of Visual Studio version by setting $MSVS_VERSION + after construction environment initialization. + + From Jean-Baptiste Lab: - Try using zipimport if we can't import Tool or Platform modules using the normal "imp" module. This allows SCons to be packaged using py2exe's all-in-one-zip-file approach. + From Ben Liblit: + + - Do not re-scan files if the scanner returns no implicit dependencies. + From Sanjoy Mahajan: - Change use of $SOURCES to $SOURCE in all TeX-related Tool modules. @@ -70,6 +121,19 @@ RELEASE 0.97 - XXX - Prevent scanning the TeX .aux file for additional files from trying to remove it twice when the -c option is used. + From Leanid Nazdrynau: + + - Give the MSVC RES (resource) Builder a src_builder list and a .rc + src_suffix so other builders can generate .rc files. + + From Matthew A. Nicholson: + + - Enhance Install() and InstallAs() to handle directory trees as sources. + + From Jan Nijtmans: + + - Don't use the -fPIC flag when using gcc on Windows (e.g. MinGW). + From Greg Noel: - Add an env.ParseFlags() method that provides separate logic for @@ -105,10 +169,36 @@ RELEASE 0.97 - XXX - Initial infrastructure for running SCons tests under QMTest. + From Sohail Sumani: + + - Fix tests that fail due to gcc warnings. + + From Dobes Vandermeer: + + - In stack traces, print the full paths of SConscript files. + From Atul Varma: - Fix detection of Visual C++ Express Edition. + From Dobes Vandermeer: + + - Let the src_dir option to the SConscript() function affect all the + the source file paths, instead of treating all source files paths + as relative to the SConscript directory itself. + + From Nicolas Vigier: + + - Fix finding Fortran modules in build directories. + + - Fix use of BuildDir() when the source file in the source directory + is a symlink with a relative path. + + From Edward Wang: + + - Fix the Memoizer when the SCons Python modules are executed from + .pyo files at different locations from where they were compiled. + From Johan Zander: - Fix missing os.path.join() when constructing the $FRAMEWORKSDKDIR/bin. diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 9d6c972..c762f1c 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -2,6 +2,7 @@ SCons/__init__.py SCons/Action.py SCons/Builder.py SCons/Conftest.py +SCons/cpp.py SCons/dblite.py SCons/Debug.py SCons/Defaults.py diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 1085586..57910de 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -182,6 +182,8 @@ if os.name == 'java': else: python = sys.executable +_python_ = '"' + python + '"' + class ActionTestCase(unittest.TestCase): """Test the Action() factory function""" @@ -903,7 +905,7 @@ class CommandActionTestCase(unittest.TestCase): except AttributeError: env = Environment() - cmd1 = r'%s %s %s xyzzy' % (python, act_py, outfile) + cmd1 = r'%s %s %s xyzzy' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd1) r = act([], [], env.Copy()) @@ -911,7 +913,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'xyzzy'\n", c - cmd2 = r'%s %s %s $TARGET' % (python, act_py, outfile) + cmd2 = r'%s %s %s $TARGET' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd2) r = act(DummyNode('foo'), [], env.Copy()) @@ -919,7 +921,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'foo'\n", c - cmd3 = r'%s %s %s ${TARGETS}' % (python, act_py, outfile) + cmd3 = r'%s %s %s ${TARGETS}' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd3) r = act(map(DummyNode, ['aaa', 'bbb']), [], env.Copy()) @@ -927,7 +929,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'aaa' 'bbb'\n", c - cmd4 = r'%s %s %s $SOURCES' % (python, act_py, outfile) + cmd4 = r'%s %s %s $SOURCES' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd4) r = act([], [DummyNode('one'), DummyNode('two')], env.Copy()) @@ -935,7 +937,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'one' 'two'\n", c - cmd4 = r'%s %s %s ${SOURCES[:2]}' % (python, act_py, outfile) + cmd4 = r'%s %s %s ${SOURCES[:2]}' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd4) sources = [DummyNode('three'), DummyNode('four'), DummyNode('five')] @@ -945,7 +947,7 @@ class CommandActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'three' 'four'\n", c - cmd5 = r'%s %s %s $TARGET XYZZY' % (python, act_py, outfile) + cmd5 = r'%s %s %s $TARGET XYZZY' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd5) env5 = Environment() @@ -978,7 +980,7 @@ class CommandActionTestCase(unittest.TestCase): def get_subst_proxy(self): return self - cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (python, act_py, outfile) + cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (_python_, act_py, outfile) act = SCons.Action.CommandAction(cmd6) r = act(target = [Obj('111'), Obj('222')], @@ -1016,31 +1018,31 @@ class CommandActionTestCase(unittest.TestCase): r = act([], [], env.Copy(out = outfile)) assert r == expect_nonexecutable, "r == %d" % r - act = SCons.Action.CommandAction('%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 1, r - act = SCons.Action.CommandAction('@%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 1, r - act = SCons.Action.CommandAction('@-%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@-%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r - act = SCons.Action.CommandAction('-%s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('-%s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r - act = SCons.Action.CommandAction('@ %s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@ %s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 1, r - act = SCons.Action.CommandAction('@- %s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('@- %s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r - act = SCons.Action.CommandAction('- %s %s 1' % (python, exit_py)) + act = SCons.Action.CommandAction('- %s %s 1' % (_python_, exit_py)) r = act([], [], env) assert r == 0, r @@ -1074,7 +1076,7 @@ class CommandActionTestCase(unittest.TestCase): # test redirection operators def test_redirect(self, redir, stdout_msg, stderr_msg): - cmd = r'%s %s %s xyzzy %s' % (python, act_py, outfile, redir) + cmd = r'%s %s %s xyzzy %s' % (_python_, act_py, outfile, redir) # Write the output and error messages to files because # Windows can't handle strings that are too big in its # external environment (os.spawnve() returns EINVAL, @@ -1571,7 +1573,7 @@ class ListActionTestCase(unittest.TestCase): a([], [], Environment(s = self)) assert self.inc == 3, self.inc - cmd2 = r'%s %s %s syzygy' % (python, act_py, outfile) + cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile) def function2(target, source, env): open(env['out'], 'a').write("function2\n") @@ -1644,7 +1646,7 @@ class LazyActionTestCase(unittest.TestCase): a = SCons.Action.Action('$BAR') a([], [], env=Environment(BAR = f, s = self)) assert self.test == 1, self.test - cmd = r'%s %s %s lazy' % (python, act_py, outfile) + cmd = r'%s %s %s lazy' % (_python_, act_py, outfile) a([], [], env=Environment(BAR = cmd, s = self)) c = test.read(outfile, 'r') assert c == "act.py: 'lazy'\n", c diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 1cff9c6..47d2134 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -119,20 +119,22 @@ else: caller_dicts = {} -def caller(back=0): +def caller(*backlist): import traceback - tb = traceback.extract_stack(limit=3+back) - key = tb[1][:3] - try: - entry = caller_dicts[key] - except KeyError: - entry = caller_dicts[key] = {} - key = tb[0][:3] - try: - entry[key] = entry[key] + 1 - except KeyError: - entry[key] = 1 - return '%s:%d(%s)' % func_shorten(key) + if not backlist: + backlist = [0] + result = [] + for back in backlist: + tb = traceback.extract_stack(limit=3+back) + key = tb[1][:3] + try: + entry = caller_dicts[key] + except KeyError: + entry = caller_dicts[key] = {} + key = tb[0][:3] + entry[key] = entry.get(key, 0) + 1 + result.append('%s:%d(%s)' % func_shorten(key)) + return result def dump_caller_counts(file=sys.stdout): keys = caller_dicts.keys() diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index cb628b8..7513c0d 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -173,14 +173,34 @@ Touch = ActionFactory(touch_func, lambda file: 'Touch("%s")' % file) # Internal utility functions -def copyFunc(dest, source, env): - """Install a source file into a destination by copying it (and its - permission/mode bits).""" - shutil.copy2(source, dest) - st = os.stat(source) - os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) +def installFunc(dest, source, env): + """Install a source file or directory into a destination by copying, + (including copying permission/mode bits).""" + + if os.path.isdir(source): + if os.path.exists(dest): + if not os.path.isdir(dest): + raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source)) + else: + parent = os.path.split(dest)[0] + if not os.path.exists(parent): + os.makedirs(parent) + shutil.copytree(source, dest) + else: + shutil.copy2(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + return 0 +def installStr(dest, source, env): + source = str(source) + if os.path.isdir(source): + type = 'directory' + else: + type = 'file' + return 'Install %s: "%s" as "%s"' % (type, source, dest) + def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None): """Creates a new list from 'list' by first interpolating each element in the list using the 'env' dictionary and then calling f @@ -334,13 +354,14 @@ ConstructionEnvironment = { 'SCANNERS' : [], 'CONFIGUREDIR' : '#/.sconf_temp', 'CONFIGURELOG' : '#/config.log', - 'INSTALLSTR' : 'Install file: "$SOURCE" as "$TARGET"', 'CPPSUFFIXES' : SCons.Tool.CSuffixes, 'DSUFFIXES' : SCons.Tool.DSuffixes, + 'ENV' : {}, 'IDLSUFFIXES' : SCons.Tool.IDLSuffixes, + 'INSTALL' : installFunc, + 'INSTALLSTR' : installStr, + '_installStr' : installStr, 'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes, - 'ENV' : {}, - 'INSTALL' : copyFunc, '_concat' : _concat, '_defines' : _defines, '_stripixes' : _stripixes, diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index d76f71d..7aa1909 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -84,7 +84,11 @@ def installFunc(target, source, env): return install(target[0].path, source[0].path, env) def installString(target, source, env): - return env.subst_target_source(env['INSTALLSTR'], 0, target, source) + s = env.get('INSTALLSTR', '') + if callable(s): + return s(target[0].path, source[0].path, env) + else: + return env.subst_target_source(s, 0, target, source) installAction = SCons.Action.Action(installFunc, installString) @@ -742,21 +746,31 @@ class Base(SubstitutionEnvironment): # environment before calling the tools, because they may use # some of them during initialization. apply(self.Replace, (), kw) + keys = kw.keys() if options: + keys = keys + options.keys() options.Update(self) + save = {} + for k in keys: + try: + save[k] = self._dict[k] + except KeyError: + # No value may have been set if they tried to pass in a + # reserved variable name like TARGETS. + pass + if tools is None: tools = self._dict.get('TOOLS', None) if tools is None: tools = ['default'] apply_tools(self, tools, toolpath) - # Now re-apply the passed-in variables and customizable options + # Now restore the passed-in variables and customized options # to the environment, since the values the user set explicitly # should override any values set by the tools. - apply(self.Replace, (), kw) - if options: - options.Update(self) + for key, val in save.items(): + self._dict[key] = val ####################################################################### # Utility methods that are primarily for internal use by SCons. @@ -895,19 +909,19 @@ class Base(SubstitutionEnvironment): self._dict[key] = val else: try: - # Most straightforward: just try to add them - # together. This will work in most cases, when the - # original and new values are of compatible types. - self._dict[key] = orig + val - except TypeError: + # Check if the original looks like a dictionary. + # If it is, we can't just try adding the value because + # dictionaries don't have __add__() methods, and + # things like UserList will incorrectly coerce the + # original dict to a list (which we don't want). + update_dict = orig.update + except AttributeError: try: - # Try to update a dictionary value with another. - # If orig isn't a dictionary, it won't have an - # update() method; if val isn't a dictionary, - # it won't have a keys() method. Either way, - # it's an AttributeError. - orig.update(val) - except AttributeError: + # Most straightforward: just try to add them + # together. This will work in most cases, when the + # original and new values are of compatible types. + self._dict[key] = orig + val + except (KeyError, TypeError): try: # Check if the original is a list. add_to_orig = orig.append @@ -925,6 +939,17 @@ class Base(SubstitutionEnvironment): # value to it (if there's a value to append). if val: add_to_orig(val) + else: + # The original looks like a dictionary, so update it + # based on what we think the value looks like. + if SCons.Util.is_List(val): + for v in val: + orig[v] = None + else: + try: + update_dict(val) + except (AttributeError, TypeError, ValueError): + orig[val] = None self.scanner_map_delete(kw) def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): @@ -952,7 +977,7 @@ class Base(SubstitutionEnvironment): """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): - if not self._dict.has_key(key) or not self._dict[key]: + if not self._dict.has_key(key) or self._dict[key] in ('', None): self._dict[key] = val elif SCons.Util.is_Dict(self._dict[key]) and \ SCons.Util.is_Dict(val): @@ -1134,19 +1159,19 @@ class Base(SubstitutionEnvironment): self._dict[key] = val else: try: - # Most straightforward: just try to add them - # together. This will work in most cases, when the - # original and new values are of compatible types. - self._dict[key] = val + orig - except TypeError: + # Check if the original looks like a dictionary. + # If it is, we can't just try adding the value because + # dictionaries don't have __add__() methods, and + # things like UserList will incorrectly coerce the + # original dict to a list (which we don't want). + update_dict = orig.update + except AttributeError: try: - # Try to update a dictionary value with another. - # If orig isn't a dictionary, it won't have an - # update() method; if val isn't a dictionary, - # it won't have a keys() method. Either way, - # it's an AttributeError. - orig.update(val) - except AttributeError: + # Most straightforward: just try to add them + # together. This will work in most cases, when the + # original and new values are of compatible types. + self._dict[key] = val + orig + except (KeyError, TypeError): try: # Check if the added value is a list. add_to_val = val.append @@ -1164,6 +1189,17 @@ class Base(SubstitutionEnvironment): if orig: add_to_val(orig) self._dict[key] = val + else: + # The original looks like a dictionary, so update it + # based on what we think the value looks like. + if SCons.Util.is_List(val): + for v in val: + orig[v] = None + else: + try: + update_dict(val) + except (AttributeError, TypeError, ValueError): + orig[val] = None self.scanner_map_delete(kw) def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): @@ -1191,7 +1227,7 @@ class Base(SubstitutionEnvironment): """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): - if not self._dict.has_key(key) or not self._dict[key]: + if not self._dict.has_key(key) or self._dict[key] in ('', None): self._dict[key] = val elif SCons.Util.is_Dict(self._dict[key]) and \ SCons.Util.is_Dict(val): @@ -1504,25 +1540,37 @@ class Base(SubstitutionEnvironment): try: dnodes = self.arg2nodes(dir, self.fs.Dir) except TypeError: - raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir) + fmt = "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" + raise SCons.Errors.UserError, fmt % str(dir) try: - sources = self.arg2nodes(source, self.fs.File) + sources = self.arg2nodes(source, self.fs.Entry) except TypeError: if SCons.Util.is_List(source): - raise SCons.Errors.UserError, "Source `%s' of Install() contains one or more non-files. Install() source must be one or more files." % repr(map(str, source)) + s = repr(map(str, source)) else: - raise SCons.Errors.UserError, "Source `%s' of Install() is not a file. Install() source must be one or more files." % str(source) + s = str(source) + fmt = "Source `%s' of Install() is neither a file nor a directory. Install() source must be one or more files or directories" + raise SCons.Errors.UserError, fmt % s tgt = [] for dnode in dnodes: for src in sources: - target = self.fs.File(src.name, dnode) + target = self.fs.Entry(src.name, dnode) tgt.extend(InstallBuilder(self, target, src)) return tgt def InstallAs(self, target, source): """Install sources as targets.""" - sources = self.arg2nodes(source, self.fs.File) - targets = self.arg2nodes(target, self.fs.File) + sources = self.arg2nodes(source, self.fs.Entry) + targets = self.arg2nodes(target, self.fs.Entry) + if len(sources) != len(targets): + if not SCons.Util.is_List(target): + target = [target] + if not SCons.Util.is_List(source): + source = [source] + t = repr(map(str, target)) + s = repr(map(str, source)) + fmt = "Target (%s) and source (%s) lists of InstallAs() must be the same length." + raise SCons.Errors.UserError, fmt % (t, s) result = [] for src, tgt in map(lambda x, y: (x, y), sources, targets): result.extend(InstallBuilder(self, tgt, src)) @@ -1632,10 +1680,10 @@ class Base(SubstitutionEnvironment): else: raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type - def Value(self, value): + def Value(self, value, built_value=None): """ """ - return SCons.Node.Python.Value(value) + return SCons.Node.Python.Value(value, built_value) class OverrideEnvironment(Base): """A proxy that overrides variables in a wrapped construction diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index c56f1f5..52aac23 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -23,6 +23,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import copy import os import string import StringIO @@ -595,15 +596,17 @@ sys.exit(1) save_stderr = sys.stderr + python = '"' + sys.executable + '"' + try: - cmd = '%s %s' % (sys.executable, test.workpath('stdout.py')) + cmd = '%s %s' % (python, test.workpath('stdout.py')) output = env.backtick(cmd) assert output == 'this came from stdout.py\n', output sys.stderr = StringIO.StringIO() - cmd = '%s %s' % (sys.executable, test.workpath('stderr.py')) + cmd = '%s %s' % (python, test.workpath('stderr.py')) output = env.backtick(cmd) errout = sys.stderr.getvalue() @@ -612,7 +615,7 @@ sys.exit(1) sys.stderr = StringIO.StringIO() - cmd = '%s %s' % (sys.executable, test.workpath('fail.py')) + cmd = '%s %s' % (python, test.workpath('fail.py')) try: env.backtick(cmd) except OSError, e: @@ -747,6 +750,24 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert not env1.has_key('__env__') assert not env2.has_key('__env__') + def test_options(self): + """Test that options only get applied once.""" + class FakeOptions: + def __init__(self, key, val): + self.calls = 0 + self.key = key + self.val = val + def keys(self): + return [self.key] + def Update(self, env): + env[self.key] = self.val + self.calls = self.calls + 1 + + o = FakeOptions('AAA', 'fake_opt') + env = Environment(options=o, AAA='keyword_arg') + assert o.calls == 1, o.calls + assert env['AAA'] == 'fake_opt', env['AAA'] + def test_get(self): """Test the get() method.""" env = self.TestEnvironment(aaa = 'AAA') @@ -1212,6 +1233,8 @@ def exists(env): b2 = Environment()['BUILDERS'] assert b1 == b2, diff_dict(b1, b2) + import UserDict + UD = UserDict.UserDict import UserList UL = UserList.UserList @@ -1243,6 +1266,18 @@ def exists(env): UL(['i7']), [''], UL(['i7', '']), UL(['i8']), UL(['']), UL(['i8', '']), + {'d1':1}, 'D1', {'d1':1, 'D1':None}, + {'d2':1}, ['D2'], {'d2':1, 'D2':None}, + {'d3':1}, UL(['D3']), {'d3':1, 'D3':None}, + {'d4':1}, {'D4':1}, {'d4':1, 'D4':1}, + {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}), + + UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}), + UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}), + UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}), + UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}), + UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}), + '', 'M1', 'M1', '', ['M2'], ['M2'], '', UL(['M3']), UL(['M3']), @@ -1293,14 +1328,21 @@ def exists(env): failed = 0 while cases: input, append, expect = cases[:3] - env['XXX'] = input - env.Append(XXX = append) - result = env['XXX'] - if result != expect: + env['XXX'] = copy.copy(input) + try: + env.Append(XXX = append) + except Exception, e: if failed == 0: print - print " %s Append %s => %s did not match %s" % \ - (repr(input), repr(append), repr(result), repr(expect)) + print " %s Append %s exception: %s" % \ + (repr(input), repr(append), e) failed = failed + 1 + else: + result = env['XXX'] + if result != expect: + if failed == 0: print + print " %s Append %s => %s did not match %s" % \ + (repr(input), repr(append), repr(result), repr(expect)) + failed = failed + 1 del cases[:3] assert failed == 0, "%d Append() cases failed" % failed @@ -1399,6 +1441,33 @@ def exists(env): assert env['CCC1'] == 'c1', env['CCC1'] assert env['CCC2'] == ['c2'], env['CCC2'] + env['CLVar'] = CLVar([]) + env.AppendUnique(CLVar = 'bar') + result = env['CLVar'] + if sys.version[0] == '1': + # Python 1.5.2 has a quirky behavior where CLVar([]) actually + # matches '' and [] due to different __coerce__() semantics + # in the UserList implementation. It isn't worth a lot of + # effort to get this corner case to work identically (support + # for Python 1.5 support will die soon anyway), so just treat + # it separately for now. + assert result == 'bar', result + else: + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + + env['CLVar'] = CLVar(['abc']) + env.AppendUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['abc', 'bar'], result + + env['CLVar'] = CLVar(['bar']) + env.AppendUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + def test_Copy(self): """Test construction environment copying @@ -1784,6 +1853,8 @@ f5: \ def test_Prepend(self): """Test prepending to construction variables in an Environment """ + import UserDict + UD = UserDict.UserDict import UserList UL = UserList.UserList @@ -1815,6 +1886,18 @@ f5: \ UL(['i7']), [''], UL(['', 'i7']), UL(['i8']), UL(['']), UL(['', 'i8']), + {'d1':1}, 'D1', {'d1':1, 'D1':None}, + {'d2':1}, ['D2'], {'d2':1, 'D2':None}, + {'d3':1}, UL(['D3']), {'d3':1, 'D3':None}, + {'d4':1}, {'D4':1}, {'d4':1, 'D4':1}, + {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}), + + UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}), + UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}), + UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}), + UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}), + UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}), + '', 'M1', 'M1', '', ['M2'], ['M2'], '', UL(['M3']), UL(['M3']), @@ -1865,14 +1948,21 @@ f5: \ failed = 0 while cases: input, prepend, expect = cases[:3] - env['XXX'] = input - env.Prepend(XXX = prepend) - result = env['XXX'] - if result != expect: + env['XXX'] = copy.copy(input) + try: + env.Prepend(XXX = prepend) + except Exception, e: if failed == 0: print - print " %s Prepend %s => %s did not match %s" % \ - (repr(input), repr(prepend), repr(result), repr(expect)) + print " %s Prepend %s exception: %s" % \ + (repr(input), repr(prepend), e) failed = failed + 1 + else: + result = env['XXX'] + if result != expect: + if failed == 0: print + print " %s Prepend %s => %s did not match %s" % \ + (repr(input), repr(prepend), repr(result), repr(expect)) + failed = failed + 1 del cases[:3] assert failed == 0, "%d Prepend() cases failed" % failed @@ -1965,6 +2055,33 @@ f5: \ assert env['CCC1'] == 'c1', env['CCC1'] assert env['CCC2'] == ['c2'], env['CCC2'] + env['CLVar'] = CLVar([]) + env.PrependUnique(CLVar = 'bar') + result = env['CLVar'] + if sys.version[0] == '1': + # Python 1.5.2 has a quirky behavior where CLVar([]) actually + # matches '' and [] due to different __coerce__() semantics + # in the UserList implementation. It isn't worth a lot of + # effort to get this corner case to work identically (support + # for Python 1.5 support will die soon anyway), so just treat + # it separately for now. + assert result == 'bar', result + else: + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + + env['CLVar'] = CLVar(['abc']) + env.PrependUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['bar', 'abc'], result + + env['CLVar'] = CLVar(['bar']) + env.PrependUnique(CLVar = 'bar') + result = env['CLVar'] + assert isinstance(result, CLVar), repr(result) + assert result == ['bar'], result + def test_Replace(self): """Test replacing construction variables in an Environment @@ -2650,23 +2767,23 @@ def generate(env): for tnode in tgt: assert tnode.builder == InstallBuilder - exc_caught = None - try: - tgt = env.Install('export', 'export') - except SCons.Errors.UserError, e: - exc_caught = 1 - assert exc_caught, "UserError should be thrown when Install() target is not a file." - match = str(e) == "Source `export' of Install() is not a file. Install() source must be one or more files." - assert match, e + tgt = env.Install('export', 'build') + paths = map(str, tgt) + paths.sort() + expect = ['export/build'] + assert paths == expect, paths + for tnode in tgt: + assert tnode.builder == InstallBuilder - exc_caught = None - try: - tgt = env.Install('export', ['export', 'build/foo1']) - except SCons.Errors.UserError, e: - exc_caught = 1 - assert exc_caught, "UserError should be thrown when Install() target containins non-files." - match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files. Install() source must be one or more files." - assert match, e + tgt = env.Install('export', ['build', 'build/foo1']) + paths = map(str, tgt) + paths.sort() + expect = ['export/build', 'export/foo1'] + assert paths == expect, paths + for tnode in tgt: + assert tnode.builder == InstallBuilder + + env.File('export/foo1') exc_caught = None try: @@ -2674,8 +2791,8 @@ def generate(env): except SCons.Errors.UserError, e: exc_caught = 1 assert exc_caught, "UserError should be thrown reversing the order of Install() targets." - match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" - assert match, e + expect = "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" + assert str(e) == expect, e def test_InstallAs(self): """Test the InstallAs method""" @@ -2956,6 +3073,9 @@ def generate(env): assert not v1 is v2 assert v1.value == v2.value + v3 = env.Value('c', 'build-c') + assert v3.value == 'c', v3.value + def test_Environment_global_variable(type): diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index 134206f..c2a3027 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.py @@ -798,9 +798,14 @@ else: # Make sure filename has os.sep+'SCons'+os.sep so that # SCons.Script.find_deepest_user_frame doesn't stop here import inspect # It's OK, can't get here for Python < 2.1 + filename = inspect.getsourcefile(_MeMoIZeR_superinit) + if not filename: + # This file was compiled at a path name different from + # how it's invoked now, so just make up something. + filename = whoami('superinit', '???') superinitcode = compile( "lambda self, *args, **kw: MPI(self, cls, args, kw)", - inspect.getsourcefile(_MeMoIZeR_superinit) or '', + filename, "eval") superinit = eval(superinitcode, {'cls':cls, diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index ce5bcc0..382bca3 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -95,10 +95,33 @@ def save_strings(val): # there should be *no* changes to the external file system(s)... # -def _copy_func(src, dest): +if hasattr(os, 'link'): + def _hardlink_func(fs, src, dst): + # If the source is a symlink, we can't just hard-link to it + # because a relative symlink may point somewhere completely + # different. We must disambiguate the symlink and then + # hard-link the final destination file. + while fs.islink(src): + link = fs.readlink(src) + if not os.path.isabs(link): + src = link + else: + src = os.path.join(os.path.dirname(src), link) + fs.link(src, dst) +else: + _hardlink_func = None + +if hasattr(os, 'symlink'): + def _softlink_func(fs, src, dst): + fs.symlink(src, dst) +else: + _softlink_func = None + +def _copy_func(fs, src, dest): shutil.copy2(src, dest) - st=os.stat(src) - os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + st = fs.stat(src) + fs.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + Valid_Duplicates = ['hard-soft-copy', 'soft-hard-copy', 'hard-copy', 'soft-copy', 'copy'] @@ -113,16 +136,6 @@ def set_duplicate(duplicate): # underlying implementations. We do this inside this function, # not in the top-level module code, so that we can remap os.link # and os.symlink for testing purposes. - try: - _hardlink_func = os.link - except AttributeError: - _hardlink_func = None - - try: - _softlink_func = os.symlink - except AttributeError: - _softlink_func = None - link_dict = { 'hard' : _hardlink_func, 'soft' : _softlink_func, @@ -152,10 +165,11 @@ def LinkFunc(target, source, env): if not Link_Funcs: # Set a default order of link functions. set_duplicate('hard-soft-copy') + fs = source[0].fs # Now link the files with the previously specified order. for func in Link_Funcs: try: - func(src,dest) + func(fs, src, dest) break except (IOError, OSError): # An OSError indicates something happened like a permissions @@ -213,13 +227,15 @@ def CacheRetrieveFunc(target, source, env): t = target[0] fs = t.fs cachedir, cachefile = t.cachepath() - if fs.exists(cachefile): - if SCons.Action.execute_actions: - fs.copy2(cachefile, t.path) - st = fs.stat(cachefile) - fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) - return 0 - return 1 + if not fs.exists(cachefile): + fs.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile) + return 1 + fs.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile) + if SCons.Action.execute_actions: + fs.copy2(cachefile, t.path) + st = fs.stat(cachefile) + fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + return 0 def CacheRetrieveString(target, source, env): t = target[0] @@ -237,9 +253,18 @@ def CachePushFunc(target, source, env): fs = t.fs cachedir, cachefile = t.cachepath() if fs.exists(cachefile): - # Don't bother copying it if it's already there. + # Don't bother copying it if it's already there. Note that + # usually this "shouldn't happen" because if the file already + # existed in cache, we'd have retrieved the file from there, + # not built it. This can happen, though, in a race, if some + # other person running the same build pushes their copy to + # the cache after we decide we need to build it but before our + # build completes. + fs.CacheDebug('CachePush(%s): %s already exists in cache\n', t, cachefile) return + fs.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile) + if not fs.isdir(cachedir): fs.makedirs(cachedir) @@ -258,7 +283,6 @@ def CachePushFunc(target, source, env): SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning, "Unable to copy %s to cache. Cache file is %s" % (str(target), cachefile)) - return CachePush = SCons.Action.Action(CachePushFunc, None) @@ -835,6 +859,14 @@ class LocalFS: def islink(self, path): return 0 # no symlinks + if hasattr(os, 'readlink'): + def readlink(self, file): + return os.readlink(file) + else: + def readlink(self, file): + return '' + + if SCons.Memoize.use_old_memoization(): _FSBase = LocalFS class LocalFS(SCons.Memoize.Memoizer, _FSBase): @@ -1139,6 +1171,21 @@ class FS(LocalFS): result.extend(dir.get_all_rdirs()) return result + def CacheDebugWrite(self, fmt, target, cachefile): + self.CacheDebugFP.write(fmt % (target, os.path.split(cachefile)[1])) + + def CacheDebugQuiet(self, fmt, target, cachefile): + pass + + CacheDebug = CacheDebugQuiet + + def CacheDebugEnable(self, file): + if file == '-': + self.CacheDebugFP = sys.stdout + else: + self.CacheDebugFP = open(file, 'w') + self.CacheDebug = self.CacheDebugWrite + def CacheDir(self, path): self.CachePath = path @@ -1776,7 +1823,7 @@ class File(Base): __cacheable__""" if not scanner: return [] - return map(lambda N: N.disambiguate(), scanner(self, env, path)) + return scanner(self, env, path) def _createDir(self): # ensure that the directories for this node are @@ -1818,11 +1865,14 @@ class File(Base): if self.fs.cache_show: if CacheRetrieveSilent(self, [], None, execute=1) == 0: self.build(presub=0, execute=0) + self.set_state(SCons.Node.executed) return 1 elif CacheRetrieve(self, [], None, execute=1) == 0: + self.set_state(SCons.Node.executed) return 1 return None + def built(self): """Called just after this node is successfully built. __cache_reset__""" diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 98e08a9..1b38ffe 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -425,57 +425,39 @@ class BuildDirTestCase(unittest.TestCase): class LinkSimulator : """A class to intercept os.[sym]link() calls and track them.""" - def __init__( self, duplicate ) : + def __init__( self, duplicate, link, symlink, copy ) : self.duplicate = duplicate - self._reset() - - def _reset( self ) : - """Reset the simulator if necessary""" - if not self._need_reset() : return # skip if not needed now - self.links_to_be_called = self.duplicate - - def _need_reset( self ) : - """ - Determines whether or not the simulator needs to be reset. - A reset is necessary if the object is first being initialized, - or if all three methods have been tried already. - """ - return ( - ( not hasattr( self , "links_to_be_called" ) ) - or - (self.links_to_be_called == "") - ) + self.have = {} + self.have['hard'] = link + self.have['soft'] = symlink + self.have['copy'] = copy + + self.links_to_be_called = [] + for link in string.split(self.duplicate, '-'): + if self.have[link]: + self.links_to_be_called.append(link) def link_fail( self , src , dest ) : - self._reset() - l = string.split(self.links_to_be_called, "-") - next_link = l[0] - assert next_link == "hard", \ + next_link = self.links_to_be_called.pop(0) + assert next_link == "hard", \ "Wrong link order: expected %s to be called "\ "instead of hard" % next_link - self.links_to_be_called = string.join(l[1:], '-') raise OSError( "Simulating hard link creation error." ) def symlink_fail( self , src , dest ) : - self._reset() - l = string.split(self.links_to_be_called, "-") - next_link = l[0] - assert next_link == "soft", \ + next_link = self.links_to_be_called.pop(0) + assert next_link == "soft", \ "Wrong link order: expected %s to be called "\ "instead of soft" % next_link - self.links_to_be_called = string.join(l[1:], '-') raise OSError( "Simulating symlink creation error." ) def copy( self , src , dest ) : - self._reset() - l = string.split(self.links_to_be_called, "-") - next_link = l[0] - assert next_link == "copy", \ + next_link = self.links_to_be_called.pop(0) + assert next_link == "copy", \ "Wrong link order: expected %s to be called "\ "instead of copy" % next_link - self.links_to_be_called = string.join(l[1:], '-') # copy succeeds, but use the real copy - self._real_copy(src, dest) + self.have['copy'](src, dest) # end class LinkSimulator try: @@ -485,32 +467,31 @@ class BuildDirTestCase(unittest.TestCase): pass for duplicate in SCons.Node.FS.Valid_Duplicates: - simulator = LinkSimulator(duplicate) - # save the real functions for later restoration - real_link = None - real_symlink = None try: real_link = os.link except AttributeError: - pass + real_link = None try: real_symlink = os.symlink except AttributeError: - pass + real_symlink = None real_copy = shutil.copy2 - simulator._real_copy = real_copy # the simulator needs the real one + + simulator = LinkSimulator(duplicate, real_link, real_symlink, real_copy) # override the real functions with our simulation os.link = simulator.link_fail os.symlink = simulator.symlink_fail shutil.copy2 = simulator.copy - SCons.Node.FS.set_duplicate(duplicate) - - src_foo = test.workpath('src', 'foo') - build_foo = test.workpath('build', 'foo') try: + + SCons.Node.FS.set_duplicate(duplicate) + + src_foo = test.workpath('src', 'foo') + build_foo = test.workpath('build', 'foo') + test.write(src_foo, 'src/foo\n') os.chmod(src_foo, stat.S_IRUSR) try: diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 99dc5b0..a639aee 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -45,16 +45,18 @@ class Value(SCons.Node.Node): NodeInfo = ValueNodeInfo BuildInfo = ValueBuildInfo - def __init__(self, value): + def __init__(self, value, built_value=None): SCons.Node.Node.__init__(self) self.value = value + if not built_value is None: + self.built_value = built_value def __str__(self): return repr(self.value) - def build(self): - """A "builder" for Values.""" - pass + def build(self, **kw): + if not hasattr(self, 'built_value'): + apply (SCons.Node.Node.build, (self,), kw) current = SCons.Node.Node.children_are_up_to_date @@ -64,9 +66,23 @@ class Value(SCons.Node.Node): # are outside the filesystem: return 1 + def write(self, built_value): + """Set the value of the node.""" + self.built_value = built_value + + def read(self): + """Return the value. If necessary, the value is built.""" + self.build() + if not hasattr(self, 'built_value'): + self.built_value = self.value + return self.built_value + def get_contents(self): - """The contents of a Value are the concatenation - of all the contents of its sources with the node's value itself.""" + """By the assumption that the node.built_value is a + deterministic product of the sources, the contents of a Value + are the concatenation of all the contents of its sources. As + the value need not be built when get_contents() is called, we + cannot use the actual node.built_value.""" contents = str(self.value) for kid in self.children(None): contents = contents + kid.get_contents() diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 0801fb3..62bcf8b 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -45,6 +45,44 @@ class ValueTestCase(unittest.TestCase): assert not v1 is v2 assert v1.value == v2.value + v3 = SCons.Node.Python.Value('c', 'cb') + assert v3.built_value == 'cb' + + def test_build(self): + """Test "building" a Value Node + """ + class fake_executor: + def __call__(self, node, exitstatfunc): + node.write('faked') + + v1 = SCons.Node.Python.Value('b', 'built') + v1.executor = fake_executor() + v1.build() + assert v1.built_value == 'built', v1.built_value + + v2 = SCons.Node.Python.Value('b') + v2.executor = fake_executor() + v2.build() + assert v2.built_value == 'faked', v2.built_value + + def test_read(self): + """Test the Value.read() method + """ + v1 = SCons.Node.Python.Value('a') + x = v1.read() + assert x == 'a', x + + def test_write(self): + """Test the Value.write() method + """ + v1 = SCons.Node.Python.Value('a') + assert v1.value == 'a', v1.value + assert not hasattr(v1, 'built_value') + + v1.write('new') + assert v1.value == 'a', v1.value + assert v1.built_value == 'new', v1.built_value + def test_get_csig(self): """Test calculating the content signature of a Value() object """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index bda3a48..42be5b1 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -474,6 +474,7 @@ class Node: d = filter(lambda x, seen=seen: not seen.has_key(x), n.get_found_includes(env, scanner, path)) if d: + d = map(lambda N: N.disambiguate(), d) deps.extend(d) for n in d: seen[n] = 1 @@ -538,7 +539,7 @@ class Node: # Here's where we implement --implicit-cache. if implicit_cache and not implicit_deps_changed: implicit = self.get_stored_implicit() - if implicit: + if implicit is not None: factory = build_env.get_factory(self.builder.source_factory) nodes = [] for i in implicit: diff --git a/src/engine/SCons/Options/ListOption.py b/src/engine/SCons/Options/ListOption.py index d14b22a..5aa508a 100644 --- a/src/engine/SCons/Options/ListOption.py +++ b/src/engine/SCons/Options/ListOption.py @@ -65,7 +65,7 @@ class _ListOption(UserList.UserList): UserList.UserList.__init__(self, filter(None, initlist)) self.allowedElems = allowedElems[:] self.allowedElems.sort() - + def __cmp__(self, other): raise NotImplementedError def __eq__(self, other): @@ -88,7 +88,7 @@ class _ListOption(UserList.UserList): return string.join(self, ',') def __repr__(self): return self.__str__() - + def _converter(val, allowedElems, mapdict): """ """ diff --git a/src/engine/SCons/Options/ListOptionTests.py b/src/engine/SCons/Options/ListOptionTests.py index a892e18..22378bc 100644 --- a/src/engine/SCons/Options/ListOptionTests.py +++ b/src/engine/SCons/Options/ListOptionTests.py @@ -122,9 +122,6 @@ class ListOptionTestCase(unittest.TestCase): l = o.converter('all') n = l.__class__(copy.copy(l)) - def test___repr__(self): - """Test copying a ListOption like an Environment would""" - if __name__ == "__main__": suite = unittest.makeSuite(ListOptionTestCase, 'test_') if not unittest.TextTestRunner().run(suite).wasSuccessful(): diff --git a/src/engine/SCons/Options/OptionsTests.py b/src/engine/SCons/Options/OptionsTests.py index aeffe2d..1d9b851 100644 --- a/src/engine/SCons/Options/OptionsTests.py +++ b/src/engine/SCons/Options/OptionsTests.py @@ -59,6 +59,19 @@ def checkSave(file, expected): class OptionsTestCase(unittest.TestCase): + def test_keys(self): + """Test the Options.keys() method""" + opts = SCons.Options.Options() + + opts.Add('VAR1') + opts.Add('VAR2', + 'THE answer to THE question', + "42", + check, + lambda x: int(x) + 12) + keys = opts.keys() + assert keys == ['VAR1', 'VAR2'], keys + def test_Add(self): """Test adding to an Options object""" opts = SCons.Options.Options() diff --git a/src/engine/SCons/Options/__init__.py b/src/engine/SCons/Options/__init__.py index 7333985..83798b3 100644 --- a/src/engine/SCons/Options/__init__.py +++ b/src/engine/SCons/Options/__init__.py @@ -76,6 +76,11 @@ class Options: self.options.append(option) + def keys(self): + """ + Returns the keywords for the options + """ + return map(lambda o: o.key, self.options) def Add(self, key, help="", default=None, validator=None, converter=None, **kw): """ @@ -100,7 +105,6 @@ class Options: self._do_add(key, help, default, validator, converter) - def AddOptions(self, *optlist): """ Add a list of options. diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index 675167e..1d4e9f7 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -70,7 +70,7 @@ def exec_spawnvpe(l, env): # returned by os.waitpid() or os.system(). return stat -def exec_fork(l, env): +def exec_fork(l, env): pid = os.fork() if not pid: # Child process. @@ -78,7 +78,7 @@ def exec_fork(l, env): try: os.execvpe(l[0], l, env) except OSError, e: - exitval = exitvalmap[e[0]] + exitval = exitvalmap.get(e[0], e[0]) sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) os._exit(exitval) else: @@ -159,7 +159,7 @@ def exec_piped_fork(l, env, stdout, stderr): try: os.execvpe(l[0], l, env) except OSError, e: - exitval = exitvalmap[e[0]] + exitval = exitvalmap.get(e[0], e[0]) stderr.write("scons: %s: %s\n" % (l[0], e[1])) os._exit(exitval) else: diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 6188098..148d9df 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -90,7 +90,11 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): ret = os.spawnve(os.P_WAIT, sh, args, env) except OSError, e: # catch any error - ret = exitvalmap[e[0]] + try: + ret = exitvalmap[e[0]] + except KeyError: + result = 127 + sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e[0], cmd, e[1])) if stderr != None: stderr.write("scons: %s: %s\n" % (cmd, e[1])) # copy child output from tempfiles to our streams @@ -114,8 +118,19 @@ def exec_spawn(l, env): try: result = os.spawnve(os.P_WAIT, l[0], l, env) except OSError, e: - result = exitvalmap[e[0]] - sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) + try: + result = exitvalmap[e[0]] + sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) + except KeyError: + result = 127 + if len(l) > 2: + if len(l[2]) < 1000: + command = string.join(l[0:3]) + else: + command = l[0] + else: + command = l[0] + sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e[0], command, e[1])) return result def spawn(sh, escape, cmd, args, env): @@ -124,9 +139,15 @@ def spawn(sh, escape, cmd, args, env): return 127 return exec_spawn([sh, '/C', escape(string.join(args))], env) -# Windows does not allow special characters in file names anyway, so -# no need for a complex escape function, we will just quote the arg. -escape = lambda x: '"' + x + '"' +# Windows does not allow special characters in file names anyway, so no +# need for a complex escape function, we will just quote the arg, except +# that "cmd /c" requires that if an argument ends with a backslash it +# needs to be escaped so as not to interfere with closing double quote +# that we add. +def escape(x): + if x[-1] == '\\': + x = x + '\\' + return '"' + x + '"' # Get the windows system directory name def get_system_root(): diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py index c57e7f7..2ca522b 100644 --- a/src/engine/SCons/Scanner/CTests.py +++ b/src/engine/SCons/Scanner/CTests.py @@ -221,6 +221,7 @@ def deps_match(self, deps, headers): class CScannerTestCase1(unittest.TestCase): def runTest(self): + """Find local files with no CPPPATH""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -230,6 +231,7 @@ class CScannerTestCase1(unittest.TestCase): class CScannerTestCase2(unittest.TestCase): def runTest(self): + """Find a file in a CPPPATH directory""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -239,6 +241,7 @@ class CScannerTestCase2(unittest.TestCase): class CScannerTestCase3(unittest.TestCase): def runTest(self): + """Find files in explicit subdirectories, ignore missing file""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -248,6 +251,7 @@ class CScannerTestCase3(unittest.TestCase): class CScannerTestCase4(unittest.TestCase): def runTest(self): + """Find files in explicit subdirectories""" env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -257,6 +261,7 @@ class CScannerTestCase4(unittest.TestCase): class CScannerTestCase5(unittest.TestCase): def runTest(self): + """Make sure files in repositories will get scanned""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -280,6 +285,7 @@ class CScannerTestCase5(unittest.TestCase): class CScannerTestCase6(unittest.TestCase): def runTest(self): + """Find a same-named file in different directories when CPPPATH changes""" env1 = DummyEnvironment(CPPPATH=[test.workpath("d1")]) env2 = DummyEnvironment(CPPPATH=[test.workpath("d1/d2")]) s = SCons.Scanner.C.CScanner() @@ -294,6 +300,7 @@ class CScannerTestCase6(unittest.TestCase): class CScannerTestCase8(unittest.TestCase): def runTest(self): + """Find files in a subdirectory relative to the current directory""" env = DummyEnvironment(CPPPATH=["include"]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -310,6 +317,7 @@ class CScannerTestCase8(unittest.TestCase): class CScannerTestCase9(unittest.TestCase): def runTest(self): + """Generate a warning when we can't find a #included file""" SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: def __call__(self, x): @@ -334,6 +342,7 @@ class CScannerTestCase9(unittest.TestCase): class CScannerTestCase10(unittest.TestCase): def runTest(self): + """Find files in the local directory when the scanned file is elsewhere""" fs = SCons.Node.FS.FS(test.workpath('')) fs.chdir(fs.Dir('include')) env = DummyEnvironment(CPPPATH=[]) @@ -348,6 +357,7 @@ class CScannerTestCase10(unittest.TestCase): class CScannerTestCase11(unittest.TestCase): def runTest(self): + """Handle dependencies on a derived .h file in a non-existent directory""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.Repository(test.workpath('repository')) @@ -367,6 +377,7 @@ class CScannerTestCase11(unittest.TestCase): class CScannerTestCase12(unittest.TestCase): def runTest(self): + """Find files in BuildDir() directories""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.BuildDir('build1', 'src', 1) @@ -388,6 +399,7 @@ class CScannerTestCase12(unittest.TestCase): class CScannerTestCase13(unittest.TestCase): def runTest(self): + """Find files in directories named in a substituted environment variable""" class SubstEnvironment(DummyEnvironment): def subst(self, arg, test=test): return test.workpath("d1") @@ -400,6 +412,7 @@ class CScannerTestCase13(unittest.TestCase): class CScannerTestCase14(unittest.TestCase): def runTest(self): + """Find files when there's no space between "#include" and the name""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() path = s.path(env) @@ -409,6 +422,7 @@ class CScannerTestCase14(unittest.TestCase): class CScannerTestCase15(unittest.TestCase): def runTest(self): + """Verify scanner initialization with the suffixes in $CPPSUFFIXES""" suffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", ".F", ".fpp", ".FPP", diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 73f96e2..2c18112 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -588,29 +588,29 @@ def _create_path(plist): path = path + '/' + d return path +def version_string(label, module): + fmt = "\t%s: v%s.%s, %s, by %s on %s\n" + return fmt % (label, + module.__version__, + module.__build__, + module.__date__, + module.__developer__, + module.__buildsys__) class OptParser(OptionParser): def __init__(self): import __main__ - import SCons + parts = ["SCons by Steven Knight et al.:\n"] try: - parts.append("\tscript: v%s.%s, %s, by %s on %s\n" % (__main__.__version__, - __main__.__build__, - __main__.__date__, - __main__.__developer__, - __main__.__buildsys__)) + parts.append(version_string("script", __main__)) except KeyboardInterrupt: raise except: # On Windows there is no scons.py, so there is no # __main__.__version__, hence there is no script version. pass - parts.append("\tengine: v%s.%s, %s, by %s on %s\n" % (SCons.__version__, - SCons.__build__, - SCons.__date__, - SCons.__developer__, - SCons.__buildsys__)) + parts.append(version_string("engine", SCons)) parts.append("__COPYRIGHT__") OptionParser.__init__(self, version=string.join(parts, ''), usage="usage: scons [OPTION] [TARGET] ...") @@ -630,6 +630,10 @@ class OptParser(OptionParser): metavar="DIR", help="Change to DIR before doing anything.") + self.add_option('--cache-debug', action="store", + dest="cache_debug", metavar="FILE", + help="Print CacheDir debug info to FILE.") + self.add_option('--cache-disable', '--no-cache', action="store_true", dest='cache_disable', default=0, help="Do not retrieve built targets from CacheDir.") @@ -1048,6 +1052,9 @@ def _main(args, parser): display.set_mode(0) if options.silent: SCons.Action.print_actions = None + + if options.cache_debug: + fs.CacheDebugEnable(options.cache_debug) if options.cache_disable: def disable(self): pass fs.CacheDir = disable @@ -1291,8 +1298,21 @@ def _exec_main(): import pdb pdb.Pdb().runcall(_main, args, parser) elif options.profile_file: - import profile - prof = profile.Profile() + from profile import Profile + + # Some versions of Python 2.4 shipped a profiler that had the + # wrong 'c_exception' entry in its dispatch table. Make sure + # we have the right one. (This may put an unnecessary entry + # in the table in earlier versions of Python, but its presence + # shouldn't hurt anything). + try: + dispatch = Profile.dispatch + except AttributeError: + pass + else: + dispatch['c_exception'] = Profile.trace_dispatch_return + + prof = Profile() try: prof.runcall(_main, args, parser) except SystemExit: diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index f932d30..dc896a0 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -176,7 +176,7 @@ def _SConscript(fs, *files, **kw): # fs match so we can open the SConscript. fs.chdir(top, change_os_dir=1) if f.rexists(): - _file_ = open(f.rstr(), "r") + _file_ = open(f.rfile().get_abspath(), "r") elif f.has_src_builder(): # The SConscript file apparently exists in a source # code management system. Build it, but then clear @@ -185,7 +185,7 @@ def _SConscript(fs, *files, **kw): f.build() f.builder_set(None) if f.exists(): - _file_ = open(str(f), "r") + _file_ = open(f.get_abspath(), "r") if _file_: # Chdir to the SConscript directory. Use a path # name relative to the SConstruct file so that if @@ -197,7 +197,18 @@ def _SConscript(fs, *files, **kw): # where the SConstruct and SConscript files might be # in different Repositories. For now, cross that # bridge when someone comes to it. - ldir = fs.Dir(f.dir.get_path(sd)) + try: + src_dir = kw['src_dir'] + except KeyError: + ldir = fs.Dir(f.dir.get_path(sd)) + else: + ldir = fs.Dir(src_dir) + if not ldir.is_under(f.dir): + # They specified a source directory, but + # it's above the SConscript directory. + # Do the sensible thing and just use the + # SConcript directory. + ldir = fs.Dir(f.dir.get_path(sd)) try: fs.chdir(ldir, change_os_dir=sconscript_chdir) except OSError: @@ -208,6 +219,7 @@ def _SConscript(fs, *files, **kw): # interpret the stuff within the SConscript file # relative to where we are logically. fs.chdir(ldir, change_os_dir=0) + # TODO Not sure how to handle src_dir here os.chdir(f.rfile().dir.get_abspath()) # Append the SConscript directory to the beginning @@ -223,7 +235,16 @@ def _SConscript(fs, *files, **kw): # SConscript can base the printed frames at this # level and not show SCons internals as well. call_stack[-1].globals.update({stack_bottom:1}) - exec _file_ in call_stack[-1].globals + old_file = call_stack[-1].globals.get('__file__') + try: + del call_stack[-1].globals['__file__'] + except KeyError: + pass + try: + exec _file_ in call_stack[-1].globals + finally: + if old_file is not None: + call_stack[-1].globals.update({__file__:old_file}) else: SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning, "Ignoring missing SConscript '%s'" % f.path) @@ -374,6 +395,7 @@ class SConsEnvironment(SCons.Environment.Base): src_dir = kw.get('src_dir') if not src_dir: src_dir, fname = os.path.split(str(files[0])) + files = [os.path.join(str(build_dir), fname)] else: if not isinstance(src_dir, SCons.Node.Node): src_dir = self.fs.Dir(src_dir) @@ -383,11 +405,11 @@ class SConsEnvironment(SCons.Environment.Base): if fn.is_under(src_dir): # Get path relative to the source directory. fname = fn.get_path(src_dir) + files = [os.path.join(str(build_dir), fname)] else: - # Fast way to only get the terminal path component of a Node. - fname = fn.get_path(fn.dir) + files = [fn.abspath] + kw['src_dir'] = build_dir self.fs.BuildDir(build_dir, src_dir, duplicate) - files = [os.path.join(str(build_dir), fname)] return (files, exports) @@ -490,8 +512,8 @@ class SConsEnvironment(SCons.Environment.Base): subst_kw[key] = val files, exports = self._get_SConscript_filenames(ls, subst_kw) - - return apply(_SConscript, [self.fs,] + files, {'exports' : exports}) + subst_kw['exports'] = exports + return apply(_SConscript, [self.fs,] + files, subst_kw) def SConscriptChdir(self, flag): global sconscript_chdir diff --git a/src/engine/SCons/Tool/as.py b/src/engine/SCons/Tool/as.py index 5a267a5..1b1b4b3 100644 --- a/src/engine/SCons/Tool/as.py +++ b/src/engine/SCons/Tool/as.py @@ -52,11 +52,15 @@ def generate(env): for suffix in ASSuffixes: static_obj.add_action(suffix, SCons.Defaults.ASAction) + shared_obj.add_action(suffix, SCons.Defaults.ASAction) static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) for suffix in ASPPSuffixes: static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + shared_obj.add_action(suffix, SCons.Defaults.ASPPAction) static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter) + shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter) env['AS'] = env.Detect(assemblers) or 'as' env['ASFLAGS'] = SCons.Util.CLVar('') diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py index b694a58..b83e7d3 100644 --- a/src/engine/SCons/Tool/fortran.py +++ b/src/engine/SCons/Tool/fortran.py @@ -146,7 +146,7 @@ def add_to_env(env): env['FORTRANMODDIR'] = '' # where the compiler should place .mod files env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX - env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__)} $)' + env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)' env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes) diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py index 1be665a..ad02e0d 100644 --- a/src/engine/SCons/Tool/gcc.py +++ b/src/engine/SCons/Tool/gcc.py @@ -46,7 +46,7 @@ def generate(env): cc.generate(env) env['CC'] = env.Detect(compilers) or 'gcc' - if env['PLATFORM'] == 'cygwin': + if env['PLATFORM'] in ['cygwin', 'win32']: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') else: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC') diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py index 5765e25..d679b53 100644 --- a/src/engine/SCons/Tool/mingw.py +++ b/src/engine/SCons/Tool/mingw.py @@ -118,7 +118,7 @@ def generate(env): # Most of mingw is the same as gcc and friends... - gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas'] + gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas', 'm4'] for tool in gnu_tools: SCons.Tool.Tool(tool)(env) @@ -130,7 +130,6 @@ def generate(env): env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') env['SHLINKCOM'] = shlib_action env.Append(SHLIBEMITTER = [shlib_emitter]) - env['LINK'] = 'g++' env['AS'] = 'as' env['WIN32DEFPREFIX'] = '' diff --git a/src/engine/SCons/Tool/mslink.xml b/src/engine/SCons/Tool/mslink.xml index 58cfb1d..6499cfe 100644 --- a/src/engine/SCons/Tool/mslink.xml +++ b/src/engine/SCons/Tool/mslink.xml @@ -37,6 +37,20 @@ Example: env['PDB'] = 'hello.pdb' + +The Visual C++ compiler switch that SCons uses by default +to generate PDB information is . +This works correctly with parallel () 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 instead may yield improved +link-time performance, +although parallel builds will no longer work. +You can generate PDB files with the +switch by overriding the default &cv-CCPDBFLAGS; variable; +see the entry for that variable for specific examples. diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index 86cde78..80b5926 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -517,9 +517,10 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs): include_paths.append( env_include_path ) if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'): - include_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'include' ) ) - lib_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'lib' ) ) - exe_paths.append( paths['FRAMEWORKSDKDIR'], 'bin' ) + fwdir = paths['FRAMEWORKSDKDIR'] + include_paths.append( os.path.join( fwdir, 'include' ) ) + lib_paths.append( os.path.join( fwdir, 'lib' ) ) + exe_paths.append( os.path.join( fwdir, 'bin' ) ) if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'): exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) ) @@ -658,7 +659,10 @@ pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', emitter=pch_emitter, source_scanner=SCons.Tool.SourceFileScanner) res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') -res_builder = SCons.Builder.Builder(action=res_action, suffix='.res', +res_builder = SCons.Builder.Builder(action=res_action, + src_suffix='.rc', + suffix='.res', + src_builder=[], source_scanner=SCons.Tool.SourceFileScanner) SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index 252d962..1c0f3fa 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -47,6 +47,53 @@ env.RES('resource.rc') + + +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. + + + + +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 . +This works correctly with parallel () 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 instead may yield improved +link-time performance, +although parallel builds will no longer work. + +You can generate PDB files with the +switch by overriding the default &cv-CCPDBFLAGS; variable as follows: + + +import SCons.Util +env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}']) + + +An alternative would be to use the +to put the debugging information in a separate .pdb +file for each object file by overriding +the &cv-CCPDBFLAGS; variable as follows: + + +env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' + + + The Microsoft Visual C++ precompiled header that will be used when compiling diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index e8aaf83..e35c92a 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -297,7 +297,7 @@ class _DSPGenerator: for n in sourcenames: self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower())) - def AddConfig(variant, buildtarget, outdir, runfile, cmdargs): + def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile): config = Config() config.buildtarget = buildtarget config.outdir = outdir @@ -316,7 +316,7 @@ class _DSPGenerator: print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'" for i in range(len(variants)): - AddConfig(variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) + AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) self.platforms = [] for key in self.configs.keys(): @@ -690,6 +690,29 @@ class _GenerateV7DSP(_DSPGenerator): pdata = base64.encodestring(pdata) self.file.write(pdata + '-->\n') + def printSources(self, hierarchy, commonprefix): + sorteditems = hierarchy.items() + sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower())) + + # First folders, then files + for key, value in sorteditems: + if SCons.Util.is_Dict(value): + self.file.write('\t\t\t\n' % (key)) + self.printSources(value, commonprefix) + self.file.write('\t\t\t\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\n' + '\t\t\t\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\n' % (key)) - printSources(value, commonprefix) - self.file.write('\t\t\t\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\n' - '\t\t\t\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\n') @@ -873,7 +879,7 @@ class _GenerateV7DSW(_DSWGenerator): if self.nokeep == 0 and os.path.exists(self.dswfile): self.Parse() - def AddConfig(variant): + def AddConfig(self, variant, dswfile=dswfile): config = Config() match = re.match('(.*)\|(.*)', variant) @@ -892,10 +898,10 @@ class _GenerateV7DSW(_DSWGenerator): "You must specify a 'variant' argument (i.e. 'Debug' or " +\ "'Release') to create an MSVS Solution File." elif SCons.Util.is_String(env['variant']): - AddConfig(env['variant']) + AddConfig(self, env['variant']) elif SCons.Util.is_List(env['variant']): for variant in env['variant']: - AddConfig(variant) + AddConfig(self, variant) self.platforms = [] for key in self.configs.keys(): @@ -1127,32 +1133,24 @@ def GenerateDSW(dswfile, source, env): def get_default_visualstudio_version(env): """Returns the version set in the env, or the latest version installed, if it can find it, or '6.0' if all else fails. Also - updated the environment with what it found.""" + updates the environment with what it found.""" - version = '6.0' - versions = [version] + versions = ['6.0'] if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']): - env['MSVS'] = {} - - if env['MSVS'].has_key('VERSIONS'): - versions = env['MSVS']['VERSIONS'] - elif SCons.Util.can_read_reg: - v = get_visualstudio_versions() - if v: - versions = v - if env.has_key('MSVS_VERSION'): - version = env['MSVS_VERSION'] - else: - version = versions[0] #use highest version by default - - env['MSVS_VERSION'] = version - env['MSVS']['VERSIONS'] = versions - env['MSVS']['VERSION'] = version + v = get_visualstudio_versions() + if v: + versions = v + env['MSVS'] = {'VERSIONS' : versions} else: - version = env['MSVS']['VERSION'] + versions = env['MSVS'].get('VERSIONS', versions) + + if not env.has_key('MSVS_VERSION'): + env['MSVS_VERSION'] = versions[0] #use highest version by default + + env['MSVS']['VERSION'] = env['MSVS_VERSION'] - return version + return env['MSVS_VERSION'] def get_visualstudio_versions(): """ diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 6095dff..b1125e7 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -471,6 +471,18 @@ class msvsTestCase(unittest.TestCase): assert env['MSVS']['VERSION'] == '7.0', env['MSVS']['VERSION'] assert v2 == '7.0', v2 + env = DummyEnv() + v3 = get_default_visualstudio_version(env) + if v3 == '7.1': + override = '7.0' + else: + override = '7.1' + env['MSVS_VERSION'] = override + v3 = get_default_visualstudio_version(env) + assert env['MSVS_VERSION'] == override, env['MSVS_VERSION'] + assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION'] + assert v3 == override, v3 + def test_get_visual_studio_versions(self): """Test retrieval of the list of visual studio versions""" v1 = get_visualstudio_versions() diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py new file mode 100644 index 0000000..9bf5779 --- /dev/null +++ b/src/engine/SCons/cpp.py @@ -0,0 +1,561 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +__doc__ = """ +SCons C Pre-Processor module +""" + +import os +import re +import string +import sys + + + +import __builtin__ +try: + __builtin__.zip +except AttributeError: + def zip(*lists): + result = [] + for i in xrange(len(lists[0])): + result.append(tuple(map(lambda l, i=i: l[i], lists))) + return result + + + +# +# First "subsystem" of regular expressions that we set up: +# +# Stuff to turn the C preprocessor directives in a file's contents into +# a list of tuples that we can process easily. +# + +# A table of regular expressions that fetch the arguments from the rest of +# a C preprocessor line. Different directives have different arguments +# that we want to fetch, using the regular expressions to which the lists +# of preprocessor directives map. +cpp_lines_dict = { + # Fetch the rest of a #if/#elif/#ifdef/#ifndef/#import/#include/ + # #include_next line as one argument. + ('if', 'elif', 'ifdef', 'ifndef', 'import', 'include', 'include_next',) + : '\s+(.+)', + + # We don't care what comes after a #else or #endif line. + ('else', 'endif',) : '', + + # Fetch three arguments from a #define line: + # 1) The #defined keyword. + # 2) The optional parentheses and arguments (if it's a function-like + # macro, '' if it's not). + # 3) The expansion value. + ('define',) : '\s+([_A-Za-z][_A-Za-z0-9_]+)(\([^)]*\))?\s*(.*)', + + # Fetch the #undefed keyword from a #undef line. + ('undef',) : '\s+([_A-Za-z][A-Za-z0-9_]+)', +} + +# Create a table that maps each individual C preprocessor directive to +# the corresponding compiled regular expression that fetches the arguments +# we care about. +Table = {} +for op_list, expr in cpp_lines_dict.items(): + e = re.compile(expr) + for op in op_list: + Table[op] = e +del e +del op +del op_list + +# Create a list of the expressions we'll use to match all of the +# preprocessor directives. These are the same as the directives +# themselves *except* that we must use a negative lookahead assertion +# when matching "if" so it doesn't match the "if" in "ifdef." +override = { + 'if' : 'if(?!def)', +} +l = map(lambda x, o=override: o.get(x, x), Table.keys()) + + +# Turn the list of expressions into one big honkin' regular expression +# that will match all the preprocessor lines at once. This will return +# a list of tuples, one for each preprocessor line. The preprocessor +# directive will be the first element in each tuple, and the rest of +# the line will be the second element. +e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$' + +# And last but not least, compile the expression. +CPP_Expression = re.compile(e, re.M) + + + + +# +# Second "subsystem" of regular expressions that we set up: +# +# Stuff to translate a C preprocessor expression (as found on a #if or +# #elif line) into an equivalent Python expression that we can eval(). +# + +# A dictionary that maps the C representation of Boolean operators +# to their Python equivalents. +CPP_to_Python_Ops_Dict = { + '!' : ' not ', + '!=' : ' != ', + '&&' : ' and ', + '||' : ' or ', + '?' : ' and ', + ':' : ' or ', + '\r' : '', +} + +CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)] + +# We have to sort the keys by length so that longer expressions +# come *before* shorter expressions--in particular, "!=" must +# come before "!" in the alternation. Without this, the Python +# re module, as late as version 2.2.2, empirically matches the +# "!" in "!=" first, instead of finding the longest match. +# What's up with that? +l = CPP_to_Python_Ops_Dict.keys() +l.sort(lambda a, b: cmp(len(b), len(a))) + +# Turn the list of keys into one regular expression that will allow us +# to substitute all of the operators at once. +expr = string.join(map(re.escape, l), '|') + +# ...and compile the expression. +CPP_to_Python_Ops_Expression = re.compile(expr) + +# A separate list of expressions to be evaluated and substituted +# sequentially, not all at once. +CPP_to_Python_Eval_List = [ + ['defined\s+(\w+)', '__dict__.has_key("\\1")'], + ['defined\s*\((\w+)\)', '__dict__.has_key("\\1")'], + ['/\*.*\*/', ''], + ['/\*.*', ''], + ['//.*', ''], + ['(0x[0-9A-Fa-f]*)[UL]+', '\\1L'], +] + +# Replace the string representations of the regular expressions in the +# list with compiled versions. +for l in CPP_to_Python_Eval_List: + l[0] = re.compile(l[0]) + +# Wrap up all of the above into a handy function. +def CPP_to_Python(s): + """ + Converts a C pre-processor expression into an equivalent + Python expression that can be evaluated. + """ + s = CPP_to_Python_Ops_Expression.sub(CPP_to_Python_Ops_Sub, s) + for expr, repl in CPP_to_Python_Eval_List: + s = expr.sub(repl, s) + return s + + + +del expr +del l +del override + + + +class FunctionEvaluator: + """ + Handles delayed evaluation of a #define function call. + """ + def __init__(self, name, args, expansion): + """ + Squirrels away the arguments and expansion value of a #define + macro function for later evaluation when we must actually expand + a value that uses it. + """ + self.name = name + self.args = function_arg_separator.split(args) + self.expansion = string.split(expansion, '##') + def __call__(self, *values): + """ + Evaluates the expansion of a #define macro function called + with the specified values. + """ + if len(self.args) != len(values): + raise ValueError, "Incorrect number of arguments to `%s'" % self.name + # Create a dictionary that maps the macro arguments to the + # corresponding values in this "call." We'll use this when we + # eval() the expansion so that arguments will get expanded to + # the right values. + locals = {} + for k, v in zip(self.args, values): + locals[k] = v + + parts = [] + for s in self.expansion: + if not s in self.args: + s = repr(s) + parts.append(s) + statement = string.join(parts, ' + ') + + return eval(statement, globals(), locals) + + + +# Find line continuations. +line_continuations = re.compile('\\\\\r?\n') + +# Search for a "function call" macro on an expansion. Returns the +# two-tuple of the "function" name itself, and a string containing the +# arguments within the call parentheses. +function_name = re.compile('(\S+)\(([^)]*)\)') + +# Split a string containing comma-separated function call arguments into +# the separate arguments. +function_arg_separator = re.compile(',\s*') + + + +class PreProcessor: + """ + The main workhorse class for handling C pre-processing. + """ + def __init__(self, current='.', cpppath=[], dict={}, all=0): + global Table + + self.searchpath = { + '"' : [current] + cpppath, + '<' : cpppath + [current], + } + + # Initialize our C preprocessor namespace for tracking the + # values of #defined keywords. We use this namespace to look + # for keywords on #ifdef/#ifndef lines, and to eval() the + # expressions on #if/#elif lines (after massaging them from C to + # Python). + self.cpp_namespace = dict.copy() + self.cpp_namespace['__dict__'] = self.cpp_namespace + + if all: + self.do_include = self.all_include + + # For efficiency, a dispatch table maps each C preprocessor + # directive (#if, #define, etc.) to the method that should be + # called when we see it. We accomodate state changes (#if, + # #ifdef, #ifndef) by pushing the current dispatch table on a + # stack and changing what method gets called for each relevant + # directive we might see next at this level (#else, #elif). + # #endif will simply pop the stack. + d = {} + for op in Table.keys(): + d[op] = getattr(self, 'do_' + op) + self.default_table = d + + # Controlling methods. + + def tupleize(self, contents): + """ + Turns the contents of a file into a list of easily-processed + tuples describing the CPP lines in the file. + + The first element of each tuple is the line's preprocessor + directive (#if, #include, #define, etc., minus the initial '#'). + The remaining elements are specific to the type of directive, as + pulled apart by the regular expression. + """ + global CPP_Expression, Table + contents = line_continuations.sub('', contents) + cpp_tuples = CPP_Expression.findall(contents) + return map(lambda m, t=Table: + (m[0],) + t[m[0]].match(m[1]).groups(), + cpp_tuples) + + def __call__(self, contents): + """ + Pre-processes a file contents. + + This is the main entry point, which + """ + self.stack = [] + self.dispatch_table = self.default_table.copy() + self.tuples = self.tupleize(contents) + + self.result = [] + while self.tuples: + t = self.tuples.pop(0) + # Uncomment to see the list of tuples being processed (e.g., + # to validate the CPP lines are being translated correctly). + #print t + self.dispatch_table[t[0]](t) + + return self.result + + # Dispatch table stack manipulation methods. + + def save(self): + """ + Pushes the current dispatch table on the stack and re-initializes + the current dispatch table to the default. + """ + self.stack.append(self.dispatch_table) + self.dispatch_table = self.default_table.copy() + + def restore(self): + """ + Pops the previous dispatch table off the stack and makes it the + current one. + """ + try: self.dispatch_table = self.stack.pop() + except IndexError: pass + + # Utility methods. + + def do_nothing(self, t): + """ + Null method for when we explicitly want the action for a + specific preprocessor directive to do nothing. + """ + pass + + def eval_expression(self, t): + """ + Evaluates a C preprocessor expression. + + This is done by converting it to a Python equivalent and + eval()ing it in the C preprocessor namespace we use to + track #define values. + """ + t = CPP_to_Python(string.join(t[1:])) + try: return eval(t, self.cpp_namespace) + except (NameError, TypeError): return 0 + + def find_include_file(self, t): + """ + Finds the #include file for a given preprocessor tuple. + """ + fname = t[2] + for d in self.searchpath[t[1]]: + f = os.path.join(d, fname) + if os.path.isfile(f): + return f + return None + + # Start and stop processing include lines. + + def start_handling_includes(self, t=None): + """ + Causes the PreProcessor object to start processing #import, + #include and #include_next lines. + + This method will be called when a #if, #ifdef, #ifndef or #elif + evaluates True, or when we reach the #else in a #if, #ifdef, + #ifndef or #elif block where a condition already evaluated + False. + + """ + d = self.dispatch_table + d['import'] = self.do_import + d['include'] = self.do_include + d['include_next'] = self.do_include + + def stop_handling_includes(self, t=None): + """ + Causes the PreProcessor object to stop processing #import, + #include and #include_next lines. + + This method will be called when a #if, #ifdef, #ifndef or #elif + evaluates False, or when we reach the #else in a #if, #ifdef, + #ifndef or #elif block where a condition already evaluated True. + """ + d = self.dispatch_table + d['import'] = self.do_nothing + d['include'] = self.do_nothing + d['include_next'] = self.do_nothing + + # Default methods for handling all of the preprocessor directives. + # (Note that what actually gets called for a given directive at any + # point in time is really controlled by the dispatch_table.) + + def _do_if_else_condition(self, condition): + """ + Common logic for evaluating the conditions on #if, #ifdef and + #ifndef lines. + """ + self.save() + d = self.dispatch_table + if condition: + self.start_handling_includes() + d['elif'] = self.stop_handling_includes + d['else'] = self.stop_handling_includes + else: + self.stop_handling_includes() + d['elif'] = self.do_elif + d['else'] = self.start_handling_includes + + def do_ifdef(self, t): + """ + Default handling of a #ifdef line. + """ + self._do_if_else_condition(self.cpp_namespace.has_key(t[1])) + + def do_ifndef(self, t): + """ + Default handling of a #ifndef line. + """ + self._do_if_else_condition(not self.cpp_namespace.has_key(t[1])) + + def do_if(self, t): + """ + Default handling of a #if line. + """ + self._do_if_else_condition(self.eval_expression(t)) + + def do_elif(self, t): + """ + Default handling of a #elif line. + """ + d = self.dispatch_table + if self.eval_expression(t): + self.start_handling_includes() + d['elif'] = self.stop_handling_includes + d['else'] = self.stop_handling_includes + + def do_else(self, t): + """ + Default handling of a #else line. + """ + pass + + def do_endif(self, t): + """ + Default handling of a #endif line. + """ + self.restore() + + def do_define(self, t): + """ + Default handling of a #define line. + """ + _, name, args, expansion = t + try: + expansion = int(expansion) + except (TypeError, ValueError): + pass + if args: + evaluator = FunctionEvaluator(name, args[1:-1], expansion) + self.cpp_namespace[name] = evaluator + else: + self.cpp_namespace[name] = expansion + + def do_undef(self, t): + """ + Default handling of a #undef line. + """ + try: del self.cpp_namespace[t[1]] + except KeyError: pass + + def do_import(self, t): + """ + Default handling of a #import line. + """ + # XXX finish this -- maybe borrow/share logic from do_include()...? + pass + + def do_include(self, t): + """ + Default handling of a #include line. + """ + t = self.resolve_include(t) + include_file = self.find_include_file(t) + if include_file: + #print "include_file =", include_file + self.result.append(include_file) + contents = open(include_file).read() + new_tuples = self.tupleize(contents) + self.tuples[:] = new_tuples + self.tuples + + # Date: Tue, 22 Nov 2005 20:26:09 -0500 + # From: Stefan Seefeld + # + # 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 ' which would + # correctly resolve to '/bar/baz.h' (if that exists), but *not* see + # '/foo/baz.h' again. See http://www.delorie.com/gnu/docs/gcc/cpp_11.html + # for more reasoning. + # + # I have no idea in what context 'import' might be used. + + # XXX is #include_next really the same as #include ? + do_include_next = do_include + + # Utility methods for handling resolution of include files. + + def resolve_include(self, t): + """Resolve a tuple-ized #include line. + + This handles recursive expansion of values without "" or <> + surrounding the name until an initial " or < is found, to handle + #include FILE + where FILE is a #define somewhere else. + """ + s = t[1] + while not s[0] in '<"': + #print "s =", s + try: + s = self.cpp_namespace[s] + except KeyError: + m = function_name.search(s) + s = self.cpp_namespace[m.group(1)] + if callable(s): + args = function_arg_separator.split(m.group(2)) + s = apply(s, args) + if not s: + return None + return (t[0], s[0], s[1:-1]) + + def all_include(self, t): + """ + """ + self.result.append(self.resolve_include(t)) + +class DumbPreProcessor(PreProcessor): + """A preprocessor that ignores all #if/#elif/#else/#endif directives + and just reports back *all* of the #include files (like the classic + SCons scanner did). + + This is functionally equivalent to using a regular expression to + find all of the #include lines, only slower. It exists mainly as + an example of how the main PreProcessor class can be sub-classed + to tailor its behavior. + """ + def __init__(self, *args, **kw): + apply(PreProcessor.__init__, (self,)+args, kw) + d = self.default_table + for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']: + d[func] = d[func] = self.do_nothing + +del __revision__ diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py new file mode 100644 index 0000000..0959e2c --- /dev/null +++ b/src/engine/SCons/cppTests.py @@ -0,0 +1,573 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +print sys.path +import cpp + + + +basic_input = """ +#include "file1-yes" +#include +""" + + +substitution_input = """ +#define FILE3 "file3-yes" +#define FILE4 + +#include FILE3 +#include FILE4 + +#define XXX_FILE5 YYY_FILE5 +#define YYY_FILE5 ZZZ_FILE5 +#define ZZZ_FILE5 FILE5 + +#define FILE5 "file5-yes" +#define FILE6 + +#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 +#else +#include +#endif +""" + + +if_boolean_input = """ +#define ZERO 0 +#define ONE 1 + +#if ZERO +#include "file9-no" +#else +#include "file9-yes" +#endif + +#if ONE +#include +#else +#include +#endif + +#if ZERO +#include "file11-no-1" +#elif ZERO +#include "file11-no-2" +#else +#include "file11-yes" +#endif + +#if ZERO +#include +#elif ONE +#include +#else +#include +#endif + +#if ONE +#include "file13-yes" +#elif ZERO +#include "file13-no-1" +#else +#include "file13-no-2" +#endif + +#if ONE +#include +#elif ONE +#include +#else +#include +#endif +""" + + +if_defined_input = """ +#define DEFINED 0 + +#if defined(DEFINED) +#include "file15-yes" +#endif + +#if ! defined(DEFINED) +#include +#else +#include +#endif + +#if defined DEFINED +#include "file17-yes" +#endif + +#if ! defined DEFINED +#include +#else +#include +#endif +""" + + +expression_input = """ +#define ZERO 0 +#define ONE 1 + +#if ZERO && ZERO +#include "file19-no" +#else +#include "file19-yes" +#endif + +#if ZERO && ONE +#include +#else +#include +#endif + +#if ONE && ZERO +#include "file21-no" +#else +#include "file21-yes" +#endif + +#if ONE && ONE +#include +#else +#include +#endif + +#if ZERO || ZERO +#include "file23-no" +#else +#include "file23-yes" +#endif + +#if ZERO || ONE +#include +#else +#include +#endif + +#if ONE || ZERO +#include "file25-yes" +#else +#include "file25-no" +#endif + +#if ONE || ONE +#include +#else +#include +#endif + +#if ONE == ONE +#include "file27-yes" +#else +#include "file27-no" +#endif + +#if ONE != ONE +#include +#else +#include +#endif + +#if ! (ONE == ONE) +#include "file29-no" +#else +#include "file29-yes" +#endif + +#if ! (ONE != ONE) +#include +#else +#include +#endif +""" + + +undef_input = """ +#define UNDEFINE 0 + +#ifdef UNDEFINE +#include "file31-yes" +#else +#include "file31-no" +#endif + +#undef UNDEFINE + +#ifdef UNDEFINE +#include +#else +#include +#endif +""" + + +macro_function_input = """ +#define ZERO 0 +#define ONE 1 + +#define FUNC33(x) "file33-yes" +#define FUNC34(x) + +#include FUNC33(ZERO) +#include FUNC34(ZERO) + +#define FILE35 "file35-yes" +#define FILE36 + +#define FUNC35(x, y) FILE35 +#define FUNC36(x, y) FILE36 + +#include FUNC35(ZERO, ONE) +#include FUNC36(ZERO, ONE) + +#define FILE37 "file37-yes" +#define FILE38 + +#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 + +#define FUNC39a(x0, y0) FILE39 +#define FUNC40a(x0, y0) FILE40 + +#define FUNC39b(x1, y2) FUNC39a(x1, y1) +#define FUNC40b(x1, y2) FUNC40a(x1, y1) + +#define FUNC39c(x2, y2) FUNC39b(x2, y2) +#define FUNC40c(x2, y2) FUNC40b(x2, y2) + +#include FUNC39c(ZERO, ONE) +#include FUNC40c(ZERO, ONE) +""" + + +token_pasting_input = """ +#define PASTE_QUOTE(q, name) q##name##-yes##q +#define PASTE_ANGLE(name) <##name##-yes> + +#define FUNC41 PASTE_QUOTE(", file41) +#define FUNC42 PASTE_ANGLE(file42) + +#include FUNC41 +#include FUNC42 +""" + + + +# pp_class = PreProcessor +# #pp_class = DumbPreProcessor + +# pp = pp_class(current = ".", +# cpppath = ['/usr/include'], +# print_all = 1) +# #pp(open(sys.argv[1]).read()) +# pp(input) + + +class cppTestCase(unittest.TestCase): + def setUp(self): + self.cpp = self.cpp_class(current = ".", + cpppath = ['/usr/include']) + + def test_basic(self): + """Test basic #include scanning""" + expect = self.basic_expect + result = self.cpp(basic_input) + assert expect == result, (expect, result) + + def test_substitution(self): + """Test substitution of #include files using CPP variables""" + expect = self.substitution_expect + result = self.cpp(substitution_input) + assert expect == result, (expect, result) + + def test_ifdef(self): + """Test basic #ifdef processing""" + expect = self.ifdef_expect + result = self.cpp(ifdef_input) + assert expect == result, (expect, result) + + def test_if_boolean(self): + """Test #if with Boolean values""" + expect = self.if_boolean_expect + result = self.cpp(if_boolean_input) + assert expect == result, (expect, result) + + def test_if_defined(self): + """Test #if defined() idioms""" + expect = self.if_defined_expect + result = self.cpp(if_defined_input) + assert expect == result, (expect, result) + + def test_expression(self): + """Test #if with arithmetic expressions""" + expect = self.expression_expect + result = self.cpp(expression_input) + assert expect == result, (expect, result) + + def test_undef(self): + """Test #undef handling""" + expect = self.undef_expect + result = self.cpp(undef_input) + assert expect == result, (expect, result) + + def test_macro_function(self): + """Test using macro functions to express file names""" + expect = self.macro_function_expect + result = self.cpp(macro_function_input) + assert expect == result, (expect, result) + + def test_token_pasting(self): + """Test taken-pasting to construct file names""" + expect = self.token_pasting_expect + result = self.cpp(token_pasting_input) + assert expect == result, (expect, result) + +class cppAllTestCase(cppTestCase): + def setUp(self): + self.cpp = self.cpp_class(current = ".", + cpppath = ['/usr/include'], + all=1) + +class PreProcessorTestCase(cppAllTestCase): + cpp_class = cpp.PreProcessor + + basic_expect = [ + ('include', '"', 'file1-yes'), + ('include', '<', 'file2-yes'), + ] + + substitution_expect = [ + ('include', '"', 'file3-yes'), + ('include', '<', 'file4-yes'), + ('include', '"', 'file5-yes'), + ('include', '<', 'file6-yes'), + ] + + ifdef_expect = [ + ('include', '"', 'file7-yes'), + ('include', '<', 'file8-yes'), + ] + + if_boolean_expect = [ + ('include', '"', 'file9-yes'), + ('include', '<', 'file10-yes'), + ('include', '"', 'file11-yes'), + ('include', '<', 'file12-yes'), + ('include', '"', 'file13-yes'), + ('include', '<', 'file14-yes'), + ] + + if_defined_expect = [ + ('include', '"', 'file15-yes'), + ('include', '<', 'file16-yes'), + ('include', '"', 'file17-yes'), + ('include', '<', 'file18-yes'), + ] + + expression_expect = [ + ('include', '"', 'file19-yes'), + ('include', '<', 'file20-yes'), + ('include', '"', 'file21-yes'), + ('include', '<', 'file22-yes'), + ('include', '"', 'file23-yes'), + ('include', '<', 'file24-yes'), + ('include', '"', 'file25-yes'), + ('include', '<', 'file26-yes'), + ('include', '"', 'file27-yes'), + ('include', '<', 'file28-yes'), + ('include', '"', 'file29-yes'), + ('include', '<', 'file30-yes'), + ] + + undef_expect = [ + ('include', '"', 'file31-yes'), + ('include', '<', 'file32-yes'), + ] + + macro_function_expect = [ + ('include', '"', 'file33-yes'), + ('include', '<', 'file34-yes'), + ('include', '"', 'file35-yes'), + ('include', '<', 'file36-yes'), + ('include', '"', 'file37-yes'), + ('include', '<', 'file38-yes'), + ('include', '"', 'file39-yes'), + ('include', '<', 'file40-yes'), + ] + + token_pasting_expect = [ + ('include', '"', 'file41-yes'), + ('include', '<', 'file42-yes'), + ] + +class DumbPreProcessorTestCase(cppAllTestCase): + cpp_class = cpp.DumbPreProcessor + + basic_expect = [ + ('include', '"', 'file1-yes'), + ('include', '<', 'file2-yes'), + ] + + substitution_expect = [ + ('include', '"', 'file3-yes'), + ('include', '<', 'file4-yes'), + ('include', '"', 'file5-yes'), + ('include', '<', 'file6-yes'), + ] + + ifdef_expect = [ + ('include', '"', 'file7-yes'), + ('include', '"', 'file7-no'), + ('include', '<', 'file8-no'), + ('include', '<', 'file8-yes'), + ] + + if_boolean_expect = [ + ('include', '"', 'file9-no'), + ('include', '"', 'file9-yes'), + ('include', '<', 'file10-yes'), + ('include', '<', 'file10-no'), + ('include', '"', 'file11-no-1'), + ('include', '"', 'file11-no-2'), + ('include', '"', 'file11-yes'), + ('include', '<', 'file12-no-1'), + ('include', '<', 'file12-yes'), + ('include', '<', 'file12-no-2'), + ('include', '"', 'file13-yes'), + ('include', '"', 'file13-no-1'), + ('include', '"', 'file13-no-2'), + ('include', '<', 'file14-yes'), + ('include', '<', 'file14-no-1'), + ('include', '<', 'file14-no-2'), + ] + + if_defined_expect = [ + ('include', '"', 'file15-yes'), + ('include', '<', 'file16-no'), + ('include', '<', 'file16-yes'), + ('include', '"', 'file17-yes'), + ('include', '<', 'file18-no'), + ('include', '<', 'file18-yes'), + ] + + expression_expect = [ + ('include', '"', 'file19-no'), + ('include', '"', 'file19-yes'), + ('include', '<', 'file20-no'), + ('include', '<', 'file20-yes'), + ('include', '"', 'file21-no'), + ('include', '"', 'file21-yes'), + ('include', '<', 'file22-yes'), + ('include', '<', 'file22-no'), + ('include', '"', 'file23-no'), + ('include', '"', 'file23-yes'), + ('include', '<', 'file24-yes'), + ('include', '<', 'file24-no'), + ('include', '"', 'file25-yes'), + ('include', '"', 'file25-no'), + ('include', '<', 'file26-yes'), + ('include', '<', 'file26-no'), + ('include', '"', 'file27-yes'), + ('include', '"', 'file27-no'), + ('include', '<', 'file28-no'), + ('include', '<', 'file28-yes'), + ('include', '"', 'file29-no'), + ('include', '"', 'file29-yes'), + ('include', '<', 'file30-yes'), + ('include', '<', 'file30-no'), + ] + + undef_expect = [ + ('include', '"', 'file31-yes'), + ('include', '"', 'file31-no'), + ('include', '<', 'file32-no'), + ('include', '<', 'file32-yes'), + ] + + macro_function_expect = [ + ('include', '"', 'file33-yes'), + ('include', '<', 'file34-yes'), + ('include', '"', 'file35-yes'), + ('include', '<', 'file36-yes'), + ('include', '"', 'file37-yes'), + ('include', '<', 'file38-yes'), + ('include', '"', 'file39-yes'), + ('include', '<', 'file40-yes'), + ] + + token_pasting_expect = [ + ('include', '"', 'file41-yes'), + ('include', '<', 'file42-yes'), + ] + +if __name__ == '__main__': + suite = unittest.TestSuite() + tclasses = [ PreProcessorTestCase, + DumbPreProcessorTestCase, + ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(map(tclass, names)) + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + diff --git a/src/test_copyrights.py b/src/test_copyrights.py index 195649b..3f7d1c9 100644 --- a/src/test_copyrights.py +++ b/src/test_copyrights.py @@ -46,9 +46,12 @@ try: except KeyError: cwd = os.getcwd() -build_scons = os.path.join(cwd, 'build', 'scons') -build_local = os.path.join(cwd, 'build', 'scons-local', 'scons-local-0.96.92') -build_src = os.path.join(cwd, 'build', 'scons-src') +def build_path(*args): + return apply(os.path.join, (cwd, 'build',)+args) + +build_scons = build_path('scons') +build_local = build_path('scons-local', 'scons-local-'+test.scons_version) +build_src = build_path('scons-src') class Collect: expression = re.compile('Copyright.*The SCons Foundation') diff --git a/src/test_files.py b/src/test_files.py new file mode 100644 index 0000000..1424c62 --- /dev/null +++ b/src/test_files.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that we have certain important files in our distribution +packages. + +Note that this is a packaging test, not a functional test, so the +name of this script doesn't end in *Tests.py. +""" + +import os +import os.path +import re +import string + +import TestSCons + +test = TestSCons.TestSCons() + +try: + cwd = os.environ['SCONS_CWD'] +except KeyError: + cwd = os.getcwd() + +def build_path(*args): + return apply(os.path.join, (cwd, 'build',) + args) + +build_scons_tar_gz = build_path('unpack-tar-gz', 'scons-'+test.scons_version) +build_scons_zip = build_path('unpack-zip', 'scons-'+test.scons_version) +build_local_tar_gz = build_path('test-local-tar-gz') +build_local_zip = build_path('test-local-zip') + +scons_files = [ + 'CHANGES.txt', + 'LICENSE.txt', + 'README.txt', + 'RELEASE.txt', +] + +local_files = [ + 'scons-LICENSE', + 'scons-README', +] + +# Map each directory to search (dictionary keys) to a list of its +# subsidiary files and directories to exclude from copyright checks. +check = { + build_scons_tar_gz : scons_files, + build_scons_zip : scons_files, + build_local_tar_gz : local_files, + build_local_zip : local_files, +} + +missing = [] +no_result = [] + +for directory, check_list in check.items(): + if os.path.exists(directory): + for c in check_list: + f = os.path.join(directory, c) + if not os.path.isfile(f): + missing.append(f) + else: + no_result.append(directory) + +if missing: + print "Missing the following files:\n" + print "\t" + string.join(missing, "\n\t") + test.fail_test(1) + +if no_result: + print "Cannot check files, the following have apparently not been built:" + print "\t" + string.join(no_result, "\n\t") + test.no_result(1) + +test.pass_test() diff --git a/src/test_setup.py b/src/test_setup.py index d612897..e2bb48b 100644 --- a/src/test_setup.py +++ b/src/test_setup.py @@ -40,15 +40,11 @@ import sys try: WindowsError except NameError: WindowsError = OSError -#try: -# version = os.environ['SCONS_VERSION'] -#except KeyError: -# version = '__VERSION__' -version = '0.96.92' +import TestSCons -scons_version = 'scons-%s' % version +version = TestSCons.TestSCons.scons_version -import TestSCons +scons_version = 'scons-%s' % version python = TestSCons.python @@ -203,8 +199,9 @@ if not os.path.isdir(scons_version) and os.path.isfile(tar_gz): os.system("gunzip -c %s | tar xf -" % tar_gz) if not os.path.isdir(scons_version): - print "Found neither SCons package `%s' nor `%s'." % (tar_gz, zip) - print "Cannot test package installation." + print "Cannot test package installation, found none of the following packages:" + print "\t" + tar_gz + print "\t" + zip test.no_result(1) # Verify that a virgin installation installs the version library, diff --git a/test/AR/AR.py b/test/AR/AR.py index 32419fa..cb11175 100644 --- a/test/AR/AR.py +++ b/test/AR/AR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) ar = foo.Dictionary('AR') -bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], AR = r'%s wrapper.py ' + ar) +bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], AR = r'%(_python_)s wrapper.py ' + ar) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -53,9 +53,11 @@ obj = foo.Object('main', 'main.c') foo.Program(target = 'f', source = obj) bar.Program(target = 'b', source = obj) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include + void library_function(void) { @@ -64,6 +66,8 @@ library_function(void) """) test.write('bar.c', r""" +#include + void library_function(void) { @@ -72,6 +76,9 @@ library_function(void) """) test.write('main.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/AR/ARCOM.py b/test/AR/ARCOM.py index c8ac1d8..73c36fc 100644 --- a/test/AR/ARCOM.py +++ b/test/AR/ARCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $ARCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,12 +51,12 @@ test.write('myranlib.py', """ test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n") test.write('file.2', "file.2\n/*ar*/\n") diff --git a/test/AR/ARCOMSTR.py b/test/AR/ARCOMSTR.py index ae63ea0..914031b 100644 --- a/test/AR/ARCOMSTR.py +++ b/test/AR/ARCOMSTR.py @@ -32,7 +32,7 @@ the displayed archiver string. import TestSCons import string -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,13 +53,13 @@ test.write('myranlib.py', """ test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', ARCOMSTR = 'Archiving $TARGET from $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n") test.write('file.2', "file.2\n/*ar*/\n") diff --git a/test/AR/ARFLAGS.py b/test/AR/ARFLAGS.py index 399170e..d4d122e 100644 --- a/test/AR/ARFLAGS.py +++ b/test/AR/ARFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], - AR = '', ARFLAGS = foo.subst(r'%s wrapper.py $AR $ARFLAGS')) + AR = '', ARFLAGS = foo.subst(r'%(_python_)s wrapper.py $AR $ARFLAGS')) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -53,9 +53,11 @@ obj = foo.Object('main', 'main.c') foo.Program(target = 'f', source = obj) bar.Program(target = 'b', source = obj) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include + void library_function(void) { @@ -64,6 +66,8 @@ library_function(void) """) test.write('bar.c', r""" +#include + void library_function(void) { @@ -72,6 +76,8 @@ library_function(void) """) test.write('main.c', r""" +#include + int main(int argc, char *argv[]) { diff --git a/test/AS/AS.py b/test/AS/AS.py index 0543a0c..2c9e624 100644 --- a/test/AS/AS.py +++ b/test/AS/AS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -110,17 +110,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', - LINKFLAGS = [], - AS = r'%s myas.py', - CC = r'%s myas.py') +env = Environment(LINK = r'%(_python_)s mylink.py', + AS = r'%(_python_)s myas.py', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.s') env.Program(target = 'test2', source = 'test2.S') env.Program(target = 'test3', source = 'test3.asm') env.Program(target = 'test4', source = 'test4.ASM') env.Program(target = 'test5', source = 'test5.spp') env.Program(target = 'test6', source = 'test6.SPP') -""" % (python, python, python)) +""" % locals()) test.write('test1.s', r"""This is a .s file. #as @@ -183,12 +182,12 @@ os.system(cmd) test.write('SConstruct', """\ aaa = Environment() -bbb = aaa.Copy(AS = r'%s wrapper.py ' + WhereIs('as')) +bbb = aaa.Copy(AS = r'%(_python_)s wrapper.py ' + WhereIs('as')) ccc = aaa.Copy(CPPPATH=['.']) aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c']) bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c']) ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c']) -""" % python) +""" % locals()) test.write('aaa.s', """ .file "aaa.s" @@ -226,6 +225,9 @@ name: """) test.write('aaa_main.c', r""" +#include +#include + extern char name[]; int @@ -238,6 +240,9 @@ main(int argc, char *argv[]) """) test.write('bbb_main.c', r""" +#include +#include + extern char name[]; int @@ -250,6 +255,9 @@ main(int argc, char *argv[]) """) test.write('ccc_main.c', r""" +#include +#include + extern char name[]; int @@ -309,10 +317,10 @@ import os ccc = Environment(tools = ['msvc', 'mslink', 'masm'], ASFLAGS = '/nologo /coff') ccc['ENV']['PATH'] = ccc['ENV']['PATH'] + os.pathsep + os.environ['PATH'] -ddd = ccc.Copy(AS = r'%s wrapper.py ' + ccc['AS']) +ddd = ccc.Copy(AS = r'%(_python_)s wrapper.py ' + ccc['AS']) ccc.Program(target = 'ccc', source = ['ccc.asm', 'ccc_main.c']) ddd.Program(target = 'ddd', source = ['ddd.asm', 'ddd_main.c']) -""" % python) +""" % locals()) test.write('ccc.asm', """ @@ -398,11 +406,11 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ eee = Environment(tools = ['gcc', 'gnulink', 'nasm'], - ASFLAGS = '-f %s') -fff = eee.Copy(AS = r'%s wrapper.py ' + WhereIs('nasm')) + ASFLAGS = '-f %(nasm_format)s') +fff = eee.Copy(AS = r'%(_python_)s wrapper.py ' + WhereIs('nasm')) eee.Program(target = 'eee', source = ['eee.asm', 'eee_main.c']) fff.Program(target = 'fff', source = ['fff.asm', 'fff_main.c']) -""" % (nasm_format, python)) +""" % locals()) test.write('eee.asm', """ diff --git a/test/AS/ASCOM.py b/test/AS/ASCOM.py index da66bca..4292581 100644 --- a/test/AS/ASCOM.py +++ b/test/AS/ASCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -56,18 +56,27 @@ else: alt_asm_suffix = '.asm' test.write('SConstruct', """ -env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE', - OBJSUFFIX = '.obj') +env = Environment(ASCOM = r'%(_python_)s myas.py $TARGET $SOURCE', + OBJSUFFIX = '.obj', + SHOBJSUFFIX = '.shobj') env.Object(target = 'test1', source = 'test1.s') env.Object(target = 'test2', source = 'test2%(alt_s_suffix)s') env.Object(target = 'test3', source = 'test3.asm') env.Object(target = 'test4', source = 'test4%(alt_asm_suffix)s') +env.SharedObject(target = 'test5', source = 'test5.s') +env.SharedObject(target = 'test6', source = 'test6%(alt_s_suffix)s') +env.SharedObject(target = 'test7', source = 'test7.asm') +env.SharedObject(target = 'test8', source = 'test8%(alt_asm_suffix)s') """ % locals()) test.write('test1.s', "test1.s\n#as\n") test.write('test2'+alt_s_suffix, "test2.S\n#as\n") test.write('test3.asm', "test3.asm\n#as\n") test.write('test4'+alt_asm_suffix, "test4.ASM\n#as\n") +test.write('test5.s', "test5.s\n#as\n") +test.write('test6'+alt_s_suffix, "test6.S\n#as\n") +test.write('test7.asm', "test7.asm\n#as\n") +test.write('test8'+alt_asm_suffix, "test8.ASM\n#as\n") test.run(arguments = '.') @@ -75,6 +84,10 @@ test.fail_test(test.read('test1.obj') != "test1.s\n") test.fail_test(test.read('test2.obj') != "test2.S\n") test.fail_test(test.read('test3.obj') != "test3.asm\n") test.fail_test(test.read('test4.obj') != "test4.ASM\n") +test.fail_test(test.read('test5.shobj') != "test5.s\n") +test.fail_test(test.read('test6.shobj') != "test6.S\n") +test.fail_test(test.read('test7.shobj') != "test7.asm\n") +test.fail_test(test.read('test8.shobj') != "test8.ASM\n") diff --git a/test/AS/ASCOMSTR.py b/test/AS/ASCOMSTR.py index c8eed62..287da16 100644 --- a/test/AS/ASCOMSTR.py +++ b/test/AS/ASCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,7 +57,7 @@ else: alt_asm_suffix = '.asm' test.write('SConstruct', """ -env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE', +env = Environment(ASCOM = r'%(_python_)s myas.py $TARGET $SOURCE', ASCOMSTR = 'Assembling $TARGET from $SOURCE', OBJSUFFIX = '.obj') env.Object(target = 'test1', source = 'test1.s') diff --git a/test/AS/ASFLAGS.py b/test/AS/ASFLAGS.py index 6396c45..a0da9ff 100644 --- a/test/AS/ASFLAGS.py +++ b/test/AS/ASFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -126,17 +126,17 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - AS = r'%s myas.py', ASFLAGS = '-x', - CC = r'%s myas.py') + AS = r'%(_python_)s myas.py', ASFLAGS = '-x', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.s') env.Program(target = 'test2', source = 'test2.S') env.Program(target = 'test3', source = 'test3.asm') env.Program(target = 'test4', source = 'test4.ASM') env.Program(target = 'test5', source = 'test5.spp') env.Program(target = 'test6', source = 'test6.SPP') -""" % (python, python, python)) +""" % locals()) test.write('test1.s', r"""This is a .s file. #as diff --git a/test/AS/ASPP.py b/test/AS/ASPP.py index da47618..2045a3d 100644 --- a/test/AS/ASPP.py +++ b/test/AS/ASPP.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -110,13 +110,13 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - ASPP = r'%s myas.py', - CC = r'%s myas.py') + ASPP = r'%(_python_)s myas.py', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.spp') env.Program(target = 'test2', source = 'test2.SPP') -""" % (python, python, python)) +""" % locals()) test.write('test1.spp', r"""This is a .spp file. #as diff --git a/test/AS/ASPPCOM.py b/test/AS/ASPPCOM.py index e877354..bb330dc 100644 --- a/test/AS/ASPPCOM.py +++ b/test/AS/ASPPCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,19 +49,26 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(ASPPCOM = r'%(python)s myas.py $TARGET $SOURCE', - OBJSUFFIX = '.obj') +env = Environment(ASPPCOM = r'%(_python_)s myas.py $TARGET $SOURCE', + OBJSUFFIX = '.obj', + SHOBJSUFFIX = '.shobj') env.Object(target = 'test1', source = 'test1.spp') env.Object(target = 'test2', source = 'test2.SPP') +env.SharedObject(target = 'test3', source = 'test3.spp') +env.SharedObject(target = 'test4', source = 'test4.SPP') """ % locals()) test.write('test1.spp', "test1.spp\n#as\n") test.write('test2.SPP', "test2.SPP\n#as\n") +test.write('test3.spp', "test3.spp\n#as\n") +test.write('test4.SPP', "test4.SPP\n#as\n") test.run(arguments = '.') test.fail_test(test.read('test1.obj') != "test1.spp\n") test.fail_test(test.read('test2.obj') != "test2.SPP\n") +test.fail_test(test.read('test3.shobj') != "test3.spp\n") +test.fail_test(test.read('test4.shobj') != "test4.SPP\n") diff --git a/test/AS/ASPPCOMSTR.py b/test/AS/ASPPCOMSTR.py index 21e8033..1956154 100644 --- a/test/AS/ASPPCOMSTR.py +++ b/test/AS/ASPPCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(ASPPCOM = r'%(python)s myas.py $TARGET $SOURCE', +env = Environment(ASPPCOM = r'%(_python_)s myas.py $TARGET $SOURCE', ASPPCOMSTR = 'Assembling $TARGET from $SOURCE', OBJSUFFIX = '.obj') env.Object(target = 'test1', source = 'test1.spp') diff --git a/test/AS/ASPPFLAGS.py b/test/AS/ASPPFLAGS.py index cbd4339..27858bd 100644 --- a/test/AS/ASPPFLAGS.py +++ b/test/AS/ASPPFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -126,10 +126,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%(python)s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - ASPP = r'%(python)s myas.py', ASPPFLAGS = '-x', - CC = r'%(python)s myas.py') + ASPP = r'%(_python_)s myas.py', ASPPFLAGS = '-x', + CC = r'%(_python_)s myas.py') env.Program(target = 'test1', source = 'test1.spp') env.Program(target = 'test2', source = 'test2.SPP') """ % locals()) diff --git a/test/Actions/actions.py b/test/Actions/actions.py index 7ae951a..61c3c7d 100644 --- a/test/Actions/actions.py +++ b/test/Actions/actions.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,10 +41,10 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGET 1 $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGET 1 $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.write('foo.in', "foo.in\n") @@ -55,10 +55,10 @@ test.fail_test(test.read('foo.out') != "1\nfoo.in\n") test.up_to_date(arguments = '.') test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGET 2 $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGET 2 $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.') @@ -70,14 +70,14 @@ test.write('SConstruct', """ import os import string def func(env, target, source): - cmd = r'%s build.py %%s 3 %%s' %% (string.join(map(str, target)), + cmd = r'%(_python_)s build.py %%s 3 %%s' %% (string.join(map(str, target)), string.join(map(str, source))) print cmd return os.system(cmd) B = Builder(action = func) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.', stderr = None) @@ -91,7 +91,7 @@ assert not globals().has_key('string') import string class bld: def __init__(self): - self.cmd = r'%s build.py %%s 4 %%s' + self.cmd = r'%(_python_)s build.py %%s 4 %%s' def __call__(self, env, target, source): cmd = self.get_contents(env, target, source) print cmd @@ -102,7 +102,7 @@ class bld: B = Builder(action = bld()) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.') diff --git a/test/Actions/pre-post.py b/test/Actions/pre-post.py index e25def5..e076f24 100644 --- a/test/Actions/pre-post.py +++ b/test/Actions/pre-post.py @@ -34,7 +34,7 @@ import sys import TestSCons _exe = TestSCons._exe -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -187,7 +187,7 @@ def post_action(target, source, env): env = Environment() o = env.Command(['pre-post', 'file.out'], 'file.in', - "%(python)s build.py ${TARGETS[1]} $SOURCE") + '%(_python_)s build.py ${TARGETS[1]} $SOURCE') env.AddPreAction(o, pre_action) env.AddPostAction(o, post_action) """ % locals()) diff --git a/test/Alias/Alias.py b/test/Alias/Alias.py index 56efafd..b53b8ce 100644 --- a/test/Alias/Alias.py +++ b/test/Alias/Alias.py @@ -29,7 +29,7 @@ import sys import TestSCons import TestCmd -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match=TestCmd.match_re) @@ -42,7 +42,7 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(action = r"%s build.py $TARGET $SOURCES") +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment() env['BUILDERS']['B'] = B env.B(target = 'f1.out', source = 'f1.in') @@ -62,7 +62,7 @@ env.Depends('f1.out', 'bar') assert Alias('foo') == foo assert Alias('bar') == bar -""" % python) +""" % locals()) test.write(['sub1', 'SConscript'], """ Import("env") @@ -134,7 +134,7 @@ test.up_to_date(arguments = 'f1.out') test.write('SConstruct', """ TargetSignatures('content') -B = Builder(action = r"%s build.py $TARGET $SOURCES") +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment() env['BUILDERS']['B'] = B env.B(target = 'f1.out', source = 'f1.in') @@ -147,7 +147,7 @@ env.Alias('bar', ['sub2', 'f3.out']) env.Alias('blat', ['sub2', 'f3.out']) env.Alias('blat', ['f2.out', 'sub1']) env.Depends('f1.out', 'bar') -""" % python) +""" % locals()) os.unlink(test.workpath('f1.out')) @@ -157,12 +157,12 @@ test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.write('f3.in', "f3.in 3 \n") -test.run(arguments = 'f1.out', - match = TestCmd.match_exact, - stdout = test.wrap_stdout("""\ -%s build.py f3.out f3.in -%s build.py f1.out f1.in -""" % (python, python))) +expect = test.wrap_stdout("""\ +%(_python_)s build.py f3.out f3.in +%(_python_)s build.py f1.out f1.in +""" % locals()) + +test.run(arguments = 'f1.out', match = TestCmd.match_exact, stdout = expect) test.up_to_date(arguments = 'f1.out') diff --git a/test/BadBuilder.py b/test/BadBuilder.py index 4667a21..8c28ea5 100644 --- a/test/BadBuilder.py +++ b/test/BadBuilder.py @@ -34,6 +34,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + sconstruct = """ def buildop(env, source, target): outf = open(str(target[0]), 'wb') @@ -58,42 +60,42 @@ built ### Gross mistake in Builder spec -test.write('SConstruct', sconstruct % '\ +test.write(SConstruct_path, sconstruct % '\ b2 = Builder(act__ion=buildop, src_suffix=".b", suffix=".c")') -test.run(arguments='.', - stderr="""\ +expect_stderr = """\ scons: *** Builder b2 must have an action to build ['foo.c']. -File "SConstruct", line 14, in ? -""", -status = 2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='.', stderr=expect_stderr, status = 2) ### Subtle mistake in Builder spec -test.write('SConstruct', sconstruct % '\ +test.write(SConstruct_path, sconstruct % '\ b2 = Builder(actoin=buildop, src_suffix=".b", suffix=".c")') -test.run(arguments='test2', - stderr="""\ +expect_stderr="""\ scons: *** Builder b2 must have an action to build ['foo.c']. -File "SConstruct", line 14, in ? -""", -status = 2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='test2', stderr=expect_stderr, status=2) ### Missing action in Builder spec -test.write('SConstruct', sconstruct % '\ +test.write(SConstruct_path, sconstruct % '\ b2 = Builder(src_suffix=".b", suffix=".c")') -test.run(arguments='test2', - stderr="""\ +expect_stderr = """\ scons: *** Builder b2 must have an action to build ['foo.c']. -File "SConstruct", line 14, in ? -""", -status = 2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='test2', stderr=expect_stderr, status = 2) test.pass_test() diff --git a/test/BitKeeper/BITKEEPERCOM.py b/test/BitKeeper/BITKEEPERCOM.py index 2b76cc3..a4bdd90 100644 --- a/test/BitKeeper/BITKEEPERCOM.py +++ b/test/BitKeeper/BITKEEPERCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'BitKeeper'], BUILDERS={'Cat':Builder(action=cat)}, - BITKEEPERCOM='%(python)s my-bk-get.py $TARGET') + BITKEEPERCOM='%(_python_)s my-bk-get.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['BitKeeper', 'sub', 'fff.in'], "BitKeeper/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-bk-get.py %(sub_SConscript)s +%(_python_)s my-bk-get.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-bk-get.py aaa.in +%(_python_)s my-bk-get.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-bk-get.py ccc.in +%(_python_)s my-bk-get.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-bk-get.py %(sub_ddd_in)s +%(_python_)s my-bk-get.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-bk-get.py %(sub_fff_in)s +%(_python_)s my-bk-get.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/BitKeeper/BITKEEPERCOMSTR.py b/test/BitKeeper/BITKEEPERCOMSTR.py index 604642b..aa9e2a0 100644 --- a/test/BitKeeper/BITKEEPERCOMSTR.py +++ b/test/BitKeeper/BITKEEPERCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'BitKeeper'], BUILDERS={'Cat':Builder(action=cat)}, - BITKEEPERCOM='%(python)s my-bk-get.py $TARGET', + BITKEEPERCOM='%(_python_)s my-bk-get.py $TARGET', BITKEEPERCOMSTR='Checking out $TARGET from our fake BitKeeper') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/BuildDir/BuildDir.py b/test/BuildDir/BuildDir.py index 0bae185..f655bf9 100644 --- a/test/BuildDir/BuildDir.py +++ b/test/BuildDir/BuildDir.py @@ -129,6 +129,9 @@ if fortran and env.Detect(fortran): """ % (fortran_runtime, fortran_runtime)) test.write(['work1', 'src', 'f1.c'], r""" +#include +#include + #include "f1.h" int @@ -141,6 +144,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f2.in'], r""" +#include +#include + #include "f2.h" int @@ -153,6 +159,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f3.c'], r""" +#include +#include + #include "f3.h" int @@ -165,6 +174,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f4.in'], r""" +#include +#include + #include "f4.h" int @@ -325,6 +337,9 @@ env.Program('prog.c') """) test.write(['work2', 'prog.c'], r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/BuildDir/Sconscript-build_dir.py b/test/BuildDir/Sconscript-build_dir.py index 298eb9b..685011d 100644 --- a/test/BuildDir/Sconscript-build_dir.py +++ b/test/BuildDir/Sconscript-build_dir.py @@ -212,6 +212,9 @@ env.Program('foo', [foo_obj, 'bar.c']) """) test.write(['test2', 'bar.c'], r""" +#include +#include + void bar(void) { printf("bar.c\n"); @@ -219,6 +222,9 @@ bar(void) { """) test.write(['test2', 'foo.c'], r""" +#include +#include + int main(int argc, char *argv[]) { bar(); diff --git a/test/BuildDir/errors.py b/test/BuildDir/errors.py index 285b996..4fcd625 100644 --- a/test/BuildDir/errors.py +++ b/test/BuildDir/errors.py @@ -155,17 +155,22 @@ f.close() # build directory results in an error message, rather # than just silently failing. test.subdir('duplicate', ['duplicate', 'src1'], ['duplicate', 'src2']) -test.write(['duplicate', 'SConstruct'], """\ + +duplicate_SConstruct_path = test.workpath('duplicate', 'SConstruct') + +test.write(duplicate_SConstruct_path, """\ BuildDir('build', 'src1') BuildDir('build', 'src2') """) +expect_stderr = """ +scons: *** 'build' already has a source directory: 'src1'. +File "%(duplicate_SConstruct_path)s", line 2, in ? +""" % locals() + test.run(chdir = 'duplicate', arguments = ".", status = 2, - stderr = """ -scons: *** 'build' already has a source directory: 'src1'. -File "SConstruct", line 2, in ? -""") + stderr = expect_stderr) test.pass_test() diff --git a/test/BuildDir/nested-sconscripts.py b/test/BuildDir/nested-sconscripts.py new file mode 100644 index 0000000..d9e110e --- /dev/null +++ b/test/BuildDir/nested-sconscripts.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that nested SConscript files in a BuildDir don't throw +an OSError exception looking for the wrong file. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir(['src'], + ['src', 'md'], + ['src', 'md', 'test']) + +test.write(['src', 'SConstruct'], """\ +BUILD_DIR = '../build' + +base_env = Environment() + +for flavor in ['prod', 'debug']: + build_env = base_env.Copy() + # In real life, we would modify build_env appropriately here + FLAVOR_DIR = BUILD_DIR + '/' + flavor + Export('build_env') + BuildDir(FLAVOR_DIR, 'md', duplicate=0) + SConscript(FLAVOR_DIR + '/SConscript') +""") + +test.write(['src', 'md', 'SConscript'], """\ +SConscript('test/SConscript') +""") + +test.write(['src', 'md', 'test', 'SConscript'], """\ +# empty +""") + +test.run(chdir='src') + +test.pass_test() diff --git a/test/BuildDir/reflect.py b/test/BuildDir/reflect.py index beb7df0..9a25029 100644 --- a/test/BuildDir/reflect.py +++ b/test/BuildDir/reflect.py @@ -39,8 +39,9 @@ import re import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python -re_python = re.escape(python) + +_python_ = TestSCons._python_ +re_python = re.escape(TestSCons.python) test.write("mycc.py", """ print 'Compile' @@ -51,8 +52,8 @@ print 'Link' """) sconstruct = """ -env = Environment(CC = r'%(python)s mycc.py', - LINK = r'%(python)s mylink.py', +env = Environment(CC = r'%(_python_)s mycc.py', + LINK = r'%(_python_)s mylink.py', INCPREFIX = 'INC_', INCSUFFIX = '_CNI', CPPPATH='%(cpppath)s') # note no leading '#' @@ -86,17 +87,16 @@ test.write('SConstruct', sconstruct % locals() ) targets = re.escape(os.path.join('dir1', 'dir2')) INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2', 'dir1', 'dir2_CNI')) -# The .* after mycc\\.py below handles /nologo flags from Visual C/C++. -test.run(arguments = '', - stdout=test.wrap_stdout("""\ +# The .+ after mycc\\.py below handles /nologo flags from Visual C/C++. +expect = test.wrap_stdout("""\ scons: building associated BuildDir targets: %(targets)s -%(re_python)s mycc\\.py.* %(INC_CNI)s .+ +"%(re_python)s" mycc\\.py.* %(INC_CNI)s .+ Compile -%(re_python)s mylink\\.py .+ +"%(re_python)s" mylink\\.py .+ Link -""" % locals()), - match=TestSCons.match_re, - ) +""" % locals()) + +test.run(arguments = '', match=TestSCons.match_re, stdout=expect) # Note that we don't check for the existence of dir1/dir2/foo.h, because # this bad cpppath will expand to dir1/dir2/dir1/dir2, which means it @@ -120,9 +120,9 @@ INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2_CNI')) test.run(arguments = '', stdout=test.wrap_stdout("""\ scons: building associated BuildDir targets: %(targets)s -%(re_python)s mycc\\.py.* %(INC_CNI)s .+ +"%(re_python)s" mycc\\.py.* %(INC_CNI)s .+ Compile -%(re_python)s mylink\\.py .+ +"%(re_python)s" mylink\\.py .+ Link """ % locals()), match=TestSCons.match_re, diff --git a/test/CC/CC.py b/test/CC/CC.py index a790baa..c57b7db 100644 --- a/test/CC/CC.py +++ b/test/CC/CC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -108,13 +108,13 @@ sys.exit(0) test.write('SConstruct', """ cc = Environment().Dictionary('CC') -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CC = r'%s mycc.py', + CC = r'%(_python_)s mycc.py', CXX = cc, CXXFLAGS = []) env.Program(target = 'test1', source = 'test1.c') -""" % (python, python)) +""" % locals()) test.write('test1.c', r"""This is a .c file. /*cc*/ @@ -129,11 +129,11 @@ if os.path.normcase('.c') == os.path.normcase('.C'): test.write('SConstruct', """ cc = Environment().Dictionary('CC') -env = Environment(LINK = r'%s mylink.py', - CC = r'%s mycc.py', +env = Environment(LINK = r'%(_python_)s mylink.py', + CC = r'%(_python_)s mycc.py', CXX = cc) env.Program(target = 'test2', source = 'test2.C') -""" % (python, python)) +""" % locals()) test.write('test2.C', r"""This is a .C file. /*cc*/ @@ -158,12 +158,15 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() cc = foo.Dictionary('CC') -bar = Environment(CC = r'%s wrapper.py ' + cc) +bar = Environment(CC = r'%(_python_)s wrapper.py ' + cc) foo.Program(target = 'foo', source = 'foo.c') bar.Program(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include +#include + int main(int argc, char *argv[]) { @@ -174,6 +177,9 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CC/CCCOM.py b/test/CC/CCCOM.py index 1be89a3..ca13ec8 100644 --- a/test/CC/CCCOM.py +++ b/test/CC/CCCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.c') env.Object(target = 'test2', source = 'test2%(alt_c_suffix)s') diff --git a/test/CC/CCCOMSTR.py b/test/CC/CCCOMSTR.py index 1dd6a57..50ddb5a 100644 --- a/test/CC/CCCOMSTR.py +++ b/test/CC/CCCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', CCCOMSTR = 'Building $TARGET from $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.c') diff --git a/test/CC/CCFLAGS.py b/test/CC/CCFLAGS.py index d05cdef..bee2499 100644 --- a/test/CC/CCFLAGS.py +++ b/test/CC/CCFLAGS.py @@ -50,6 +50,9 @@ foo.Program(target = 'prog', source = 'prog.c', """ % (fooflags, barflags, _obj, _obj, _obj, _obj)) test.write('prog.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CC/SHCC.py b/test/CC/SHCC.py index 3679a9e..9a025b1 100644 --- a/test/CC/SHCC.py +++ b/test/CC/SHCC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,12 +44,15 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() shcc = foo.Dictionary('SHCC') -bar = Environment(SHCC = r'%s wrapper.py ' + shcc) +bar = Environment(SHCC = r'%(_python_)s wrapper.py ' + shcc) foo.SharedObject(target = 'foo/foo', source = 'foo.c') bar.SharedObject(target = 'bar/bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include +#include + int main(int argc, char *argv[]) { @@ -60,6 +63,9 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CC/SHCCCOM.py b/test/CC/SHCCCOM.py index 13cdaa8..5606fd0 100644 --- a/test/CC/SHCCCOM.py +++ b/test/CC/SHCCCOM.py @@ -33,7 +33,7 @@ import TestSCons Test the ability to configure the $SHCCCOM construction variable. """ -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -54,7 +54,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.c') env.SharedObject(target = 'test2', source = 'test2%(alt_c_suffix)s') diff --git a/test/CC/SHCCCOMSTR.py b/test/CC/SHCCCOMSTR.py index 27e5cbc..4d240ae 100644 --- a/test/CC/SHCCCOMSTR.py +++ b/test/CC/SHCCCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_c_suffix = '.c' test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHCCCOMSTR = 'Building $TARGET from $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.c') diff --git a/test/CC/SHCCFLAGS.py b/test/CC/SHCCFLAGS.py index 1f4fd3d..316da0f 100644 --- a/test/CC/SHCCFLAGS.py +++ b/test/CC/SHCCFLAGS.py @@ -28,16 +28,13 @@ import sys import TestSCons import os import string - -if sys.platform == 'win32': - fooflags = '/nologo -DFOO' - barflags = '/nologo -DBAR' -else: - fooflags = '-DFOO' - barflags = '-DBAR' test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCCFLAGS'] + ' -DFOO' +barflags = e['SHCCFLAGS'] + ' -DBAR' + if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' if string.find(sys.platform, 'irix') > -1: @@ -79,6 +76,8 @@ EXPORTS """) test.write('prog.c', r""" +#include + void doIt() { diff --git a/test/CFILESUFFIX.py b/test/CFILESUFFIX.py index a122fe0..9cbadf2 100644 --- a/test/CFILESUFFIX.py +++ b/test/CFILESUFFIX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,10 +46,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', tools = ['lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) env.CFile(target = 'foo', source = 'foo.l') env.Copy(CFILESUFFIX = '.xyz').CFile(target = 'bar', source = 'bar.l') -""" % python) +""" % locals()) input = r""" int diff --git a/test/CPPDEFINES.py b/test/CPPDEFINES.py index 7c65401..8639eb2 100644 --- a/test/CPPDEFINES.py +++ b/test/CPPDEFINES.py @@ -87,6 +87,9 @@ baz.Program(target = 'baz', source = 'baz.cpp') """) test.write('prog.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CPPFLAGS.py b/test/CPPFLAGS.py index 72b10b7..ce8bd77 100644 --- a/test/CPPFLAGS.py +++ b/test/CPPFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj _shobj = TestSCons._shobj @@ -102,14 +102,14 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(CPPFLAGS = '-x', - LINK = r'%s mylink.py', + LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CC = r'%s mygcc.py cc', - CXX = r'%s mygcc.py c++', + CC = r'%(_python_)s mygcc.py cc', + CXX = r'%(_python_)s mygcc.py c++', CXXFLAGS = [], - FORTRAN = r'%s mygcc.py g77') + FORTRAN = r'%(_python_)s mygcc.py g77') env.Program(target = 'foo', source = Split('test1.c test2.cpp test3.F')) -""" % (python, python, python, python)) +""" % locals()) test.write('test1.c', r"""test1.c #cc @@ -139,15 +139,15 @@ else: test.write('SConstruct', """ env = Environment(CPPFLAGS = '-x', - SHLINK = r'%s mylink.py', + SHLINK = r'%(_python_)s mylink.py', SHLINKFLAGS = [], - CC = r'%s mygcc.py cc', - CXX = r'%s mygcc.py c++', + CC = r'%(_python_)s mygcc.py cc', + CXX = r'%(_python_)s mygcc.py c++', CXXFLAGS = [], - FORTRAN = r'%s mygcc.py g77') + FORTRAN = r'%(_python_)s mygcc.py g77') env.SharedLibrary(target = File('foo.bar'), source = Split('test1.c test2.cpp test3.F')) -""" % (python, python, python, python)) +""" % locals()) test.write('test1.c', r"""test1.c #cc diff --git a/test/CPPSUFFIXES.py b/test/CPPSUFFIXES.py index a340a4a..305cf04 100644 --- a/test/CPPSUFFIXES.py +++ b/test/CPPSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $CPPSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(CPPPATH = ['.'], - CC = r'%s mycc.py', + CC = r'%(_python_)s mycc.py', CCFLAGS = [], CCCOM = '$CC $TARGET $SOURCES', OBJSUFFIX = '.o') @@ -60,7 +60,7 @@ env.Object(target = 'test1', source = 'test1.c') env.InstallAs('test1_c', 'test1.c') env.InstallAs('test1_h', 'test1.h') env.InstallAs('test1_x', 'test1.x') -""" % (python,)) +""" % locals()) test.write('test1.c', """\ test1.c 1 @@ -80,12 +80,14 @@ test1.x 1 test.write('foo.h', "foo.h 1\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c Install file: "test1.c" as "test1_c" Install file: "test1.h" as "test1_h" Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 @@ -99,9 +101,11 @@ test.up_to_date(arguments='.') test.write('foo.h', "foo.h 2\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c -""" % (python,))) +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 @@ -118,10 +122,12 @@ test1.x 2 #include """) -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 """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mycc.py test1.o test1.c +expect = test.wrap_stdout("""\ +%(_python_)s mycc.py test1.o test1.c Install file: "test1.h" as "test1_h" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.c 1 diff --git a/test/CVS.py b/test/CVS.py index 3002ee7..c21d9ad 100644 --- a/test/CVS.py +++ b/test/CVS.py @@ -97,7 +97,8 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(ENV = { 'PATH' : os.environ['PATH'] }, +env = Environment(ENV = { 'PATH' : os.environ['PATH'], + 'EDITOR' : os.environ.get('EDITOR', 'ed') }, BUILDERS={'Cat':Builder(action=cat)}) env.Prepend(CVSFLAGS='-Q') env.Cat('aaa.out', 'foo/aaa.in') @@ -161,7 +162,8 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(ENV = { 'PATH' : os.environ['PATH'] }, +env = Environment(ENV = { 'PATH' : os.environ['PATH'], + 'EDITOR' : os.environ.get('EDITOR', 'ed') }, BUILDERS={'Cat':Builder(action=cat)}) env.Prepend(CVSFLAGS='-q') env.Cat('aaa.out', 'aaa.in') @@ -232,7 +234,8 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(ENV = { 'PATH' : os.environ['PATH'] }, +env = Environment(ENV = { 'PATH' : os.environ['PATH'], + 'EDITOR' : os.environ.get('EDITOR', 'ed') }, BUILDERS={'Cat':Builder(action=cat)}, CVSROOT=r'%s') env.Prepend(CVSFLAGS='-q') diff --git a/test/CVSCOM.py b/test/CVSCOM.py index f8eaa6a..cbb2f3f 100644 --- a/test/CVSCOM.py +++ b/test/CVSCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'CVS'], BUILDERS={'Cat':Builder(action=cat)}, - CVSCOM='%(python)s my-cvs-co-.py $TARGET') + CVSCOM='%(_python_)s my-cvs-co-.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['CVS', 'sub', 'fff.in'], "CVS/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-cvs-co-.py %(sub_SConscript)s +%(_python_)s my-cvs-co-.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-cvs-co-.py aaa.in +%(_python_)s my-cvs-co-.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-cvs-co-.py ccc.in +%(_python_)s my-cvs-co-.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-cvs-co-.py %(sub_ddd_in)s +%(_python_)s my-cvs-co-.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-cvs-co-.py %(sub_fff_in)s +%(_python_)s my-cvs-co-.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/CVSCOMSTR.py b/test/CVSCOMSTR.py index 78c40f7..acf0647 100644 --- a/test/CVSCOMSTR.py +++ b/test/CVSCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'CVS'], BUILDERS={'Cat':Builder(action=cat)}, - CVSCOM='%(python)s my-cvs-co.py $TARGET', + CVSCOM='%(_python_)s my-cvs-co.py $TARGET', CVSCOMSTR='Checking out $TARGET from our fake CVS') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py index 70a9b82..a1b4c2a 100644 --- a/test/CXX/CXX.py +++ b/test/CXX/CXX.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -107,16 +107,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CXX = r'%s myc++.py', + CXX = r'%(_python_)s myc++.py', CXXFLAGS = []) env.Program(target = 'test1', source = 'test1.cc') env.Program(target = 'test2', source = 'test2.cpp') env.Program(target = 'test3', source = 'test3.cxx') env.Program(target = 'test4', source = 'test4.c++') env.Program(target = 'test5', source = 'test5.C++') -""" % (python, python)) +""" % locals()) test.write('test1.cc', r"""This is a .cc file. /*c++*/ @@ -158,12 +158,12 @@ test.must_match('test5' + _exe, "This is a .C++ file.\n") if TestSCons.case_sensitive_suffixes('.c', '.C'): test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - CXX = r'%s myc++.py', + CXX = r'%(_python_)s myc++.py', CXXFLAGS = []) env.Program(target = 'test6', source = 'test6.C') -""" % (python, python)) +""" % locals()) test.write('test6.C', r"""This is a .C file. /*c++*/ @@ -188,10 +188,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() cxx = foo.Dictionary('CXX') -bar = Environment(CXX = r'%s wrapper.py ' + cxx) +bar = Environment(CXX = r'%(_python_)s wrapper.py ' + cxx) foo.Program(target = 'foo', source = 'foo.cxx') bar.Program(target = 'bar', source = 'bar.cxx') -""" % python) +""" % locals()) test.write('foo.cxx', r""" #include diff --git a/test/CXX/CXXCOM.py b/test/CXX/CXXCOM.py index c4c419d..c98fb8c 100644 --- a/test/CXX/CXXCOM.py +++ b/test/CXX/CXXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.cpp') env.Object(target = 'test2', source = 'test2.cc') diff --git a/test/CXX/CXXCOMSTR.py b/test/CXX/CXXCOMSTR.py index 82f7ace..23bd3e6 100644 --- a/test/CXX/CXXCOMSTR.py +++ b/test/CXX/CXXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', CXXCOMSTR = 'Building $TARGET from $SOURCE', OBJSUFFIX='.obj') env.Object(target = 'test1', source = 'test1.cpp') diff --git a/test/CXX/CXXFILESUFFIX.py b/test/CXX/CXXFILESUFFIX.py index 8f4c4fa..62e8cc1 100644 --- a/test/CXX/CXXFILESUFFIX.py +++ b/test/CXX/CXXFILESUFFIX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,10 +46,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', tools = ['lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) env.CXXFile(target = 'foo', source = 'foo.ll') env.Copy(CXXFILESUFFIX = '.xyz').CXXFile(target = 'bar', source = 'bar.ll') -""" % python) +""" % locals()) input = r""" int diff --git a/test/CXX/SHCXX.py b/test/CXX/SHCXX.py index 5c050d1..c02086b 100644 --- a/test/CXX/SHCXX.py +++ b/test/CXX/SHCXX.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,10 +44,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() shcxx = foo.Dictionary('SHCXX') -bar = Environment(SHCXX = r'%s wrapper.py ' + shcxx) +bar = Environment(SHCXX = r'%(_python_)s wrapper.py ' + shcxx) foo.SharedObject(target = 'foo/foo', source = 'foo.cpp') bar.SharedObject(target = 'bar/bar', source = 'bar.cpp') -""" % python) +""" % locals()) test.write('foo.cpp', r""" #include diff --git a/test/CXX/SHCXXCOM.py b/test/CXX/SHCXXCOM.py index 54ef0d5..600049e 100644 --- a/test/CXX/SHCXXCOM.py +++ b/test/CXX/SHCXXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(SHCXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.cpp') env.SharedObject(target = 'test2', source = 'test2.cc') diff --git a/test/CXX/SHCXXCOMSTR.py b/test/CXX/SHCXXCOMSTR.py index ad3a907..33beae7 100644 --- a/test/CXX/SHCXXCOMSTR.py +++ b/test/CXX/SHCXXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: alt_cpp_suffix = '.C' test.write('SConstruct', """ -env = Environment(SHCXXCOM = r'%(python)s mycc.py $TARGET $SOURCE', +env = Environment(SHCXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE', SHCXXCOMSTR = 'Building shared object $TARGET from $SOURCE', SHOBJSUFFIX='.obj') env.SharedObject(target = 'test1', source = 'test1.cpp') diff --git a/test/CXX/SHCXXFLAGS.py b/test/CXX/SHCXXFLAGS.py index 88da443..049835c 100644 --- a/test/CXX/SHCXXFLAGS.py +++ b/test/CXX/SHCXXFLAGS.py @@ -29,15 +29,8 @@ import TestSCons import os import string -if sys.platform == 'win32': - _obj = '.obj' - fooflags = '/nologo -DFOO' - barflags = '/nologo -DBAR' -else: - _obj = '.o' - fooflags = '-DFOO' - barflags = '-DBAR' - +_obj = TestSCons._obj + if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' if string.find(sys.platform, 'irix') > -1: @@ -45,6 +38,10 @@ if string.find(sys.platform, 'irix') > -1: test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCXXFLAGS'] + ' -DFOO' +barflags = e['SHCXXFLAGS'] + ' -DBAR' + test.write('SConstruct', """ foo = Environment(SHCXXFLAGS = '%s', WINDOWS_INSERT_DEF=1) bar = Environment(SHCXXFLAGS = '%s', WINDOWS_INSERT_DEF=1) diff --git a/test/CacheDir.py b/test/CacheDir.py deleted file mode 100644 index 67d3ed4..0000000 --- a/test/CacheDir.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Test retrieving derived files from a CacheDir. -""" - -import os.path -import shutil - -import TestSCons - -test = TestSCons.TestSCons() - -# cache2 omitted from list in order to test automatic creation of CacheDir -# directory. -test.subdir('cache1', 'cache3', 'src', 'subdir') - -test.write(['src', 'SConstruct'], """\ -CacheDir(r'%s') -SConscript('SConscript') -""" % test.workpath('cache1')) - -test.write(['src', 'SConscript'], """\ -def cat(env, source, target): - target = str(target[0]) - open('cat.out', 'ab').write(target + "\\n") - source = map(str, source) - f = open(target, "wb") - for src in source: - f.write(open(src, "rb").read()) - f.close() -env = Environment(BUILDERS={'Cat':Builder(action=cat)}) -env.Cat('aaa.out', 'aaa.in') -env.Cat('bbb.out', 'bbb.in') -env.Cat('ccc.out', 'ccc.in') -env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) -""") - -test.write(['src', 'aaa.in'], "aaa.in\n") -test.write(['src', 'bbb.in'], "bbb.in\n") -test.write(['src', 'ccc.in'], "ccc.in\n") - -############################################################################# - -# Verify that building with -n and an empty cache reports that proper -# build operations would be taken, but that nothing is actually built -# and that the cache is still empty. -test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ -cat(["aaa.out"], ["aaa.in"]) -cat(["bbb.out"], ["bbb.in"]) -cat(["ccc.out"], ["ccc.in"]) -cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""")) - -test.must_not_exist(test.workpath('src', 'aaa.out')) -test.must_not_exist(test.workpath('src', 'bbb.out')) -test.must_not_exist(test.workpath('src', 'ccc.out')) -test.must_not_exist(test.workpath('src', 'all')) -test.fail_test(len(os.listdir(test.workpath('cache1')))) - -# Verify that a normal build works correctly, and clean up. -# This should populate the cache with our derived files. -test.run(chdir = 'src', arguments = '.') - -test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_match(['src', 'cat.out'], "aaa.out\nbbb.out\nccc.out\nall\n") - -test.up_to_date(chdir = 'src', arguments = '.') - -test.run(chdir = 'src', arguments = '-c .') -test.unlink(['src', 'cat.out']) - -# Verify that we now retrieve the derived files from cache, -# not rebuild them. Then clean up. -test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ -Retrieved `aaa.out' from cache -Retrieved `bbb.out' from cache -Retrieved `ccc.out' from cache -Retrieved `all' from cache -""")) - -test.must_not_exist(test.workpath('src', 'cat.out')) - -test.up_to_date(chdir = 'src', arguments = '.') - -test.run(chdir = 'src', arguments = '-c .') - -# Verify that rebuilding with -n reports that everything was retrieved -# from the cache, but that nothing really was. -test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ -Retrieved `aaa.out' from cache -Retrieved `bbb.out' from cache -Retrieved `ccc.out' from cache -Retrieved `all' from cache -""")) - -test.must_not_exist(test.workpath('src', 'aaa.out')) -test.must_not_exist(test.workpath('src', 'bbb.out')) -test.must_not_exist(test.workpath('src', 'ccc.out')) -test.must_not_exist(test.workpath('src', 'all')) - -# Verify that rebuilding with -s retrieves everything from the cache -# even though it doesn't report anything. -test.run(chdir = 'src', arguments = '-s .', stdout = "") - -test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_not_exist(test.workpath('src', 'cat.out')) - -test.up_to_date(chdir = 'src', arguments = '.') - -test.run(chdir = 'src', arguments = '-c .') - -# Verify that updating one input file builds its derived file and -# dependency but that the other files are retrieved from cache. -test.write(['src', 'bbb.in'], "bbb.in 2\n") - -test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ -Retrieved `aaa.out' from cache -cat(["bbb.out"], ["bbb.in"]) -Retrieved `ccc.out' from cache -cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""")) - -test.must_match(['src', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") -test.must_match(['src', 'cat.out'], "bbb.out\nall\n") - -test.up_to_date(chdir = 'src', arguments = '.') - -############################################################################# -# Now we try out BuildDir() functionality. -# This is largely cut-and-paste of the above, -# with appropriate directory modifications. - -build_aaa_out = os.path.join('build', 'aaa.out') -build_bbb_out = os.path.join('build', 'bbb.out') -build_ccc_out = os.path.join('build', 'ccc.out') -build_all = os.path.join('build', 'all') - -# First, clean up the source directory and start over with fresh files. -test.run(chdir = 'src', arguments = '-c .') - -test.write(['src', 'aaa.in'], "aaa.in\n") -test.write(['src', 'bbb.in'], "bbb.in\n") -test.write(['src', 'ccc.in'], "ccc.in\n") - -# -test.write('SConstruct', """\ -env = Environment(TWO = '2') -env.CacheDir(r'%s') -BuildDir('build', 'src', duplicate=0) -SConscript('build/SConscript') -""" % test.workpath('cache${TWO}')) - -# Verify that a normal build works correctly, and clean up. -# This should populate the cache with our derived files. -test.run() - -test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_match('cat.out', "%s\n%s\n%s\n%s\n" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)) - -test.up_to_date(arguments = '.') - -test.run(arguments = '-c .') -test.unlink('cat.out') - -# Verify that we now retrieve the derived files from cache, -# not rebuild them. Then clean up. -test.run(stdout = test.wrap_stdout("""\ -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) - -test.must_not_exist(test.workpath('cat.out')) - -test.up_to_date(arguments = '.') - -test.run(arguments = '-c .') - -# Verify that rebuilding with -n reports that everything was retrieved -# from the cache, but that nothing really was. -test.run(arguments = '-n .', stdout = test.wrap_stdout("""\ -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -Retrieved `%s' from cache -""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) - -test.must_not_exist(test.workpath('build', 'aaa.out')) -test.must_not_exist(test.workpath('build', 'bbb.out')) -test.must_not_exist(test.workpath('build', 'ccc.out')) -test.must_not_exist(test.workpath('build', 'all')) - -# Verify that rebuilding with -s retrieves everything from the cache -# even though it doesn't report anything. -test.run(arguments = '-s .', stdout = "") - -test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") -test.must_not_exist(test.workpath('cat.out')) - -test.up_to_date(arguments = '.') - -test.run(arguments = '-c .') - -# Verify that updating one input file builds its derived file and -# dependency but that the other files are retrieved from cache. -test.write(['src', 'bbb.in'], "bbb.in 2\n") - -test.run(stdout = test.wrap_stdout("""\ -Retrieved `%s' from cache -cat(["%s"], ["%s"]) -Retrieved `%s' from cache -cat(["%s"], ["%s", "%s", "%s"]) -""" % (build_aaa_out, - build_bbb_out, os.path.join('src', 'bbb.in'), - build_ccc_out, - build_all, build_aaa_out, build_bbb_out, build_ccc_out))) - -test.must_match(['build', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") -test.must_match('cat.out', "%s\n%s\n" % (build_bbb_out, build_all)) - -test.up_to_date(arguments = '.') - -############################################################################# -# Test the case (reported by Jeff Petkau, bug #694744) where a target -# is source for another target with a scanner, which used to cause us -# to push the file to the CacheDir after the build signature had already -# been cleared (as a sign that the built file should now be rescanned). - -test.write(['subdir', 'SConstruct'], """\ -import SCons - -CacheDir(r'%s') - -def docopy(target,source,env): - data = source[0].get_contents() - f = open(target[0].rfile().get_abspath(), "wb") - f.write(data) - f.close() - -def sillyScanner(node, env, dirs): - print 'This is never called (unless we build file.out)' - return [] - -SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res']) - -env = Environment(tools=[], - SCANNERS = [SillyScanner], - BUILDERS = {}) - -r = env.Command('file.res', 'file.ma', docopy) - -env.Command('file.out', r, docopy) - -# make r the default. Note that we don't even try to build file.out, -# and so SillyScanner never runs. The bug is the same if we build -# file.out, though. -Default(r) -""" % test.workpath('cache3')) - -test.write(['subdir', 'file.ma'], "subdir/file.ma\n") - -test.run(chdir = 'subdir') - -test.must_not_exist(test.workpath('cache3', 'N', 'None')) - -############################################################################# -# Test that multiple target files get retrieved from cache correctly. - -test.subdir('multiple', 'cache4') - -test.write(['multiple', 'SConstruct'], """\ -def touch(env, source, target): - open('foo', 'w').write("") - open('bar', 'w').write("") -CacheDir(r'%s') -env = Environment() -env.Command(['foo', 'bar'], ['input'], touch) -""" % (test.workpath('cache4'))) - -test.write(['multiple', 'input'], "multiple/input\n") - -test.run(chdir = 'multiple') - -test.must_exist(test.workpath('multiple', 'foo')) -test.must_exist(test.workpath('multiple', 'bar')) - -test.run(chdir = 'multiple', arguments = '-c') - -test.must_not_exist(test.workpath('multiple', 'foo')) -test.must_not_exist(test.workpath('multiple', 'bar')) - -test.run(chdir = 'multiple') - -test.must_exist(test.workpath('multiple', 'foo')) -test.must_exist(test.workpath('multiple', 'bar')) - -# All done. -test.pass_test() diff --git a/test/CacheDir/BuildDir.py b/test/CacheDir/BuildDir.py new file mode 100644 index 0000000..d03bfa6 --- /dev/null +++ b/test/CacheDir/BuildDir.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test retrieving derived files from a CacheDir when a BuildDir is used. +""" + +import os.path + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('cache', 'src') + +cache = test.workpath('cache') +cat_out = test.workpath('cat.out') + +test.write(['src', 'SConstruct'], """\ +CacheDir(r'%(cache)s') +SConscript('SConscript') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +def cat(env, source, target): + target = str(target[0]) + open('cat.out', 'ab').write(target + "\\n") + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +build_aaa_out = os.path.join('build', 'aaa.out') +build_bbb_out = os.path.join('build', 'bbb.out') +build_ccc_out = os.path.join('build', 'ccc.out') +build_all = os.path.join('build', 'all') + +test.write(['src', 'aaa.in'], "aaa.in\n") +test.write(['src', 'bbb.in'], "bbb.in\n") +test.write(['src', 'ccc.in'], "ccc.in\n") + +# +test.write('SConstruct', """\ +env = Environment(TWO = '2') +env.CacheDir(r'%s') +BuildDir('build', 'src', duplicate=0) +SConscript('build/SConscript') +""" % test.workpath('cache${TWO}')) + +# Verify that a normal build works correctly, and clean up. +# This should populate the cache with our derived files. +test.run() + +test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_match('cat.out', "%s\n%s\n%s\n%s\n" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)) + +test.up_to_date(arguments = '.') + +test.run(arguments = '-c .') +test.unlink('cat.out') + +# Verify that we now retrieve the derived files from cache, +# not rebuild them. Then clean up. +test.run(stdout = test.wrap_stdout("""\ +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) + +test.must_not_exist(cat_out) + +test.up_to_date(arguments = '.') + +test.run(arguments = '-c .') + +# Verify that rebuilding with -n reports that everything was retrieved +# from the cache, but that nothing really was. +test.run(arguments = '-n .', stdout = test.wrap_stdout("""\ +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +Retrieved `%s' from cache +""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))) + +test.must_not_exist(test.workpath('build', 'aaa.out')) +test.must_not_exist(test.workpath('build', 'bbb.out')) +test.must_not_exist(test.workpath('build', 'ccc.out')) +test.must_not_exist(test.workpath('build', 'all')) + +# Verify that rebuilding with -s retrieves everything from the cache +# even though it doesn't report anything. +test.run(arguments = '-s .', stdout = "") + +test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_not_exist(cat_out) + +test.up_to_date(arguments = '.') + +test.run(arguments = '-c .') + +# Verify that updating one input file builds its derived file and +# dependency but that the other files are retrieved from cache. +test.write(['src', 'bbb.in'], "bbb.in 2\n") + +test.run(stdout = test.wrap_stdout("""\ +Retrieved `%s' from cache +cat(["%s"], ["%s"]) +Retrieved `%s' from cache +cat(["%s"], ["%s", "%s", "%s"]) +""" % (build_aaa_out, + build_bbb_out, os.path.join('src', 'bbb.in'), + build_ccc_out, + build_all, build_aaa_out, build_bbb_out, build_ccc_out))) + +test.must_match(['build', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") +test.must_match('cat.out', "%s\n%s\n" % (build_bbb_out, build_all)) + +test.up_to_date(arguments = '.') + + + +test.pass_test() diff --git a/test/CacheDir/CacheDir.py b/test/CacheDir/CacheDir.py new file mode 100644 index 0000000..f918707 --- /dev/null +++ b/test/CacheDir/CacheDir.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test retrieving derived files from a CacheDir. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +cache = test.workpath('cache') + +src_aaa_out = test.workpath('src', 'aaa.out') +src_bbb_out = test.workpath('src', 'bbb.out') +src_ccc_out = test.workpath('src', 'ccc.out') +src_cat_out = test.workpath('src', 'cat.out') +src_all = test.workpath('src', 'all') + +test.subdir('cache', 'src') + +test.write(['src', 'SConstruct'], """\ +CacheDir(r'%(cache)s') +SConscript('SConscript') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +def cat(env, source, target): + target = str(target[0]) + open('cat.out', 'ab').write(target + "\\n") + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +test.write(['src', 'aaa.in'], "aaa.in\n") +test.write(['src', 'bbb.in'], "bbb.in\n") +test.write(['src', 'ccc.in'], "ccc.in\n") + +# Verify that building with -n and an empty cache reports that proper +# build operations would be taken, but that nothing is actually built +# and that the cache is still empty. +test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ +cat(["aaa.out"], ["aaa.in"]) +cat(["bbb.out"], ["bbb.in"]) +cat(["ccc.out"], ["ccc.in"]) +cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) +""")) + +test.must_not_exist(src_aaa_out) +test.must_not_exist(src_bbb_out) +test.must_not_exist(src_ccc_out) +test.must_not_exist(src_all) +test.fail_test(len(os.listdir(cache))) + +# Verify that a normal build works correctly, and clean up. +# This should populate the cache with our derived files. +test.run(chdir = 'src', arguments = '.') + +test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_match(['src', 'cat.out'], "aaa.out\nbbb.out\nccc.out\nall\n") + +test.up_to_date(chdir = 'src', arguments = '.') + +test.run(chdir = 'src', arguments = '-c .') +test.unlink(['src', 'cat.out']) + +# Verify that we now retrieve the derived files from cache, +# not rebuild them. Then clean up. +test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ +Retrieved `aaa.out' from cache +Retrieved `bbb.out' from cache +Retrieved `ccc.out' from cache +Retrieved `all' from cache +""")) + +test.must_not_exist(src_cat_out) + +test.up_to_date(chdir = 'src', arguments = '.') + +test.run(chdir = 'src', arguments = '-c .') + +# Verify that rebuilding with -n reports that everything was retrieved +# from the cache, but that nothing really was. +test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\ +Retrieved `aaa.out' from cache +Retrieved `bbb.out' from cache +Retrieved `ccc.out' from cache +Retrieved `all' from cache +""")) + +test.must_not_exist(src_aaa_out) +test.must_not_exist(src_bbb_out) +test.must_not_exist(src_ccc_out) +test.must_not_exist(src_all) + +# Verify that rebuilding with -s retrieves everything from the cache +# even though it doesn't report anything. +test.run(chdir = 'src', arguments = '-s .', stdout = "") + +test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n") +test.must_not_exist(src_cat_out) + +test.up_to_date(chdir = 'src', arguments = '.') + +test.run(chdir = 'src', arguments = '-c .') + +# Verify that updating one input file builds its derived file and +# dependency but that the other files are retrieved from cache. +test.write(['src', 'bbb.in'], "bbb.in 2\n") + +test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\ +Retrieved `aaa.out' from cache +cat(["bbb.out"], ["bbb.in"]) +Retrieved `ccc.out' from cache +cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) +""")) + +test.must_match(['src', 'all'], "aaa.in\nbbb.in 2\nccc.in\n") +test.must_match(['src', 'cat.out'], "bbb.out\nall\n") + +test.up_to_date(chdir = 'src', arguments = '.') + + +test.pass_test() diff --git a/test/CacheDir/SideEffect.py b/test/CacheDir/SideEffect.py new file mode 100644 index 0000000..814a5e3 --- /dev/null +++ b/test/CacheDir/SideEffect.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that use of SideEffect() doesn't interfere with CacheDir. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('cache', 'work') + +cache = test.workpath('cache') + +test.write(['work', 'SConstruct'], """\ +def copy(source, target): + open(target, "wb").write(open(source, "rb").read()) + +def build(env, source, target): + s = str(source[0]) + t = str(target[0]) + copy(s, t) + if target[0].side_effects: + side_effect = open(str(target[0].side_effects[0]), "ab") + side_effect.write(s + ' -> ' + t + '\\n') + +CacheDir(r'%(cache)s') + +Build = Builder(action=build) +env = Environment(BUILDERS={'Build':Build}, SUBDIR='subdir') +env.Build('f1.out', 'f1.in') +env.Build('f2.out', 'f2.in') +env.Build('f3.out', 'f3.in') +SideEffect('log.txt', ['f1.out', 'f2.out', 'f3.out']) +""" % locals()) + +test.write(['work', 'f1.in'], 'f1.in\n') +test.write(['work', 'f2.in'], 'f2.in\n') +test.write(['work', 'f3.in'], 'f3.in\n') + +test.run(chdir='work', arguments='f1.out f2.out') + +expect = """\ +f1.in -> f1.out +f2.in -> f2.out +""" + +test.must_match(['work', 'log.txt'], expect) + + + +test.write(['work', 'f2.in'], 'f2.in 2 \n') + +test.run(chdir='work', arguments='log.txt') + +expect = """\ +f1.in -> f1.out +f2.in -> f2.out +f2.in -> f2.out +f3.in -> f3.out +""" + +test.must_match(['work', 'log.txt'], expect) + + + +test.write(['work', 'f1.in'], 'f1.in 2 \n') + +test.run(chdir='work', arguments=".") + +expect = """\ +f1.in -> f1.out +f2.in -> f2.out +f2.in -> f2.out +f3.in -> f3.out +f1.in -> f1.out +""" + +test.must_match(['work', 'log.txt'], expect) + + + +test.pass_test() diff --git a/test/CacheDir/debug.py b/test/CacheDir/debug.py new file mode 100644 index 0000000..ebf67f7 --- /dev/null +++ b/test/CacheDir/debug.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test the --cache-debug option to see if it prints the expected messages. + +Note that we don't check for the "race condition" message when someone +else's build populates the CacheDir with a file in between the time we +to build it because it doesn't exist in the CacheDir, and the time our +build of the file completes and we push it out. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons(match=TestSCons.match_re) + +test.subdir('cache', 'src') + +cache = test.workpath('cache') +debug_out = test.workpath('cache-debug.out') + + + +test.write(['src', 'SConstruct'], """\ +CacheDir(r'%(cache)s') +SConscript('SConscript') +""" % locals()) + +test.write(['src', 'SConscript'], """\ +def cat(env, source, target): + target = str(target[0]) + open('cat.out', 'ab').write(target + "\\n") + source = map(str, source) + f = open(target, "wb") + for src in source: + f.write(open(src, "rb").read()) + f.close() +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +test.write(['src', 'aaa.in'], "aaa.in\n") +test.write(['src', 'bbb.in'], "bbb.in\n") +test.write(['src', 'ccc.in'], "ccc.in\n") + + + +# Test for messages about files not being in CacheDir, with -n (don't +# actually build or push) and sendinig the message to a file. + +expect = \ +r"""cat\(\["aaa.out"\], \["aaa.in"\]\) +cat\(\["bbb.out"\], \["bbb.in"\]\) +cat\(\["ccc.out"\], \["ccc.in"\]\) +cat\(\["all"\], \["aaa.out", "bbb.out", "ccc.out"\]\) +""" + +test.run(chdir='src', + arguments='-n -Q --cache-debug=%s .' % debug_out, + stdout=expect) + +expect = \ +r"""CacheRetrieve\(aaa.out\): [0-9a-fA-F]+ not in cache +CacheRetrieve\(bbb.out\): [0-9a-fA-F]+ not in cache +CacheRetrieve\(ccc.out\): [0-9a-fA-F]+ not in cache +CacheRetrieve\(all\): [0-9a-fA-F]+ not in cache +""" + +test.must_match(debug_out, expect, mode='r') + + + +# Test for messages about actually pushing to the cache, without -n +# and to standard ouput. + +expect = \ +r"""CacheRetrieve\(aaa.out\): [0-9a-fA-F]+ not in cache +cat\(\["aaa.out"\], \["aaa.in"\]\) +CachePush\(aaa.out\): pushing to [0-9a-fA-F]+ +CacheRetrieve\(bbb.out\): [0-9a-fA-F]+ not in cache +cat\(\["bbb.out"\], \["bbb.in"\]\) +CachePush\(bbb.out\): pushing to [0-9a-fA-F]+ +CacheRetrieve\(ccc.out\): [0-9a-fA-F]+ not in cache +cat\(\["ccc.out"\], \["ccc.in"\]\) +CachePush\(ccc.out\): pushing to [0-9a-fA-F]+ +CacheRetrieve\(all\): [0-9a-fA-F]+ not in cache +cat\(\["all"\], \["aaa.out", "bbb.out", "ccc.out"\]\) +CachePush\(all\): pushing to [0-9a-fA-F]+ +""" + +test.run(chdir='src', + arguments='-Q --cache-debug=- .', + stdout=expect) + + + +# Clean up the local targets. + +test.run(chdir='src', arguments='-c --cache-debug=%s .' % debug_out) +test.unlink(['src', 'cat.out']) + + + +# Test for messages about retrieving files from CacheDir, with -n +# and sending the messages to standard output. + +expect = \ +r"""Retrieved `aaa.out' from cache +CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+ +Retrieved `bbb.out' from cache +CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+ +Retrieved `ccc.out' from cache +CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+ +Retrieved `all' from cache +CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+ +""" + +test.run(chdir='src', + arguments='-n -Q --cache-debug=- .', + stdout=expect) + + + +# And finally test for message about retrieving file from CacheDir +# *without* -n and sending the message to a file. + +expect = \ +r"""Retrieved `aaa.out' from cache +Retrieved `bbb.out' from cache +Retrieved `ccc.out' from cache +Retrieved `all' from cache +""" + +test.run(chdir='src', + arguments='-Q --cache-debug=%s .' % debug_out, + stdout=expect) + +expect = \ +r"""CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+ +CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+ +CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+ +CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+ +""" + +test.must_match(debug_out, expect, mode='r') + + + +test.pass_test() diff --git a/test/CacheDir/multi-targets.py b/test/CacheDir/multi-targets.py new file mode 100644 index 0000000..0de0331 --- /dev/null +++ b/test/CacheDir/multi-targets.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that multiple target files get retrieved from a CacheDir correctly. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('cache', 'multiple') + +cache = test.workpath('cache') + +multiple_bar = test.workpath('multiple', 'bar') +multiple_foo = test.workpath('multiple', 'foo') + +test.write(['multiple', 'SConstruct'], """\ +def touch(env, source, target): + open('foo', 'w').write("") + open('bar', 'w').write("") +CacheDir(r'%(cache)s') +env = Environment() +env.Command(['foo', 'bar'], ['input'], touch) +""" % locals()) + +test.write(['multiple', 'input'], "multiple/input\n") + +test.run(chdir = 'multiple') + +test.must_exist(multiple_foo) +test.must_exist(multiple_bar) + +test.run(chdir = 'multiple', arguments = '-c') + +test.must_not_exist(multiple_foo) +test.must_not_exist(multiple_bar) + +test.run(chdir = 'multiple') + +test.must_exist(multiple_foo) +test.must_exist(multiple_bar) + + + +test.pass_test() diff --git a/test/CacheDir/source-scanner.py b/test/CacheDir/source-scanner.py new file mode 100644 index 0000000..119a959 --- /dev/null +++ b/test/CacheDir/source-scanner.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test retrieving derived files from a CacheDir. + +This tests the case reported by Jeff Petkau (SourceForge bug #694744) +where a target is source for another target with a scanner, which used +to cause us to push the file to the CacheDir after the build signature +had already been cleared (as a sign that the built file should now +be rescanned). +""" + +import TestSCons + +test = TestSCons.TestSCons() + +cache = test.workpath('cache') + +test.subdir('cache', 'subdir') + +test.write(['subdir', 'SConstruct'], """\ +import SCons + +CacheDir(r'%(cache)s') + +def docopy(target,source,env): + data = source[0].get_contents() + f = open(target[0].rfile().get_abspath(), "wb") + f.write(data) + f.close() + +def sillyScanner(node, env, dirs): + print 'This is never called (unless we build file.out)' + return [] + +SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res']) + +env = Environment(tools=[], + SCANNERS = [SillyScanner], + BUILDERS = {}) + +r = env.Command('file.res', 'file.ma', docopy) + +env.Command('file.out', r, docopy) + +# make r the default. Note that we don't even try to build file.out, +# and so SillyScanner never runs. The bug is the same if we build +# file.out, though. +Default(r) +""" % locals()) + +test.write(['subdir', 'file.ma'], "subdir/file.ma\n") + +test.run(chdir = 'subdir') + +test.must_not_exist(test.workpath(cache, 'N', 'None')) + + + +test.pass_test() diff --git a/test/Case.py b/test/Case.py index 18fb60a..9b6bb94 100644 --- a/test/Case.py +++ b/test/Case.py @@ -40,6 +40,8 @@ Program('main', [ """) test.write('main.c', """\ +#include + void foo(); void bar(); int main() { diff --git a/test/Command.py b/test/Command.py index 6563bd9..09c51ab 100644 --- a/test/Command.py +++ b/test/Command.py @@ -28,6 +28,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,30 +66,30 @@ def sub(env, target, source): t.close() return 0 -env = Environment(COPY_THROUGH_TEMP = "%(python)s build.py .tmp $SOURCE\\n%(python)s build.py $TARGET .tmp", - EXPAND = "$COPY_THROUGH_TEMP") +env = Environment(COPY_THROUGH_TEMP = '%(_python_)s build.py .tmp $SOURCE\\n%(_python_)s build.py $TARGET .tmp', + EXPAND = '$COPY_THROUGH_TEMP') env.Command(target = 'f1.out', source = 'f1.in', action = buildIt) env.Command(target = 'f2.out', source = 'f2.in', - action = r"%(python)s build.py temp2 $SOURCES" + '\\n' + r"%(python)s build.py $TARGET temp2") + action = r'%(_python_)s build.py temp2 $SOURCES' + '\\n' + r'%(_python_)s build.py $TARGET temp2') env.Command(target = 'f3.out', source = 'f3.in', action = [ [ r'%(python)s', 'build.py', 'temp3', '$SOURCES' ], [ r'%(python)s', 'build.py', '$TARGET', 'temp3'] ]) Command(target = 'f4.out', source = 'sub', action = sub) env.Command(target = 'f5.out', source = 'f5.in', action = buildIt, - XYZZY="XYZZY is set") + XYZZY='XYZZY is set') Command(target = 'f6.out', source = 'f6.in', - action = r"%(python)s build.py f6.out f6.in") + action = r'%(_python_)s build.py f6.out f6.in') env.Command(target = 'f7.out', source = 'f7.in', - action = r"%(python)s build.py $TARGET $SOURCE") + action = r'%(_python_)s build.py $TARGET $SOURCE') Command(target = 'f8.out', source = 'f8.in', - action = r"%(python)s build.py $TARGET $SOURCE") + action = r'%(_python_)s build.py $TARGET $SOURCE') env.Command(target = 'f9.out', source = 'f9.in', - action = r"$EXPAND") + action = r'$EXPAND') env.Command(target = '${F10}.out', source = '${F10}.in', - action = r"%(python)s build.py $TARGET $SOURCE", + action = r'%(_python_)s build.py $TARGET $SOURCE', F10 = 'f10') -""" % {'python': python}) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") diff --git a/test/CommandGenerator.py b/test/CommandGenerator.py index 4a99be8..947ad42 100644 --- a/test/CommandGenerator.py +++ b/test/CommandGenerator.py @@ -44,7 +44,7 @@ sys.exit(0) test.write('SConstruct', """ def g(source, target, for_signature, env): import sys - python = r"%s" + python = r'%(python)s' return [[python, "build.py", "$TEMPFILE"] + source, [python, "build.py"] + target + ["$TEMPFILE"]] @@ -54,7 +54,7 @@ env = Environment(BUILDERS = { 'b' : b }, env.b(target = 'foo1.out', source = 'foo1.in') env.b(target = 'foo2.out', source = 'foo2.in') env.b(target = 'foo3.out', source = 'foo3.in') -""" % python) +""" % locals()) test.write('foo1.in', "foo1.in\n") diff --git a/test/Configure/CONFIGUREDIR.py b/test/Configure/CONFIGUREDIR.py index 2064886..ae1ea2b 100644 --- a/test/Configure/CONFIGUREDIR.py +++ b/test/Configure/CONFIGUREDIR.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation +# __COPYRIGHT__ # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -22,7 +22,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "test/Configure.py 0.96.D308 2005/09/25 12:59:35 knight" +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test that the configure context directory can be specified by diff --git a/test/Configure/CONFIGURELOG.py b/test/Configure/CONFIGURELOG.py index 456fcc9..4b63440 100644 --- a/test/Configure/CONFIGURELOG.py +++ b/test/Configure/CONFIGURELOG.py @@ -33,7 +33,9 @@ import TestSCons test = TestSCons.TestSCons() -test.write("SConstruct", """\ +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """\ def CustomTest(context): context.Message('Executing Custom Test ...') context.Result(1) @@ -47,13 +49,13 @@ env = conf.Finish() test.run() expect = """\ -file SConstruct,line 6: +file %(SConstruct_path)s,line 6: \tConfigure(confdir = .sconf_temp) scons: Configure: Executing Custom Test ... scons: Configure: (cached) yes -""" +""" % locals() test.must_match('custom.logfile', expect, mode='r') diff --git a/test/Configure/Configure.py b/test/Configure/Configure.py index 41c858b..4063699 100644 --- a/test/Configure/Configure.py +++ b/test/Configure/Configure.py @@ -55,6 +55,7 @@ else: work_cnt = 0 work_dir = None python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _obj = TestSCons._obj _exe = TestSCons._exe @@ -123,7 +124,7 @@ def checkLogAndStdout(checks, results, cached, sconf_dir = sconf_dir sconstruct = sconstruct - log = re.escape("file " + sconstruct + ",line ") + r"\d+:" + ls + log = r'file\ \S*%s\,line \d+:' % re.escape(sconstruct) + ls if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) log = "\t" + re.escape("Configure(confdir = %s)" % sconf_dir) + ls if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd) @@ -615,9 +616,9 @@ def CustomTest(*args): return 0 conf = env.Configure(custom_tests = {'MyTest' : CustomTest}) if not conf.MyTest(): - env.Command("hello", [], "%s cmd.py $TARGET") + env.Command("hello", [], '%(_python_)s cmd.py $TARGET') env = conf.Finish() -""" % python) +""" % locals()) test.run(chdir=work_dir, stderr="Hello World on stderr\n") # 4.2 test that calling Configure from a builder results in a @@ -673,7 +674,10 @@ conf.Finish() # 5.1 test the ConfigureDryRunError reset(EXACT) # exact match - test.write([work_dir, 'SConstruct'], """ + + SConstruct_path = test.workpath(work_dir, 'SConstruct') + + test.write(SConstruct_path, """ env = Environment() import os env.AppendENVPath('PATH', os.environ['PATH']) @@ -687,15 +691,17 @@ if not (r1 and not r2): test.run(chdir=work_dir, arguments='-n', status=2, stderr=""" scons: *** Cannot create configure directory ".sconf_temp" within a dry-run. -File "SConstruct", line 5, in ? -""") +File "%(SConstruct_path)s", line 5, in ? +""" % locals()) test.must_not_exist([work_dir, 'config.log']) test.subdir([work_dir, '.sconf_temp']) + + conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") test.run(chdir=work_dir, arguments='-n', status=2, stderr=""" -scons: *** Cannot update configure test "%s" within a dry-run. -File "SConstruct", line 6, in ? -""" % os.path.join(".sconf_temp", "conftest_0.c")) +scons: *** Cannot update configure test "%(conftest_0_c)s" within a dry-run. +File "%(SConstruct_path)s", line 6, in ? +""" % locals()) test.run(chdir=work_dir) checkLogAndStdout( ["Checking for C library %s... " % lib, @@ -722,7 +728,9 @@ File "SConstruct", line 6, in ? # 5.2 test the --config= option reset(EXACT) # exact match - test.write([work_dir, 'SConstruct'], """ + SConstruct_path = test.workpath(work_dir, 'SConstruct') + + test.write(SConstruct_path, """ env = Environment(CPPPATH='#/include') import os env.AppendENVPath('PATH', os.environ['PATH']) @@ -736,10 +744,12 @@ env = conf.Finish() /* A header */ """) + conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c") + test.run(chdir=work_dir, arguments='--config=cache', status=2, stderr=""" -scons: *** "%s" is not yet built and cache is forced. -File "SConstruct", line 6, in ? -""" % os.path.join(".sconf_temp", "conftest_0.c")) +scons: *** "%(conftest_0_c)s" is not yet built and cache is forced. +File "%(SConstruct_path)s", line 6, in ? +""" % locals()) test.run(chdir=work_dir, arguments='--config=auto') checkLogAndStdout( ["Checking for C header file non_system_header1.h... ", diff --git a/test/DSUFFIXES.py b/test/DSUFFIXES.py index 9a5a55a..a344112 100644 --- a/test/DSUFFIXES.py +++ b/test/DSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $DSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,7 +57,7 @@ env = Environment() Tool('dmd')(env) # Now replace those suffixes with our fake-D things. env.Replace(DPATH = ['.'], - DC = r'%s mydc.py', + DC = r'%(_python_)s mydc.py', DFLAGS = [], DCOM = '$DC $TARGET $SOURCES', OBJSUFFIX = '.o') @@ -66,7 +66,7 @@ env.Object(target = 'test1', source = 'test1.d') env.InstallAs('test1_d', 'test1.d') env.InstallAs('test2_d', 'test2.d') env.InstallAs('test3_d', 'test3.d') -""" % (python,)) +""" % locals()) test.write('test1.d', """\ test1.d 1 @@ -86,12 +86,14 @@ import foo; test.write('foo.d', "foo.d 1\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d Install file: "test1.d" as "test1_d" Install file: "test2.d" as "test2_d" Install file: "test3.d" as "test3_d" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 @@ -105,9 +107,11 @@ test.up_to_date(arguments='.') test.write('foo.d', "foo.d 2\n") -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d -""" % (python,))) +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 @@ -124,10 +128,12 @@ test3.d 2 import foo; """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d Install file: "test3.d" as "test3_d" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 @@ -144,10 +150,12 @@ test2.d 2 import foo; """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s mydc.py test1.o test1.d +expect = test.wrap_stdout("""\ +%(_python_)s mydc.py test1.o test1.d Install file: "test2.d" as "test2_d" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.d 1 diff --git a/test/DVIPDF/DVIPDF.py b/test/DVIPDF/DVIPDF.py index 8db5785..8d36e5a 100644 --- a/test/DVIPDF/DVIPDF.py +++ b/test/DVIPDF/DVIPDF.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -72,15 +72,15 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPDF = r'%s mydvipdf.py', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPDF = r'%(_python_)s mydvipdf.py', tools=['latex', 'tex', 'dvipdf']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.DVI(target = 'test2.dvi', source = 'test2.tex') env.PDF(target = 'test1.pdf', source = dvi) env.PDF(target = 'test2.pdf', source = 'test2.dvi') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -118,13 +118,13 @@ import os foo = Environment(ENV = { 'PATH' : os.environ['PATH'] }) dvipdf = foo.Dictionary('DVIPDF') bar = Environment(ENV = { 'PATH' : os.environ['PATH'] }, - DVIPDF = r'%s wrapper.py ' + dvipdf) + DVIPDF = r'%(_python_)s wrapper.py ' + dvipdf) foo.PDF(target = 'foo.pdf', source = foo.DVI(target = 'foo.dvi', source = 'foo.tex')) bar.PDF(target = 'bar.pdf', source = bar.DVI(target = 'bar.dvi', source = 'bar.tex')) foo.PDF(target = 'xxx.pdf', source = 'xxx.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPDF/DVIPDFCOM.py b/test/DVIPDF/DVIPDFCOM.py index 61d5ce7..0d9cd8d 100644 --- a/test/DVIPDF/DVIPDFCOM.py +++ b/test/DVIPDF/DVIPDFCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $DVIPDFCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvipdf'], - DVIPDFCOM = r'%s mypdf.py $TARGET $SOURCES') + DVIPDFCOM = r'%(_python_)s mypdf.py $TARGET $SOURCES') env.PDF(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*pdf*/\n") diff --git a/test/DVIPDF/DVIPDFCOMSTR.py b/test/DVIPDF/DVIPDFCOMSTR.py index 6e57adb..cc0c909 100644 --- a/test/DVIPDF/DVIPDFCOMSTR.py +++ b/test/DVIPDF/DVIPDFCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvipdf'], - DVIPDFCOM = r'%s mypdf.py $TARGET $SOURCES', + DVIPDFCOM = r'%(_python_)s mypdf.py $TARGET $SOURCES', DVIPDFCOMSTR = 'DVIPDFing $TARGET from $SOURCE') env.PDF(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*pdf*/\n") diff --git a/test/DVIPDF/DVIPDFFLAGS.py b/test/DVIPDF/DVIPDFFLAGS.py index e9bd8ba..4268705 100644 --- a/test/DVIPDF/DVIPDFFLAGS.py +++ b/test/DVIPDF/DVIPDFFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -78,15 +78,15 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPDF = r'%s mydvipdf.py', DVIPDFFLAGS = '-x', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPDF = r'%(_python_)s mydvipdf.py', DVIPDFFLAGS = '-x', tools = ['tex', 'latex', 'dvipdf']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.DVI(target = 'test2.dvi', source = 'test2.tex') env.PDF(target = 'test1.pdf', source = dvi) env.PDF(target = 'test2.pdf', source = 'test2.dvi') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -124,13 +124,13 @@ import os ENV = {'PATH' : os.environ['PATH']} foo = Environment(DVIPDFFLAGS = '-N', ENV = ENV) dvipdf = foo.Dictionary('DVIPDF') -bar = Environment(DVIPDF = r'%s wrapper.py ' + dvipdf, ENV = ENV) +bar = Environment(DVIPDF = r'%(_python_)s wrapper.py ' + dvipdf, ENV = ENV) foo.PDF(target = 'foo.pdf', source = foo.DVI(target = 'foo.dvi', source = 'foo.tex')) bar.PDF(target = 'bar.pdf', source = bar.DVI(target = 'bar.dvi', source = 'bar.tex')) foo.PDF(target = 'xxx.pdf', source = 'xxx.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPS/DVIPS.py b/test/DVIPS/DVIPS.py index 2ae856a..490ac95 100644 --- a/test/DVIPS/DVIPS.py +++ b/test/DVIPS/DVIPS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -72,16 +72,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPS = r'%s mydvips.py', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPS = r'%(_python_)s mydvips.py', tools=['tex', 'latex', 'dvips']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.PostScript(target = 'test1.ps', source = dvi) env.PostScript(target = 'test2.ps', source = 'test2.tex') env.PostScript(target = 'test3.ps', source = 'test3.ltx') env.PostScript(target = 'test4.ps', source = 'test4.latex') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -132,12 +132,12 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) dvips = foo.Dictionary('DVIPS') -bar = Environment(ENV = ENV, DVIPS = r'%s wrapper.py ' + dvips) +bar = Environment(ENV = ENV, DVIPS = r'%(_python_)s wrapper.py ' + dvips) foo.PostScript(target = 'foo.ps', source = 'foo.tex') bar.PostScript(target = 'bar1', source = 'bar1.tex') bar.PostScript(target = 'bar2', source = 'bar2.ltx') bar.PostScript(target = 'bar3', source = 'bar3.latex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPS/DVIPSFLAGS.py b/test/DVIPS/DVIPSFLAGS.py index 82e57c5..635acb0 100644 --- a/test/DVIPS/DVIPSFLAGS.py +++ b/test/DVIPS/DVIPSFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -79,16 +79,16 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', - LATEX = r'%s mylatex.py', - DVIPS = r'%s mydvips.py', DVIPSFLAGS = '-x', +env = Environment(TEX = r'%(_python_)s mytex.py', + LATEX = r'%(_python_)s mylatex.py', + DVIPS = r'%(_python_)s mydvips.py', DVIPSFLAGS = '-x', tools=['tex', 'latex', 'dvips']) dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex') env.PostScript(target = 'test1.ps', source = dvi) env.PostScript(target = 'test2.ps', source = 'test2.tex') env.PostScript(target = 'test3.ps', source = 'test3.ltx') env.PostScript(target = 'test4.ps', source = 'test4.latex') -""" % (python, python, python)) +""" % locals()) test.write('test1.tex', r"""This is a .dvi test. #tex @@ -139,12 +139,12 @@ import os ENV = {'PATH' : os.environ['PATH']} foo = Environment(ENV = ENV, DVIPSFLAGS = '-N') dvips = foo.Dictionary('DVIPS') -bar = Environment(ENV = ENV,DVIPS = r'%s wrapper.py ' + dvips) +bar = Environment(ENV = ENV,DVIPS = r'%(_python_)s wrapper.py ' + dvips) foo.PostScript(target = 'foo.ps', source = 'foo.tex') bar.PostScript(target = 'bar1', source = 'bar1.tex') bar.PostScript(target = 'bar2', source = 'bar2.ltx') bar.PostScript(target = 'bar3', source = 'bar3.latex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/DVIPS/PSCOM.py b/test/DVIPS/PSCOM.py index 65e66a2..0d8408e 100644 --- a/test/DVIPS/PSCOM.py +++ b/test/DVIPS/PSCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $PSCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvips'], - PSCOM = r'%s myps.py $TARGET $SOURCES') + PSCOM = r'%(_python_)s myps.py $TARGET $SOURCES') env.PostScript(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*ps*/\n") diff --git a/test/DVIPS/PSCOMSTR.py b/test/DVIPS/PSCOMSTR.py index 9a565a4..67f960e 100644 --- a/test/DVIPS/PSCOMSTR.py +++ b/test/DVIPS/PSCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'dvips'], - PSCOM = r'%s myps.py $TARGET $SOURCES', + PSCOM = r'%(_python_)s myps.py $TARGET $SOURCES', PSCOMSTR = 'PostScripting $TARGET from $SOURCE') env.PostScript(target = 'aaa', source = 'aaa.dvi') -""" % python) +""" % locals()) test.write('aaa.dvi', "aaa.dvi\n/*ps*/\n") diff --git a/test/Default.py b/test/Default.py index cda34b2..22fd883 100644 --- a/test/Default.py +++ b/test/Default.py @@ -32,7 +32,7 @@ import os import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -54,44 +54,44 @@ file.close() # test.write(['one', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out') -""" % python) +""" % locals()) test.write(['two', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out', 'bar.out') -""" % python) +""" % locals()) test.write(['three', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default(Split('foo.out bar.out')) -""" % python) +""" % locals()) test.write(['four', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo bar'], source = 'foo.in') env.B(target = 'foo', source = 'foo.in') env.B(target = 'bar', source = 'bar.in') Default(['foo bar']) -""" % python) +""" % locals()) test.write(['five', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) Default(env.B(target = 'foo.out', source = 'foo.in')) Default(env.B(target = 'bar.out', source = 'bar.in')) -""" % python) +""" % locals()) for dir in ['one', 'two', 'three', 'four', 'five']: @@ -118,34 +118,34 @@ test.fail_test(test.read(test.workpath('five', 'bar.out')) != "five/bar.in\n") # Test how a None Default() argument works to disable/reset default targets. test.write(['six', 'SConstruct'], """\ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) foo = env.B(target = 'foo.out', source = 'foo.in') bar = env.B(target = 'bar.out', source = 'bar.in') Default(None) -""" % python) +""" % locals()) test.run(chdir = 'six', status = 2, stderr = "scons: *** No targets specified and no Default() targets found. Stop.\n") test.write(['seven', 'SConstruct'], """\ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) foo = env.B(target = 'foo.out', source = 'foo.in') bar = env.B(target = 'bar.out', source = 'bar.in') Default(foo, bar, None) -""" % python) +""" % locals()) test.run(chdir = 'seven', status = 2, stderr = "scons: *** No targets specified and no Default() targets found. Stop.\n") test.write(['eight', 'SConstruct'], """\ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) foo = env.B(target = 'foo.out', source = 'foo.in') bar = env.B(target = 'bar.out', source = 'bar.in') Default(foo, None, bar) -""" % python) +""" % locals()) test.run(chdir = 'eight') # no arguments, use the Default @@ -158,20 +158,20 @@ test.fail_test(test.read(test.workpath('eight', 'bar.out')) != "eight/bar.in\n") test.subdir('nine', ['nine', 'sub1']) test.write(['nine', 'SConstruct'], """\ -B = Builder(action = r'%s build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') SConscript('sub1/SConscript') -""" % python) +""" % locals()) test.write(['nine', 'xxx.in'], "xxx.in\n") test.write(['nine', 'sub1', 'SConscript'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') Default('xxx.out') -""" % python) +""" % locals()) test.write(['nine', 'sub1', 'xxx.in'], "sub1/xxx.in\n") @@ -186,19 +186,19 @@ test.subdir('ten', ['ten', 'sub2']) test.write(['ten', 'SConstruct'], """\ Default('sub2') -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') SConscript('sub2/SConscript') -""" % python) +""" % locals()) test.write(['ten', 'xxx.in'], "xxx.in\n") test.write(['ten', 'sub2', 'SConscript'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') -""" % python) +""" % locals()) test.write(['ten', 'sub2', 'xxx.in'], "sub2/xxx.in\n") @@ -211,12 +211,12 @@ test.fail_test(test.read(test.workpath('ten', 'sub2', 'xxx.out')) != "sub2/xxx.i test.subdir('eleven') test.write(['eleven', 'SConstruct'], """ -B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }, XXX = 'foo.out') env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') env.Default('$XXX') -""" % python) +""" % locals()) test.write(os.path.join('eleven', 'foo.in'), "eleven/foo.in\n"); diff --git a/test/Depends.py b/test/Depends.py index 284d6f7..d0b2199 100644 --- a/test/Depends.py +++ b/test/Depends.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,12 +42,15 @@ file.write(contents) file.close() """) +SUBDIR_foo_dep = os.path.join('$SUBDIR', 'foo.dep') +SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out') + test.write('SConstruct', """ -Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep") -Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep") +Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep') +Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep') env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir') -env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%s') -env.Depends(target = r'%s', dependency = 'subdir/bar.dep') +env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%(SUBDIR_foo_dep)s') +env.Depends(target = r'%(SUBDIR_f3_out)s', dependency = 'subdir/bar.dep') env.Foo(target = 'f1.out', source = 'f1.in') env.Foo(target = 'f2.out', source = 'f2.in') env.Bar(target = 'subdir/f3.out', source = 'f3.in') @@ -55,10 +58,7 @@ SConscript('subdir/SConscript', "env") env.Foo(target = 'f5.out', source = 'f5.in') env.Bar(target = 'sub2/f6.out', source = 'f6.in') env.Depends(target = 'f5.out', dependency = 'sub2') -""" % (python, - python, - os.path.join('$SUBDIR', 'foo.dep'), - os.path.join('$SUBDIR', 'f3.out'))) +""" % locals()) test.write(['subdir', 'SConscript'], """ Import("env") diff --git a/test/ENV.py b/test/ENV.py index 98d04f9..9a39f30 100644 --- a/test/ENV.py +++ b/test/ENV.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -38,14 +38,14 @@ bin2_build_py = test.workpath('bin2', 'build.py') test.write('SConstruct', """ import os -Bld = Builder(action = r"%s build.py $TARGET $SOURCES") +Bld = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env1 = Environment(BUILDERS = { 'Bld' : Bld }) env2 = Environment(BUILDERS = { 'Bld' : Bld }) env1['ENV']['X'] = 'env1' env2['ENV']['X'] = 'env2' env1.Bld(target = 'env1.out', source = 'input') env2.Bld(target = 'env2.out', source = 'input') -""" % python) +""" % locals()) test.write('build.py', r"""#!/usr/bin/env python @@ -65,10 +65,10 @@ test.fail_test(test.read('env2.out') != "build.py env2\ninput file\n") test.write('SConstruct', """ env = Environment() -foo = env.Command('foo', [], r'%s build.py $TARGET') +foo = env.Command('foo', [], r'%(_python_)s build.py $TARGET') env['ENV']['LIST'] = [foo, 'bar'] env['ENV']['FOO'] = foo -"""%python) +""" % locals()) test.write('build.py', r""" diff --git a/test/ESCAPE.py b/test/ESCAPE.py index bee55bc..08f4a1a 100644 --- a/test/ESCAPE.py +++ b/test/ESCAPE.py @@ -30,7 +30,7 @@ Test the ESCAPE construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ def my_escape(s): s = string.replace(s, 'file.in', 'file.xxx') return orig_escape(s) env = Environment(ESCAPE = my_escape) -env.Command('file.out', 'file.in', "%(python)s cat.py $TARGET $SOURCES") +env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES') """ % locals()) test.write('file.in', "file.in\n") diff --git a/test/Environment.py b/test/Environment.py index 9851db7..36c72e1 100644 --- a/test/Environment.py +++ b/test/Environment.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import sys -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -35,7 +35,7 @@ test.write('SConstruct', """ env=Environment(BAR='#bar.in', BLAT='subdir/../blat blat') target = env.Command('foo.out', 'foo.in', - r'%s build.py $SOURCE $TARGET ${File(BAR)} ${Dir(BLAT)}') + r'%(_python_)s build.py $SOURCE $TARGET ${File(BAR)} ${Dir(BLAT)}') target = target[0] assert target == Dir('.').File('foo.out') @@ -45,7 +45,7 @@ assert target == target.File('foo.out') e2 = env.Environment(XXX='$BAR', YYY='$BLAT') print e2['XXX'] print e2['YYY'] -"""%python) +""" % locals()) test.write('build.py', """ import sys diff --git a/test/Execute.py b/test/Execute.py index 2637a6a..44abc73 100644 --- a/test/Execute.py +++ b/test/Execute.py @@ -30,7 +30,7 @@ Test the Execute() function for executing actions directly. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,25 +45,25 @@ sys.exit(exitval) """) test.write('SConstruct', """\ -Execute("%s my_copy.py a.in a.out") -Execute(Action("%s my_copy.py b.in b.out")) +Execute('%(_python_)s my_copy.py a.in a.out') +Execute(Action('%(_python_)s my_copy.py b.in b.out')) env = Environment(COPY = 'my_copy.py') -env.Execute("%s my_copy.py c.in c.out") -env.Execute(Action("%s my_copy.py d.in d.out")) -v = env.Execute("%s $COPY e.in e.out") +env.Execute('%(_python_)s my_copy.py c.in c.out') +env.Execute(Action('%(_python_)s my_copy.py d.in d.out')) +v = env.Execute('%(_python_)s $COPY e.in e.out') assert v == 0, v -v = env.Execute(Action("%s $COPY f.in f.out")) +v = env.Execute(Action('%(_python_)s $COPY f.in f.out')) assert v == 0, v -v = env.Execute("%s $COPY g.in g.out 1") +v = env.Execute('%(_python_)s $COPY g.in g.out 1') assert v == 1, v -v = env.Execute(Action("%s $COPY h.in h.out 2")) +v = env.Execute(Action('%(_python_)s $COPY h.in h.out 2')) assert v == 2, v import shutil Execute(lambda target, source, env: shutil.copy('i.in', 'i.out')) Execute(Action(lambda target, source, env: shutil.copy('j.in', 'j.out'))) env.Execute(lambda target, source, env: shutil.copy('k.in', 'k.out')) env.Execute(Action(lambda target, source, env: shutil.copy('l.in', 'l.out'))) -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('a.in', "a.in\n") test.write('b.in', "b.in\n") diff --git a/test/Fortran/F77.py b/test/Fortran/F77.py index 1c27def..682cfb0 100644 --- a/test/Fortran/F77.py +++ b/test/Fortran/F77.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -88,10 +88,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77 = r'%s myfortran.py g77', - FORTRAN = r'%s myfortran.py fortran') + F77 = r'%(_python_)s myfortran.py g77', + FORTRAN = r'%(_python_)s myfortran.py fortran') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -106,9 +106,9 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77 = r'%s myfortran.py g77') + F77 = r'%(_python_)s myfortran.py g77') env2.Program(target = 'test21', source = 'test21.f') env2.Program(target = 'test22', source = 'test22.F') env2.Program(target = 'test23', source = 'test23.for') @@ -119,7 +119,7 @@ env2.Program(target = 'test27', source = 'test27.fpp') env2.Program(target = 'test28', source = 'test28.FPP') env2.Program(target = 'test29', source = 'test29.f77') env2.Program(target = 'test30', source = 'test30.F77') -""" % (python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -191,12 +191,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f77 = foo.Dictionary('F77') -bar = foo.Copy(F77 = r'%s wrapper.py ' + f77) +bar = foo.Copy(F77 = r'%(_python_)s wrapper.py ' + f77) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F77COM.py b/test/Fortran/F77COM.py index 9de4d17..c566d88 100644 --- a/test/Fortran/F77COM.py +++ b/test/Fortran/F77COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - F77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES', - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + F77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + F77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,10 +104,10 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - F77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES') + F77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + F77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES') env2.Program(target = 'test21', source = 'test21.f') env2.Program(target = 'test22', source = 'test22.F') env2.Program(target = 'test23', source = 'test23.for') @@ -118,7 +118,7 @@ env2.Program(target = 'test27', source = 'test27.fpp') env2.Program(target = 'test28', source = 'test28.FPP') env2.Program(target = 'test29', source = 'test29.f77') env2.Program(target = 'test30', source = 'test30.F77') -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/F77COMSTR.py b/test/Fortran/F77COMSTR.py index 721551d..7f6f1a1 100644 --- a/test/Fortran/F77COMSTR.py +++ b/test/Fortran/F77COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(F77COM = r'%(python)s myfc.py f77 $TARGET $SOURCES', +env = Environment(F77COM = r'%(_python_)s myfc.py f77 $TARGET $SOURCES', F77COMSTR = 'Building f77 $TARGET from $SOURCES', - F77PPCOM = r'%(python)s myfc.py f77pp $TARGET $SOURCES', + F77PPCOM = r'%(_python_)s myfc.py f77pp $TARGET $SOURCES', F77PPCOMSTR = 'Building f77pp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f') diff --git a/test/Fortran/F77FLAGS.py b/test/Fortran/F77FLAGS.py index d50eeb9..b1d9142 100644 --- a/test/Fortran/F77FLAGS.py +++ b/test/Fortran/F77FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -90,9 +90,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F77 = r'%s myg77.py', + F77 = r'%(_python_)s myg77.py', F77FLAGS = '-x') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -104,7 +104,7 @@ env.Program(target = 'test07', source = 'test07.fpp') env.Program(target = 'test08', source = 'test08.FPP') env.Program(target = 'test09', source = 'test09.f77') env.Program(target = 'test10', source = 'test10.F77') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#g77\n") test.write('test02.F', "This is a .F file.\n#link\n#g77\n") @@ -146,12 +146,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %FTN_LIBs) f77 = foo.Dictionary('F77') -bar = foo.Copy(F77 = r'%s wrapper.py ' + f77, F77FLAGS = '-Ix') +bar = foo.Copy(F77 = r'%(_python_)s wrapper.py ' + f77, F77FLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F90.py b/test/Fortran/F90.py index 8f8bc45..6b38e8e 100644 --- a/test/Fortran/F90.py +++ b/test/Fortran/F90.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -89,10 +89,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90 = r'%s myfortran.py f90', - FORTRAN = r'%s myfortran.py fortran') + F90 = r'%(_python_)s myfortran.py f90', + FORTRAN = r'%(_python_)s myfortran.py fortran') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -107,7 +107,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -157,12 +157,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f90 = foo.Dictionary('F90') -bar = foo.Copy(F90 = r'%s wrapper.py ' + f90) +bar = foo.Copy(F90 = r'%(_python_)s wrapper.py ' + f90) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F90COM.py b/test/Fortran/F90COM.py index bb52340..7a206da 100644 --- a/test/Fortran/F90COM.py +++ b/test/Fortran/F90COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - F90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES', - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + F90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + F90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,13 +104,13 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - F90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES') + F90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + F90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES') env2.Program(target = 'test21', source = 'test21.f90') env2.Program(target = 'test22', source = 'test22.F90') -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/F90COMSTR.py b/test/Fortran/F90COMSTR.py index bf7451c..e2e3cf5 100644 --- a/test/Fortran/F90COMSTR.py +++ b/test/Fortran/F90COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(F90COM = r'%(python)s myfc.py f90 $TARGET $SOURCES', +env = Environment(F90COM = r'%(_python_)s myfc.py f90 $TARGET $SOURCES', F90COMSTR = 'Building f90 $TARGET from $SOURCES', - F90PPCOM = r'%(python)s myfc.py f90pp $TARGET $SOURCES', + F90PPCOM = r'%(_python_)s myfc.py f90pp $TARGET $SOURCES', F90PPCOMSTR = 'Building f90pp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f90') diff --git a/test/Fortran/F90FLAGS.py b/test/Fortran/F90FLAGS.py index 69f1dfa..9a57eae 100644 --- a/test/Fortran/F90FLAGS.py +++ b/test/Fortran/F90FLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -91,11 +91,11 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F90 = r'%s myfortran.py g90', + F90 = r'%(_python_)s myfortran.py g90', F90FLAGS = '-x', - FORTRAN = r'%s myfortran.py fortran', + FORTRAN = r'%(_python_)s myfortran.py fortran', FORTRANFLAGS = '-y') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -111,7 +111,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -161,12 +161,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f90 = foo.Dictionary('F90') -bar = foo.Copy(F90 = r'%s wrapper.py ' + f90, F90FLAGS = '-Ix') +bar = foo.Copy(F90 = r'%(_python_)s wrapper.py ' + f90, F90FLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F95.py b/test/Fortran/F95.py index a19c904..1b5fc41 100644 --- a/test/Fortran/F95.py +++ b/test/Fortran/F95.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -89,10 +89,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95 = r'%s myfortran.py f95', - FORTRAN = r'%s myfortran.py fortran') + F95 = r'%(_python_)s myfortran.py f95', + FORTRAN = r'%(_python_)s myfortran.py fortran') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -107,7 +107,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -157,12 +157,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f95 = foo.Dictionary('F95') -bar = foo.Copy(F95 = r'%s wrapper.py ' + f95) +bar = foo.Copy(F95 = r'%(_python_)s wrapper.py ' + f95) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/F95COM.py b/test/Fortran/F95COM.py index 26423f8..016230a 100644 --- a/test/Fortran/F95COM.py +++ b/test/Fortran/F95COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - F95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES', - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + F95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + F95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES', + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,13 +104,13 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -env2 = Environment(LINK = r'%s mylink.py', +env2 = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - F95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES') + F95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + F95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES') env2.Program(target = 'test21', source = 'test21.f95') env2.Program(target = 'test22', source = 'test22.F95') -""" % (python, python, python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/F95COMSTR.py b/test/Fortran/F95COMSTR.py index 823ade6..ed7d1e8 100644 --- a/test/Fortran/F95COMSTR.py +++ b/test/Fortran/F95COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(F95COM = r'%(python)s myfc.py f95 $TARGET $SOURCES', +env = Environment(F95COM = r'%(_python_)s myfc.py f95 $TARGET $SOURCES', F95COMSTR = 'Building f95 $TARGET from $SOURCES', - F95PPCOM = r'%(python)s myfc.py f95pp $TARGET $SOURCES', + F95PPCOM = r'%(_python_)s myfc.py f95pp $TARGET $SOURCES', F95PPCOMSTR = 'Building f95pp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f95') diff --git a/test/Fortran/F95FLAGS.py b/test/Fortran/F95FLAGS.py index 883d9a3..7ccffed 100644 --- a/test/Fortran/F95FLAGS.py +++ b/test/Fortran/F95FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -91,11 +91,11 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - F95 = r'%s myfortran.py g95', + F95 = r'%(_python_)s myfortran.py g95', F95FLAGS = '-x', - FORTRAN = r'%s myfortran.py fortran', + FORTRAN = r'%(_python_)s myfortran.py fortran', FORTRANFLAGS = '-y') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -111,7 +111,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -161,12 +161,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f95 = foo.Dictionary('F95') -bar = foo.Copy(F95 = r'%s wrapper.py ' + f95, F95FLAGS = '-Ix') +bar = foo.Copy(F95 = r'%(_python_)s wrapper.py ' + f95, F95FLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/FORTRAN.py b/test/Fortran/FORTRAN.py index 47a0a89..1bd4407 100644 --- a/test/Fortran/FORTRAN.py +++ b/test/Fortran/FORTRAN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -87,9 +87,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - FORTRAN = r'%s myg77.py') + FORTRAN = r'%(_python_)s myg77.py') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -104,7 +104,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#g77\n") test.write('test02.F', "This is a .F file.\n#link\n#g77\n") @@ -154,12 +154,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f77 = foo.Dictionary('FORTRAN') -bar = foo.Copy(FORTRAN = r'%s wrapper.py ' + f77) +bar = foo.Copy(FORTRAN = r'%(_python_)s wrapper.py ' + f77) foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/FORTRANCOM.py b/test/Fortran/FORTRANCOM.py index f79ad6d..3e3fcb2 100644 --- a/test/Fortran/FORTRANCOM.py +++ b/test/Fortran/FORTRANCOM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,10 +84,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') + FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') env.Program(target = 'test03', source = 'test03.for') @@ -102,7 +102,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n") diff --git a/test/Fortran/FORTRANCOMSTR.py b/test/Fortran/FORTRANCOMSTR.py index db75d43..fd318c3 100644 --- a/test/Fortran/FORTRANCOMSTR.py +++ b/test/Fortran/FORTRANCOMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(FORTRANCOM = r'%(python)s myfc.py fortran $TARGET $SOURCES', +env = Environment(FORTRANCOM = r'%(_python_)s myfc.py fortran $TARGET $SOURCES', FORTRANCOMSTR = 'Building fortran $TARGET from $SOURCES', - FORTRANPPCOM = r'%(python)s myfc.py fortranpp $TARGET $SOURCES', + FORTRANPPCOM = r'%(_python_)s myfc.py fortranpp $TARGET $SOURCES', FORTRANPPCOMSTR = 'Building fortranpp $TARGET from $SOURCES', OBJSUFFIX='.obj') env.Object(source = 'test01.f') diff --git a/test/Fortran/FORTRANFLAGS.py b/test/Fortran/FORTRANFLAGS.py index 8d77d63..6dd27d7 100644 --- a/test/Fortran/FORTRANFLAGS.py +++ b/test/Fortran/FORTRANFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -90,9 +90,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(LINK = r'%s mylink.py', +env = Environment(LINK = r'%(_python_)s mylink.py', LINKFLAGS = [], - FORTRAN = r'%s myfortran.py', + FORTRAN = r'%(_python_)s myfortran.py', FORTRANFLAGS = '-x') env.Program(target = 'test01', source = 'test01.f') env.Program(target = 'test02', source = 'test02.F') @@ -108,7 +108,7 @@ env.Program(target = 'test11', source = 'test11.f90') env.Program(target = 'test12', source = 'test12.F90') env.Program(target = 'test13', source = 'test13.f95') env.Program(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#link\n#fortran\n") test.write('test02.F', "This is a .F file.\n#link\n#fortran\n") @@ -158,12 +158,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) f77 = foo.Dictionary('FORTRAN') -bar = foo.Copy(FORTRAN = r'%s wrapper.py ' + f77, FORTRANFLAGS = '-Ix') +bar = foo.Copy(FORTRAN = r'%(_python_)s wrapper.py ' + f77, FORTRANFLAGS = '-Ix') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/FORTRANMODDIR.py b/test/Fortran/FORTRANMODDIR.py index 4d594a1..f0c500c 100644 --- a/test/Fortran/FORTRANMODDIR.py +++ b/test/Fortran/FORTRANMODDIR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(FORTRANCOM = r'%(python)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET', +env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET', FORTRANMODDIR = 'modules') env.Object(target = 'test1.obj', source = 'test1.f') """ % locals()) diff --git a/test/Fortran/FORTRANSUFFIXES.py b/test/Fortran/FORTRANSUFFIXES.py index c172f7a..3011fac 100644 --- a/test/Fortran/FORTRANSUFFIXES.py +++ b/test/Fortran/FORTRANSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $FORTRANSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(FORTRANPATH = ['.'], - FORTRAN = r'%s myfc.py', + FORTRAN = r'%(_python_)s myfc.py', FORTRANCOM = '$FORTRAN $TARGET $SOURCES', OBJSUFFIX = '.o') env.Append(FORTRANSUFFIXES = ['.x']) @@ -59,7 +59,7 @@ env.Object(target = 'test1', source = 'test1.f') env.InstallAs('test1_f', 'test1.f') env.InstallAs('test1_h', 'test1.h') env.InstallAs('test1_x', 'test1.x') -""" % (python,)) +""" % locals()) test.write('test1.f', """\ test1.f 1 @@ -81,12 +81,14 @@ test.write('foo.h', """\ foo.h 1 """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f Install file: "test1.f" as "test1_f" Install file: "test1.h" as "test1_h" Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 @@ -102,9 +104,11 @@ test.write('foo.h', """\ foo.h 2 """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f -""" % (python,))) +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 @@ -121,10 +125,12 @@ test.write('test1.x', """\ INCLUDE 'foo.h' """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f Install file: "test1.x" as "test1_x" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 @@ -141,10 +147,12 @@ test.write('test1.h', """\ INCLUDE 'foo.h' """) -test.run(arguments='.', stdout=test.wrap_stdout("""\ -%s myfc.py test1.o test1.f +expect = test.wrap_stdout("""\ +%(_python_)s myfc.py test1.o test1.f Install file: "test1.h" as "test1_h" -""" % (python,))) +""" % locals()) + +test.run(arguments='.', stdout=expect) test.must_match('test1.o', """\ test1.f 1 diff --git a/test/Fortran/SHF77.py b/test/Fortran/SHF77.py index 233921b..c9569c9 100644 --- a/test/Fortran/SHF77.py +++ b/test/Fortran/SHF77.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF77 = r'%s myfortran.py g77', - SHFORTRAN = r'%s myfortran.py fortran') +env = Environment(SHF77 = r'%(_python_)s myfortran.py g77', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF77 = r'%s myfortran.py g77') +env2 = Environment(SHF77 = r'%(_python_)s myfortran.py g77') env2.SharedObject(target = 'test21', source = 'test21.f') env2.SharedObject(target = 'test22', source = 'test22.F') env2.SharedObject(target = 'test23', source = 'test23.for') @@ -79,7 +79,7 @@ env2.SharedObject(target = 'test25', source = 'test25.ftn') env2.SharedObject(target = 'test26', source = 'test26.FTN') env2.SharedObject(target = 'test27', source = 'test27.fpp') env2.SharedObject(target = 'test28', source = 'test28.FPP') -""" % (python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -148,10 +148,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shf77 = foo.Dictionary('SHF77') -bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77) +bar = foo.Copy(SHF77 = r'%(_python_)s wrapper.py ' + shf77) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF77COM.py b/test/Fortran/SHF77COM.py index fa02487..75192df 100644 --- a/test/Fortran/SHF77COM.py +++ b/test/Fortran/SHF77COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - SHF77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES', - SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHF77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + SHF77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES', + SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,8 +68,8 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF77COM = r'%s myfortran.py f77 $TARGET $SOURCES', - SHF77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES') +env2 = Environment(SHF77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES', + SHF77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES') env2.SharedObject(target = 'test21', source = 'test21.f') env2.SharedObject(target = 'test22', source = 'test22.F') env2.SharedObject(target = 'test23', source = 'test23.for') @@ -80,7 +80,7 @@ env2.SharedObject(target = 'test27', source = 'test27.fpp') env2.SharedObject(target = 'test28', source = 'test28.FPP') env2.SharedObject(target = 'test29', source = 'test29.f77') env2.SharedObject(target = 'test30', source = 'test30.F77') -""" % (python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHF77COMSTR.py b/test/Fortran/SHF77COMSTR.py index fdb81c1..9085570 100644 --- a/test/Fortran/SHF77COMSTR.py +++ b/test/Fortran/SHF77COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHF77COM = r'%(python)s myfc.py f77 $TARGET $SOURCES', +env = Environment(SHF77COM = r'%(_python_)s myfc.py f77 $TARGET $SOURCES', SHF77COMSTR = 'Building f77 $TARGET from $SOURCES', - SHF77PPCOM = r'%(python)s myfc.py f77pp $TARGET $SOURCES', + SHF77PPCOM = r'%(_python_)s myfc.py f77pp $TARGET $SOURCES', SHF77PPCOMSTR = 'Building f77pp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f') diff --git a/test/Fortran/SHF77FLAGS.py b/test/Fortran/SHF77FLAGS.py index 85c1168..5354a57 100644 --- a/test/Fortran/SHF77FLAGS.py +++ b/test/Fortran/SHF77FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -63,7 +63,7 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF77 = r'%s myg77.py', +env = Environment(SHF77 = r'%(_python_)s myg77.py', SHF77FLAGS = '-x') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -75,7 +75,7 @@ env.SharedObject(target = 'test07', source = 'test07.fpp') env.SharedObject(target = 'test08', source = 'test08.FPP') env.SharedObject(target = 'test09', source = 'test09.f77') env.SharedObject(target = 'test10', source = 'test10.F77') -""" % (python,)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#g77\n") test.write('test02.F', "This is a .F file.\n#g77\n") @@ -117,12 +117,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shf77 = foo.Dictionary('SHF77') -bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77, SHF77FLAGS = '-Ix') +bar = foo.Copy(SHF77 = r'%(_python_)s wrapper.py ' + shf77, SHF77FLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF90.py b/test/Fortran/SHF90.py index 66bd68d..1696b4a 100644 --- a/test/Fortran/SHF90.py +++ b/test/Fortran/SHF90.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF90 = r'%s myfortran.py g90', - SHFORTRAN = r'%s myfortran.py fortran') +env = Environment(SHF90 = r'%(_python_)s myfortran.py g90', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -121,10 +121,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shf90 = foo.Dictionary('SHF90') -bar = foo.Copy(SHF90 = r'%s wrapper.py ' + shf90) +bar = foo.Copy(SHF90 = r'%(_python_)s wrapper.py ' + shf90) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF90COM.py b/test/Fortran/SHF90COM.py index ffc9878..13d9978 100644 --- a/test/Fortran/SHF90COM.py +++ b/test/Fortran/SHF90COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - SHF90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES', - SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHF90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + SHF90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES', + SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,11 +68,11 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF90COM = r'%s myfortran.py f90 $TARGET $SOURCES', - SHF90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES') +env2 = Environment(SHF90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES', + SHF90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES') env2.SharedObject(target = 'test21', source = 'test21.f90') env2.SharedObject(target = 'test22', source = 'test22.F90') -""" % (python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHF90COMSTR.py b/test/Fortran/SHF90COMSTR.py index f0e44d3..9633d45 100644 --- a/test/Fortran/SHF90COMSTR.py +++ b/test/Fortran/SHF90COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHF90COM = r'%(python)s myfc.py f90 $TARGET $SOURCES', +env = Environment(SHF90COM = r'%(_python_)s myfc.py f90 $TARGET $SOURCES', SHF90COMSTR = 'Building f90 $TARGET from $SOURCES', - SHF90PPCOM = r'%(python)s myfc.py f90pp $TARGET $SOURCES', + SHF90PPCOM = r'%(_python_)s myfc.py f90pp $TARGET $SOURCES', SHF90PPCOMSTR = 'Building f90pp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f90') diff --git a/test/Fortran/SHF90FLAGS.py b/test/Fortran/SHF90FLAGS.py index 3997cbb..62bb7d0 100644 --- a/test/Fortran/SHF90FLAGS.py +++ b/test/Fortran/SHF90FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -64,9 +64,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF90 = r'%s myfortran.py g90', +env = Environment(SHF90 = r'%(_python_)s myfortran.py g90', SHF90FLAGS = '-x', - SHFORTRAN = r'%s myfortran.py fortran', + SHFORTRAN = r'%(_python_)s myfortran.py fortran', SHFORTRANFLAGS = '-y') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -82,7 +82,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -132,12 +132,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shf90 = foo.Dictionary('SHF90') -bar = foo.Copy(SHF90 = r'%s wrapper.py ' + shf90, SHF90FLAGS = '-Ix') +bar = foo.Copy(SHF90 = r'%(_python_)s wrapper.py ' + shf90, SHF90FLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF95.py b/test/Fortran/SHF95.py index d2d92a9..85702df 100644 --- a/test/Fortran/SHF95.py +++ b/test/Fortran/SHF95.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF95 = r'%s myfortran.py g95', - SHFORTRAN = r'%s myfortran.py fortran') +env = Environment(SHF95 = r'%(_python_)s myfortran.py g95', + SHFORTRAN = r'%(_python_)s myfortran.py fortran') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -121,10 +121,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shf95 = foo.Dictionary('SHF95') -bar = foo.Copy(SHF95 = r'%s wrapper.py ' + shf95) +bar = foo.Copy(SHF95 = r'%(_python_)s wrapper.py ' + shf95) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHF95COM.py b/test/Fortran/SHF95COM.py index e28f863..b11933a 100644 --- a/test/Fortran/SHF95COM.py +++ b/test/Fortran/SHF95COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - SHF95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES', - SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHF95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + SHF95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES', + SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,11 +68,11 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -env2 = Environment(SHF95COM = r'%s myfortran.py f95 $TARGET $SOURCES', - SHF95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES') +env2 = Environment(SHF95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES', + SHF95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES') env2.SharedObject(target = 'test21', source = 'test21.f95') env2.SharedObject(target = 'test22', source = 'test22.F95') -""" % (python, python, python, python, python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHF95COMSTR.py b/test/Fortran/SHF95COMSTR.py index 461d7ff..eaa24ae 100644 --- a/test/Fortran/SHF95COMSTR.py +++ b/test/Fortran/SHF95COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHF95COM = r'%(python)s myfc.py f95 $TARGET $SOURCES', +env = Environment(SHF95COM = r'%(_python_)s myfc.py f95 $TARGET $SOURCES', SHF95COMSTR = 'Building f95 $TARGET from $SOURCES', - SHF95PPCOM = r'%(python)s myfc.py f95pp $TARGET $SOURCES', + SHF95PPCOM = r'%(_python_)s myfc.py f95pp $TARGET $SOURCES', SHF95PPCOMSTR = 'Building f95pp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f95') diff --git a/test/Fortran/SHF95FLAGS.py b/test/Fortran/SHF95FLAGS.py index 782a495..2288a4a 100644 --- a/test/Fortran/SHF95FLAGS.py +++ b/test/Fortran/SHF95FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -64,9 +64,9 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHF95 = r'%s myfortran.py g95', +env = Environment(SHF95 = r'%(_python_)s myfortran.py g95', SHF95FLAGS = '-x', - SHFORTRAN = r'%s myfortran.py fortran', + SHFORTRAN = r'%(_python_)s myfortran.py fortran', SHFORTRANFLAGS = '-y') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -82,7 +82,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -132,12 +132,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shf95 = foo.Dictionary('SHF95') -bar = foo.Copy(SHF95 = r'%s wrapper.py ' + shf95, SHF95FLAGS = '-Ix') +bar = foo.Copy(SHF95 = r'%(_python_)s wrapper.py ' + shf95, SHF95FLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHFORTRAN.py b/test/Fortran/SHFORTRAN.py index 17a58f5..586b54e 100644 --- a/test/Fortran/SHFORTRAN.py +++ b/test/Fortran/SHFORTRAN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHFORTRAN = r'%s myfortran.py') +env = Environment(SHFORTRAN = r'%(_python_)s myfortran.py') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -68,7 +68,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % python) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -119,10 +119,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = 'g2c') shfortran = foo.Dictionary('SHFORTRAN') -bar = foo.Copy(SHFORTRAN = r'%s wrapper.py ' + shfortran) +bar = foo.Copy(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran) foo.SharedObject(target = 'foo/foo', source = 'foo.f') bar.SharedObject(target = 'bar/bar', source = 'bar.f') -""" % python) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/SHFORTRANCOM.py b/test/Fortran/SHFORTRANCOM.py index f4d44dc..21942cf 100644 --- a/test/Fortran/SHFORTRANCOM.py +++ b/test/Fortran/SHFORTRANCOM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,8 +50,8 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES', - SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES') +env = Environment(SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') env.SharedObject(target = 'test03', source = 'test03.for') @@ -66,7 +66,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python, python)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortranpp\n") diff --git a/test/Fortran/SHFORTRANCOMSTR.py b/test/Fortran/SHFORTRANCOMSTR.py index 8ad3b14..69a1eba 100644 --- a/test/Fortran/SHFORTRANCOMSTR.py +++ b/test/Fortran/SHFORTRANCOMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: test.write('SConstruct', """ -env = Environment(SHFORTRANCOM = r'%(python)s myfc.py fortran $TARGET $SOURCES', +env = Environment(SHFORTRANCOM = r'%(_python_)s myfc.py fortran $TARGET $SOURCES', SHFORTRANCOMSTR = 'Building fortran $TARGET from $SOURCES', - SHFORTRANPPCOM = r'%(python)s myfc.py fortranpp $TARGET $SOURCES', + SHFORTRANPPCOM = r'%(_python_)s myfc.py fortranpp $TARGET $SOURCES', SHFORTRANPPCOMSTR = 'Building fortranpp $TARGET from $SOURCES', SHOBJSUFFIX='.shobj') env.SharedObject(source = 'test01.f') diff --git a/test/Fortran/SHFORTRANFLAGS.py b/test/Fortran/SHFORTRANFLAGS.py index e96ade9..d09a283 100644 --- a/test/Fortran/SHFORTRANFLAGS.py +++ b/test/Fortran/SHFORTRANFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -63,7 +63,7 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(SHFORTRAN = r'%s myfortran.py', +env = Environment(SHFORTRAN = r'%(_python_)s myfortran.py', SHFORTRANFLAGS = '-x') env.SharedObject(target = 'test01', source = 'test01.f') env.SharedObject(target = 'test02', source = 'test02.F') @@ -79,7 +79,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') env.SharedObject(target = 'test12', source = 'test12.F90') env.SharedObject(target = 'test13', source = 'test13.f95') env.SharedObject(target = 'test14', source = 'test14.F95') -""" % (python,)) +""" % locals()) test.write('test01.f', "This is a .f file.\n#fortran\n") test.write('test02.F', "This is a .F file.\n#fortran\n") @@ -129,13 +129,13 @@ os.system(string.join(sys.argv[1:], " ")) """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) test.write('SConstruct', """ -foo = Environment(LIBS = %s) +foo = Environment(LIBS = %(FTN_LIB)s) shfortran = foo.Dictionary('SHFORTRAN') -bar = foo.Copy(SHFORTRAN = r'%s wrapper.py ' + shfortran, +bar = foo.Copy(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran, SHFORTRANFLAGS = '-Ix') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') -""" % (FTN_LIB, python)) +""" % locals()) test.write('foo.f', r""" PROGRAM FOO diff --git a/test/Fortran/USE-MODULE.py b/test/Fortran/USE-MODULE.py index 541c457..23d0a89 100644 --- a/test/Fortran/USE-MODULE.py +++ b/test/Fortran/USE-MODULE.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(FORTRANCOM = r'%(python)s myfortran.py $SOURCE $TARGET') +env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $SOURCE $TARGET') env.Object(target = 'test1.obj', source = 'test1.f') """ % locals()) diff --git a/test/Fortran/module-subdir.py b/test/Fortran/module-subdir.py new file mode 100644 index 0000000..88d0888 --- /dev/null +++ b/test/Fortran/module-subdir.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Validate that $FORTRANMODDIR values get expanded correctly on Fortran +command lines relative to the appropriate subdirectory. +""" + +import os.path + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.subdir('subdir', + ['subdir', 'src'], + ['subdir', 'build']) + +test.write('myfortran.py', r""" +import getopt +import os +import sys +comment = '#' + sys.argv[1] +length = len(comment) +opts, args = getopt.getopt(sys.argv[2:], 'cM:o:') +for opt, arg in opts: + if opt == '-o': out = arg + elif opt == '-M': modsubdir = arg +import os +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:7] == 'module ': + module = modsubdir + os.sep + l[7:-1] + '.mod' + open(module, 'wb').write('myfortran.py wrote %s\n' % module) + if l[:length] != comment: + outfile.write(l) +sys.exit(0) +""") + +test.write('myar.py', """\ +import sys +t = open(sys.argv[1], 'wb') +for s in sys.argv[2:]: + t.write(open(s, 'rb').read()) +t.close +sys.exit(0) +""") + +test.write('SConstruct', """\ +env = Environment(FORTRANMODDIRPREFIX = '-M', + FORTRANMODDIR = 'modules', + F90 = r'%(_python_)s myfortran.py f90', + FORTRAN = r'%(_python_)s myfortran.py fortran', + AR = 'myar.py', + ARCOM = r'%(_python_)s $AR $TARGET $SOURCES', + RANLIBCOM = '') +Export('env') +objs = SConscript('subdir/SConscript') +env.Library('bidule', objs) +""" % locals()) + +test.write(['subdir', 'SConscript'], """\ +Import('env') + +env['FORTRANMODDIR'] = 'build' +sources = ['src/modfile.f90'] +objs = env.Object(sources) +Return("objs") +""") + +test.write(['subdir', 'src', 'modfile.f90'], """\ +#f90 comment +module somemodule + +integer :: nothing + +end module +""") + + +test.run(arguments = '.') + +somemodule = os.path.join('subdir', 'build', 'somemodule.mod') + +expect = "myfortran.py wrote %s\n" % somemodule + +test.must_match(['subdir', 'build', 'somemodule.mod'], expect) + +test.pass_test() diff --git a/test/Ghostscript/GS.py b/test/Ghostscript/GS.py index a836cf6..6089d60 100644 --- a/test/Ghostscript/GS.py +++ b/test/Ghostscript/GS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,11 +48,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(GS = r'%s mygs.py', +env = Environment(GS = r'%(_python_)s mygs.py', GSCOM = r'$GS $TARGET $SOURCE', tools=['gs']) env.PDF(target = 'test1.pdf', source = 'test1.ps') -""" % (python)) +""" % locals()) test.write('test1.ps', r"""This is a .ps test. #ps @@ -88,10 +88,10 @@ import os foo = Environment(ENV = { 'PATH' : os.environ['PATH'] }) gs = foo.Dictionary('GS') bar = Environment(ENV = { 'PATH' : os.environ['PATH'] }, - GS = r'%s wrapper.py ' + gs) + GS = r'%(_python_)s wrapper.py ' + gs) foo.PDF(target = 'foo.pdf', source = 'foo.ps') bar.PDF(target = 'bar.pdf', source = 'bar.ps') -""" % python) +""" % locals()) input = """\ %!PS-Adobe diff --git a/test/Ghostscript/GSCOM.py b/test/Ghostscript/GSCOM.py index acd46f2..a41c800 100644 --- a/test/Ghostscript/GSCOM.py +++ b/test/Ghostscript/GSCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $GSCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'gs'], - GSCOM = r'%s mygs.py $TARGET $SOURCES') + GSCOM = r'%(_python_)s mygs.py $TARGET $SOURCES') env.PDF(target = 'aaa', source = 'aaa.ps') -""" % python) +""" % locals()) test.write('aaa.ps', "aaa.ps\n/*gs*/\n") diff --git a/test/Ghostscript/GSCOMSTR.py b/test/Ghostscript/GSCOMSTR.py index 9f7aee8..923aee3 100644 --- a/test/Ghostscript/GSCOMSTR.py +++ b/test/Ghostscript/GSCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when Ghostscript is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'gs'], - GSCOM = r'%s mygs.py $TARGET $SOURCES', + GSCOM = r'%(_python_)s mygs.py $TARGET $SOURCES', GSCOMSTR = 'GSing $TARGET from $SOURCE') env.PDF(target = 'aaa', source = 'aaa.ps') -""" % python) +""" % locals()) test.write('aaa.ps', "aaa.ps\n/*gs*/\n") diff --git a/test/Ghostscript/GSFLAGS.py b/test/Ghostscript/GSFLAGS.py index 14ce769..7acb89e 100644 --- a/test/Ghostscript/GSFLAGS.py +++ b/test/Ghostscript/GSFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,10 +57,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(GS = r'%s mygs.py', GSFLAGS = '-x', +env = Environment(GS = r'%(_python_)s mygs.py', GSFLAGS = '-x', tools = ['gs']) env.PDF(target = 'test1.pdf', source = 'test1.ps') -""" % (python)) +""" % locals()) test.write('test1.ps', """\ This is a .ps test. diff --git a/test/IDL/MIDLCOM.py b/test/IDL/MIDLCOM.py index d3f6420..79857d0 100644 --- a/test/IDL/MIDLCOM.py +++ b/test/IDL/MIDLCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $MIDLCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'midl'], - MIDLCOM = r'%s mymidl.py $TARGET $SOURCES') + MIDLCOM = r'%(_python_)s mymidl.py $TARGET $SOURCES') env.TypeLibrary(target = 'aaa', source = 'aaa.idl') -""" % python) +""" % locals()) test.write('aaa.idl', "aaa.idl\n/*midl*/\n") diff --git a/test/IDL/MIDLCOMSTR.py b/test/IDL/MIDLCOMSTR.py index 89a6e25..8c3a15a 100644 --- a/test/IDL/MIDLCOMSTR.py +++ b/test/IDL/MIDLCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when midl is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'midl'], - MIDLCOM = r'%s mymidl.py $TARGET $SOURCES', + MIDLCOM = r'%(_python_)s mymidl.py $TARGET $SOURCES', MIDLCOMSTR = 'MIDLing $TARGET from $SOURCE') env.TypeLibrary(target = 'aaa', source = 'aaa.idl') -""" % python) +""" % locals()) test.write('aaa.idl', "aaa.idl\n/*midl*/\n") diff --git a/test/Ignore.py b/test/Ignore.py index 1652f60..15cf4f3 100644 --- a/test/Ignore.py +++ b/test/Ignore.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -43,19 +43,19 @@ for arg in sys.argv[2:]: file.close() """) +SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out') +SUBDIR_f3b_in = os.path.join('$SUBDIR', 'f3b.in') + test.write('SConstruct', """\ -Foo = Builder(action = r"%s build.py $TARGET $SOURCES") -Bar = Builder(action = r"%s build.py $TARGET $SOURCES") +Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') +Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir') env.Foo(target = 'f1.out', source = ['f1a.in', 'f1b.in']) Ignore(target = 'f1.out', dependency = 'f1b.in') SConscript('subdir/SConscript', "env") env.Foo(target = 'subdir/f3.out', source = ['subdir/f3a.in', 'subdir/f3b.in']) -env.Ignore(target = r'%s', dependency = r'%s') -""" % (python, - python, - os.path.join('$SUBDIR', 'f3.out'), - os.path.join('$SUBDIR', 'f3b.in'))) +env.Ignore(target = r'%(SUBDIR_f3_out)s', dependency = r'%(SUBDIR_f3b_in)s') +""" % locals()) test.write(['subdir', 'SConscript'], """ Import("env") diff --git a/test/Install/Install.py b/test/Install/Install.py index 7018466..e24641b 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -46,6 +46,8 @@ f5_txt = test.workpath('outside', 'f5.txt') f6_txt = test.workpath('outside', 'f6.txt') f6_sep = string.replace(f6_txt, os.sep, '/') +_SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out') + test.write(['work', 'SConstruct'], """\ def cat(env, source, target): target = str(target[0]) @@ -74,15 +76,13 @@ env3.Install(dir='export', source=t) env4 = env1.Copy(EXPORT='export', SUBDIR='sub') t = env4.Cat(target='sub/f4.out', source='sub/f4.in') -env4.Install(dir='$EXPORT', source=r'%s') - -env1.Install('.', r'%s') -env1.Install('export', r'%s') -env1.Install('.', r'%s') -env1.Install('export', r'%s') -""" % (os.path.join('$SUBDIR', 'f4.out'), - f5_txt, f5_txt, - f6_sep, f6_sep)) +env4.Install(dir='$EXPORT', source=r'%(_SUBDIR_f4_out)s') + +env1.Install('.', r'%(f5_txt)s') +env1.Install('export', r'%(f5_txt)s') +env1.Install('.', r'%(f6_sep)s') +env1.Install('export', r'%(f6_sep)s') +""" % locals()) test.write(['work', 'f1.in'], "f1.in\n") test.write(['work', 'f2.in'], "f2.in\n") diff --git a/test/Install/InstallAs.py b/test/Install/InstallAs.py index 4fe4bd0..7a6c9f6 100644 --- a/test/Install/InstallAs.py +++ b/test/Install/InstallAs.py @@ -41,16 +41,16 @@ install_file1_out = test.workpath('install', 'file1.out') install_file2_out = test.workpath('install', 'file2.out') install_file3_out = test.workpath('install', 'file3.out') +_INSTALLDIR_file2_out = os.path.join('$INSTALLDIR', 'file2.out') +_SUBDIR_file3_in = os.path.join('$SUBDIR', 'file3.in') + # test.write('SConstruct', r""" -env = Environment(INSTALLDIR=r'%s', SUBDIR='subdir') -InstallAs(r'%s', 'file1.in') -env.InstallAs([r'%s', r'%s'], ['file2.in', r'%s']) -""" % (install, - install_file1_out, - os.path.join('$INSTALLDIR', 'file2.out'), - install_file3_out, - os.path.join('$SUBDIR', 'file3.in'))) +env = Environment(INSTALLDIR=r'%(install)s', SUBDIR='subdir') +InstallAs(r'%(install_file1_out)s', 'file1.in') +env.InstallAs([r'%(_INSTALLDIR_file2_out)s', r'%(install_file3_out)s'], + ['file2.in', r'%(_SUBDIR_file3_in)s']) +""" % locals()) test.write('file1.in', "file1.in\n") test.write('file2.in', "file2.in\n") diff --git a/test/Install/directories.py b/test/Install/directories.py new file mode 100644 index 0000000..300ed4d --- /dev/null +++ b/test/Install/directories.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test using Install() on directories. +""" + +import os.path +import string +import sys +import time +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('outside', + 'work', + ['work', 'dir1'], + ['work', 'dir1', 'sub'], + ['work', 'dir2'], + ['work', 'dir2', 'sub'], + ['work', 'dir3'], + ['work', 'dir3', 'sub'], + ['work', 'dir4'], + ['work', 'dir4', 'sub']) + +test.write(['work', 'SConstruct'], """\ +Install('../outside', 'dir1') +InstallAs('../outside/d2', 'dir2') + +env = Environment() +env.Install('../outside', 'dir3') +env.InstallAs('../outside/d4', 'dir4') +""") + +test.write(['work', 'f1'], "work/f1\n") +test.write(['work', 'dir1', 'f2'], "work/dir1/f2\n") +test.write(['work', 'dir1', 'sub', 'f3'], "work/dir1/sub/f3\n") +test.write(['work', 'dir2', 'f4'], "work/dir2/f4\n") +test.write(['work', 'dir2', 'sub', 'f5'], "work/dir2/sub/f5\n") +test.write(['work', 'dir3', 'f6'], "work/dir3/f6\n") +test.write(['work', 'dir3', 'sub', 'f7'], "work/dir3/sub/f7\n") +test.write(['work', 'dir4', 'f8'], "work/dir4/f8\n") +test.write(['work', 'dir4', 'sub', 'f9'], "work/dir4/sub/f9\n") + + +arguments = [ + test.workpath('outside', 'dir1'), + test.workpath('outside', 'd2'), + test.workpath('outside', 'dir3'), + test.workpath('outside', 'd4'), +] + +expect = test.wrap_stdout(""" +Install directory: "dir1" as "%s" +Install directory: "dir2" as "%s" +Install directory: "dir3" as "%s" +Install directory: "dir4" as "%s" +""" % tuple(arguments)) + +test.run(chdir = 'work', arguments = arguments) + +test.must_match(test.workpath('outside', 'dir1', 'f2'), "work/dir1/f2\n") +test.must_match(test.workpath('outside', 'dir1', 'sub', 'f3'), "work/dir1/sub/f3\n") +test.must_match(test.workpath('outside', 'd2', 'f4'), "work/dir2/f4\n") +test.must_match(test.workpath('outside', 'd2', 'sub', 'f5'), "work/dir2/sub/f5\n") +test.must_match(test.workpath('outside', 'dir3', 'f6'), "work/dir3/f6\n") +test.must_match(test.workpath('outside', 'dir3', 'sub', 'f7'), "work/dir3/sub/f7\n") +test.must_match(test.workpath('outside', 'd4', 'f8'), "work/dir4/f8\n") +test.must_match(test.workpath('outside', 'd4', 'sub', 'f9'), "work/dir4/sub/f9\n") + +test.pass_test() diff --git a/test/Java/JAR.py b/test/Java/JAR.py index 1344fb1..5342a48 100644 --- a/test/Java/JAR.py +++ b/test/Java/JAR.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -56,9 +56,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['jar'], - JAR = r'%s myjar.py') + JAR = r'%(_python_)s myjar.py') env.Jar(target = 'test1.jar', source = 'test1.class') -""" % (python)) +""" % locals()) test.write('test1.class', """\ test1.class @@ -74,9 +74,9 @@ if os.path.normcase('.class') == os.path.normcase('.CLASS'): test.write('SConstruct', """ env = Environment(tools = ['jar'], - JAR = r'%s myjar.py') + JAR = r'%(_python_)s myjar.py') env.Jar(target = 'test2.jar', source = 'test2.CLASS') -""" % (python)) +""" % locals()) test.write('test2.CLASS', """\ test2.CLASS @@ -100,13 +100,13 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['jar'], - JAR = r'%s myjar2.py', + JAR = r'%(_python_)s myjar2.py', JARFLAGS='cvf') env.Jar(target = 'classes.jar', source = [ 'testdir/bar.class', 'foo.mf' ], TESTDIR='testdir', JARCHDIR='$TESTDIR') -""" % (python)) +""" % locals()) test.subdir('testdir') test.write([ 'testdir', 'bar.class' ], 'foo') @@ -150,7 +150,7 @@ foo = Environment(tools = ['javac', 'jar'], JAVAC = r'%(where_javac)s', JAR = r'%(where_jar)s') jar = foo.Dictionary('JAR') -bar = foo.Copy(JAR = r'%(python)s wrapper.py ' + jar) +bar = foo.Copy(JAR = r'%(_python_)s wrapper.py ' + jar) foo.Java(target = 'classes', source = 'com/sub/foo') bar.Java(target = 'classes', source = 'com/sub/bar') foo.Jar(target = 'foo', source = 'classes/com/sub/foo') diff --git a/test/Java/JARCOM.py b/test/Java/JARCOM.py index 0d7ebba..f03cd9f 100644 --- a/test/Java/JARCOM.py +++ b/test/Java/JARCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JARCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,7 +48,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'jar'], - JARCOM = r'%(python)s myjar.py $TARGET $SOURCES') + JARCOM = r'%(_python_)s myjar.py $TARGET $SOURCES') env.Jar(target = 'test1', source = ['file1.in', 'file2.in', 'file3.in']) """ % locals()) diff --git a/test/Java/JARCOMSTR.py b/test/Java/JARCOMSTR.py index aa8a6ad..35404ce 100644 --- a/test/Java/JARCOMSTR.py +++ b/test/Java/JARCOMSTR.py @@ -31,7 +31,7 @@ the jar output. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'jar'], - JARCOM = r'%(python)s myjar.py $TARGET $SOURCES', + JARCOM = r'%(_python_)s myjar.py $TARGET $SOURCES', JARCOMSTR = "Jar'ing up $TARGET from $SOURCES") env.Jar(target = 'test1', source = ['file1.in', 'file2.in', 'file3.in']) """ % locals()) diff --git a/test/Java/JAVAC.py b/test/Java/JAVAC.py index 93f0e7b..b5fb3f8 100644 --- a/test/Java/JAVAC.py +++ b/test/Java/JAVAC.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['javac'], - JAVAC = r'%s myjavac.py') + JAVAC = r'%(_python_)s myjavac.py') env.Java(target = '.', source = '.') -""" % (python)) +""" % locals()) test.write('test1.java', """\ test1.java @@ -77,9 +77,9 @@ if os.path.normcase('.java') == os.path.normcase('.JAVA'): test.write('SConstruct', """\ env = Environment(tools = ['javac'], - JAVAC = r'%s myjavac.py') + JAVAC = r'%(_python_)s myjavac.py') env.Java(target = '.', source = '.') -""" % python) +""" % locals()) test.write('test2.JAVA', """\ test2.JAVA @@ -114,13 +114,13 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(tools = ['javac'], - JAVAC = r'%s') + JAVAC = r'%(where_javac)s') javac = foo.Dictionary('JAVAC') -bar = foo.Copy(JAVAC = r'%s wrapper.py ' + javac) +bar = foo.Copy(JAVAC = r'%(_python_)s wrapper.py ' + javac) foo.Java(target = 'class1', source = 'com/sub/foo') bar.Java(target = 'class2', source = 'com/sub/bar') foo.Java(target = 'class3', source = ['src1', 'src2']) -""" % (where_javac, python)) +""" % locals()) test.subdir('com', ['com', 'sub'], diff --git a/test/Java/JAVACCOM.py b/test/Java/JAVACCOM.py index 171649c..7086a2a 100644 --- a/test/Java/JAVACCOM.py +++ b/test/Java/JAVACCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JAVACCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javac'], - JAVACCOM = r'%(python)s myjavac.py $TARGET $SOURCES') + JAVACCOM = r'%(_python_)s myjavac.py $TARGET $SOURCES') env.Java(target = 'classes', source = 'src') """ % locals()) diff --git a/test/Java/JAVACCOMSTR.py b/test/Java/JAVACCOMSTR.py index 7f59e90..44b1449 100644 --- a/test/Java/JAVACCOMSTR.py +++ b/test/Java/JAVACCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javac'], - JAVACCOM = r'%(python)s myjavac.py $TARGET $SOURCES', + JAVACCOM = r'%(_python_)s myjavac.py $TARGET $SOURCES', JAVACCOMSTR = "Compiling class(es) $TARGET from $SOURCES") env.Java(target = 'classes', source = 'src') """ % locals()) diff --git a/test/Java/JAVAH.py b/test/Java/JAVAH.py index eb70ac8..9901764 100644 --- a/test/Java/JAVAH.py +++ b/test/Java/JAVAH.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,9 +61,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['javah'], - JAVAH = r'%s myjavah.py') + JAVAH = r'%(_python_)s myjavah.py') env.JavaH(target = File('test1.h'), source = 'test1.java') -""" % (python)) +""" % locals()) test.write('test1.java', """\ test1.java @@ -79,9 +79,9 @@ if os.path.normcase('.java') == os.path.normcase('.JAVA'): test.write('SConstruct', """\ env = Environment(tools = ['javah'], - JAVAH = r'%s myjavah.py') + JAVAH = r'%(_python_)s myjavah.py') env.JavaH(target = File('test2.h'), source = 'test2.JAVA') -""" % python) +""" % locals()) test.write('test2.JAVA', """\ test2.JAVA @@ -126,7 +126,7 @@ foo = Environment(tools = ['javac', 'javah'], JAVAC = r'%(where_javac)s', JAVAH = r'%(where_javah)s') javah = foo.Dictionary('JAVAH') -bar = foo.Copy(JAVAH = r'%(python)s wrapper.py ' + javah) +bar = foo.Copy(JAVAH = r'%(_python_)s wrapper.py ' + javah) foo.Java(target = 'class1', source = 'com/sub/foo') bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar') foo_classes = foo.Java(target = 'class3', source = 'src') diff --git a/test/Java/JAVAHCOM.py b/test/Java/JAVAHCOM.py index 1cc4208..73067c6 100644 --- a/test/Java/JAVAHCOM.py +++ b/test/Java/JAVAHCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JAVAHCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,7 +48,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javah'], - JAVAHCOM = r'%(python)s myjavah.py $TARGET $SOURCES') + JAVAHCOM = r'%(_python_)s myjavah.py $TARGET $SOURCES') env.JavaH(target = 'out', source = 'file1.class') env.JavaH(target = 'out', source = 'file2.class') env.JavaH(target = 'out', source = 'file3.class') diff --git a/test/Java/JAVAHCOMSTR.py b/test/Java/JAVAHCOMSTR.py index 2a14e1c..8ee5767 100644 --- a/test/Java/JAVAHCOMSTR.py +++ b/test/Java/JAVAHCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,7 +59,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'javah'], - JAVAHCOM = r'%(python)s myjavah.py $TARGET $SOURCES', + JAVAHCOM = r'%(_python_)s myjavah.py $TARGET $SOURCES', JAVAHCOMSTR = 'Building javah $TARGET from $SOURCES') env.JavaH(target = 'out', source = 'file1.class') env.JavaH(target = 'out', source = 'file2.class') diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py index 7ef1359..bb098e7 100644 --- a/test/Java/RMIC.py +++ b/test/Java/RMIC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,9 +60,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['rmic'], - RMIC = r'%s myrmic.py') + RMIC = r'%(_python_)s myrmic.py') env.RMIC(target = 'outdir', source = 'test1.java') -""" % (python)) +""" % locals()) test.write('test1.java', """\ test1.java @@ -78,9 +78,9 @@ if os.path.normcase('.java') == os.path.normcase('.JAVA'): test.write('SConstruct', """\ env = Environment(tools = ['rmic'], - RMIC = r'%s myrmic.py') + RMIC = r'%(_python_)s myrmic.py') env.RMIC(target = 'outdir', source = 'test2.JAVA') -""" % python) +""" % locals()) test.write('test2.JAVA', """\ test2.JAVA @@ -128,7 +128,7 @@ foo.RMIC(target = 'outdir1', JAVACLASSDIR = 'class1') rmic = foo.Dictionary('RMIC') -bar = foo.Copy(RMIC = r'%(python)s wrapper.py ' + rmic) +bar = foo.Copy(RMIC = r'%(_python_)s wrapper.py ' + rmic) bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar') # XXX This is kind of a Python brute-force way to do what Ant # does with its "excludes" attribute. We should probably find diff --git a/test/Java/RMICCOM.py b/test/Java/RMICCOM.py index 109c22e..ed5e0d6 100644 --- a/test/Java/RMICCOM.py +++ b/test/Java/RMICCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,7 +58,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'rmic'], - RMICCOM = r'%(python)s myrmic.py $TARGET $SOURCES') + RMICCOM = r'%(_python_)s myrmic.py $TARGET $SOURCES') env.RMIC(target = 'out', source = 'file1.class') env.RMIC(target = 'out', source = 'file2.class') env.RMIC(target = 'out', source = 'file3.class') diff --git a/test/Java/RMICCOMSTR.py b/test/Java/RMICCOMSTR.py index 1bcf300..5a451eb 100644 --- a/test/Java/RMICCOMSTR.py +++ b/test/Java/RMICCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,7 +59,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['default', 'rmic'], - RMICCOM = r'%(python)s myrmic.py $TARGET $SOURCES', + RMICCOM = r'%(_python_)s myrmic.py $TARGET $SOURCES', RMICCOMSTR = 'Building rmic $TARGET from $SOURCES') env.RMIC(target = 'out', source = 'file1.class') env.RMIC(target = 'out', source = 'file2.class') diff --git a/test/LEX/LEX.py b/test/LEX/LEX.py index 5515a3e..3fd4db3 100644 --- a/test/LEX/LEX.py +++ b/test/LEX/LEX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', tools=['default', 'lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', tools=['default', 'lex']) env.Program(target = 'aaa', source = 'aaa.l') env.Program(target = 'bbb', source = 'bbb.lex') -""" % python) +""" % locals()) test.write('aaa.l', r""" int @@ -97,10 +97,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() lex = foo.Dictionary('LEX') -bar = Environment(LEX = r'%s wrapper.py ' + lex) +bar = Environment(LEX = r'%(_python_)s wrapper.py ' + lex) foo.Program(target = 'foo', source = 'foo.l') bar.Program(target = 'bar', source = 'bar.l') -""" % python) +""" % locals()) lex = r""" %%%% diff --git a/test/LEX/LEXCOM.py b/test/LEX/LEXCOM.py index ea4626d..7ce8a15 100644 --- a/test/LEX/LEXCOM.py +++ b/test/LEX/LEXCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $LEXCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'lex'], - LEXCOM = r'%s mylex.py $TARGET $SOURCES') + LEXCOM = r'%(_python_)s mylex.py $TARGET $SOURCES') env.CFile(target = 'aaa', source = 'aaa.l') env.CFile(target = 'bbb', source = 'bbb.lex') -""" % python) +""" % locals()) test.write('aaa.l', "aaa.l\n/*lex*/\n") test.write('bbb.lex', "bbb.lex\n/*lex*/\n") diff --git a/test/LEX/LEXCOMSTR.py b/test/LEX/LEXCOMSTR.py index 5b01df7..a06c20c 100644 --- a/test/LEX/LEXCOMSTR.py +++ b/test/LEX/LEXCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when lex is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'lex'], - LEXCOM = r'%s mylex.py $TARGET $SOURCES', + LEXCOM = r'%(_python_)s mylex.py $TARGET $SOURCES', LEXCOMSTR = 'Lexing $TARGET from $SOURCE') env.CFile(target = 'aaa', source = 'aaa.l') env.CFile(target = 'bbb', source = 'bbb.lex') -""" % python) +""" % locals()) test.write('aaa.l', "aaa.l\n/*lex*/\n") test.write('bbb.lex', "bbb.lex\n/*lex*/\n") diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py index 87a869f..5923934 100644 --- a/test/LEX/LEXFLAGS.py +++ b/test/LEX/LEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,9 +52,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%s mylex.py', LEXFLAGS = '-x', tools=['default', 'lex']) +env = Environment(LEX = r'%(_python_)s mylex.py', + LEXFLAGS = '-x', + tools=['default', 'lex']) env.Program(target = 'aaa', source = 'aaa.l') -""" % python) +""" % locals()) test.write('aaa.l', r""" int diff --git a/test/LIBPATH.py b/test/LIBPATH.py index c54d2ac..1ea7ed8 100644 --- a/test/LIBPATH.py +++ b/test/LIBPATH.py @@ -57,6 +57,8 @@ env2.Library(target = 'foo2', source = f1) """) test.write('f1.c', r""" +#include + void f1(void) { @@ -75,6 +77,8 @@ test() """) test.write('prog.c', r""" +#include + 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 + 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 + void f1(void) { diff --git a/test/LIBPREFIXES.py b/test/LIBPREFIXES.py index 753b9b3..1e5d6c2 100644 --- a/test/LIBPREFIXES.py +++ b/test/LIBPREFIXES.py @@ -43,6 +43,8 @@ env.Program(target = 'prog', source = ['prog.c', lib]) """) test.write('foo.c', r""" +#include + void foo(void) { @@ -51,6 +53,8 @@ foo(void) """) test.write('prog.c', r""" +#include + void foo(void); int main(int argc, char *argv[]) diff --git a/test/LIBS.py b/test/LIBS.py index 3ff26e0..708ce63 100644 --- a/test/LIBS.py +++ b/test/LIBS.py @@ -93,6 +93,7 @@ test.write('foo4.c', foo_contents) test.write('foo5.c', foo_contents) test.write('sl.c', """\ +#include void sl(void) { @@ -101,6 +102,7 @@ sl(void) """) test.write('slprog.c', """\ +#include 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 +#include #include "message2.h" int main (void) diff --git a/test/LIBSUFFIXES.py b/test/LIBSUFFIXES.py index c776ce0..29cbb18 100644 --- a/test/LIBSUFFIXES.py +++ b/test/LIBSUFFIXES.py @@ -43,6 +43,8 @@ env.Program(target = 'prog', source = ['prog.c', lib]) """) test.write('foo.c', r""" +#include + void foo(void) { @@ -51,6 +53,8 @@ foo(void) """) test.write('prog.c', r""" +#include + void foo(void); int main(int argc, char *argv[]) diff --git a/test/LINK/LINK.py b/test/LINK/LINK.py index 2d89352..ede03f5 100644 --- a/test/LINK/LINK.py +++ b/test/LINK/LINK.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,12 +45,14 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() link = foo.subst("$LINK") -bar = Environment(LINK = r'%s wrapper.py ' + link) +bar = Environment(LINK = r'%(_python_)s wrapper.py ' + link) foo.Program(target = 'foo', source = 'foo.c') bar.Program(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -61,6 +63,8 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/LINK/LINKCOM.py b/test/LINK/LINKCOM.py index c94d5e3..d914049 100644 --- a/test/LINK/LINKCOM.py +++ b/test/LINK/LINKCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(LINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', OBJSUFFIX = '.obj', PROGSUFFIX = '.exe') env.Program(target = 'test1', source = ['test1.obj', 'test2.obj']) diff --git a/test/LINK/LINKCOMSTR.py b/test/LINK/LINKCOMSTR.py index 70b5c0c..1a7efbe 100644 --- a/test/LINK/LINKCOMSTR.py +++ b/test/LINK/LINKCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(LINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', LINKCOMSTR = 'Linking $TARGET from $SOURCES', OBJSUFFIX = '.obj', PROGSUFFIX = '.exe') diff --git a/test/LINK/LINKFLAGS.py b/test/LINK/LINKFLAGS.py index ca1cd1a..d80960d 100644 --- a/test/LINK/LINKFLAGS.py +++ b/test/LINK/LINKFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,13 +45,15 @@ os.system(string.join(args, " ")) test.write('SConstruct', """ foo = Environment() -bar = Environment(LINK = foo.subst(r'%s wrapper.py $LINK'), +bar = Environment(LINK = foo.subst(r'%(_python_)s wrapper.py $LINK'), LINKFLAGS = foo.subst('$LINKFLAGS fake_link_flag')) foo.Program(target = 'foo', source = 'foo.c') bar.Program(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/LINK/SHLINK.py b/test/LINK/SHLINK.py index 8b9097d..296845c 100644 --- a/test/LINK/SHLINK.py +++ b/test/LINK/SHLINK.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ dll_ = TestSCons.dll_ _shlib = TestSCons._dll @@ -46,10 +46,10 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() shlink = foo.Dictionary('SHLINK') -bar = Environment(SHLINK = r'%s wrapper.py ' + shlink) +bar = Environment(SHLINK = r'%(_python_)s wrapper.py ' + shlink) foo.SharedLibrary(target = 'foo', source = 'foo.c') bar.SharedLibrary(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" #include diff --git a/test/LINK/SHLINKCOM.py b/test/LINK/SHLINKCOM.py index d97c4ed..2d2f718 100644 --- a/test/LINK/SHLINKCOM.py +++ b/test/LINK/SHLINKCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,8 +60,8 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCES', - SHLINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCES', + SHLINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', SHOBJSUFFIX = '.obj', SHLIBPREFIX = '', SHLIBSUFFIX = '.dll') diff --git a/test/LINK/SHLINKCOMSTR.py b/test/LINK/SHLINKCOMSTR.py index 1ea29b2..cf31813 100644 --- a/test/LINK/SHLINKCOMSTR.py +++ b/test/LINK/SHLINKCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,8 +61,8 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCES', - SHLINKCOM = r'%(python)s mylink.py $TARGET $SOURCES', +env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCES', + SHLINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES', SHLINKCOMSTR = 'Linking shared $TARGET from $SOURCES', SHOBJSUFFIX = '.obj', SHLIBPREFIX = '', @@ -85,8 +85,8 @@ test2.c """) test.run(stdout = test.wrap_stdout("""\ -%(python)s mycc.py test1.obj test1.c -%(python)s mycc.py test2.obj test2.c +%(_python_)s mycc.py test1.obj test1.c +%(_python_)s mycc.py test2.obj test2.c Linking shared test3.dll from test1.obj test2.obj """ % locals())) diff --git a/test/LINK/SHLINKFLAGS.py b/test/LINK/SHLINKFLAGS.py index 709ebc6..51a8f7c 100644 --- a/test/LINK/SHLINKFLAGS.py +++ b/test/LINK/SHLINKFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ lib_ = TestSCons.dll_ _shlib = TestSCons._dll @@ -46,11 +46,11 @@ os.system(string.join(args, " ")) test.write('SConstruct', """ foo = Environment() -bar = Environment(SHLINK = foo.subst(r'%s wrapper.py $SHLINK'), +bar = Environment(SHLINK = foo.subst(r'%(_python_)s wrapper.py $SHLINK'), SHLINKFLAGS = foo.subst('$SHLINKFLAGS fake_shlink_flag')) foo.SharedLibrary(target = 'foo', source = 'foo.c') bar.SharedLibrary(target = 'bar', source = 'bar.c') -""" % python) +""" % locals()) test.write('foo.c', r""" #include diff --git a/test/Library.py b/test/Library.py index e4626ab..3a04b9c 100644 --- a/test/Library.py +++ b/test/Library.py @@ -38,6 +38,7 @@ env.Program(target = 'prog', source = [ 'prog.cpp', libtgt ]) """) test.write('f1.c', r""" +#include void f1(void) { @@ -46,6 +47,7 @@ f1(void) """) test.write('f2a.c', r""" +#include void f2a(void) { @@ -54,6 +56,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include void f2b(void) { @@ -62,6 +65,7 @@ f2b(void) """) test.write('f2c.c', r""" +#include void f2c(void) { @@ -70,6 +74,7 @@ f2c(void) """) test.write('f3a.c', r""" +#include void f3a(void) { @@ -78,6 +83,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include void f3b(void) { diff --git a/test/M4/M4.py b/test/M4/M4.py index bf56e74..859c57b 100644 --- a/test/M4/M4.py +++ b/test/M4/M4.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,9 +49,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(M4 = r'%s mym4.py', tools=['default', 'm4']) +env = Environment(M4 = r'%(_python_)s mym4.py', tools=['default', 'm4']) env.M4(target = 'aaa.x', source = 'aaa.x.m4') -""" % python) +""" % locals()) test.write('aaa.x.m4', """\ line 1 @@ -80,7 +80,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(M4=r'%(m4)s', M4FLAGS='-DFFF=fff') m4 = foo.Dictionary('M4') -bar = Environment(M4 = r'%(python)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb') +bar = Environment(M4 = r'%(_python_)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb') foo.M4(target = 'foo.x', source = 'foo.x.m4') bar.M4(target = 'bar', source = 'bar.m4') """ % locals()) diff --git a/test/M4/M4COM.py b/test/M4/M4COM.py index d1c53b4..8c36d86 100644 --- a/test/M4/M4COM.py +++ b/test/M4/M4COM.py @@ -30,7 +30,7 @@ Test the ability to configure the $M4COM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'm4'], - M4COM = r'%s mym4.py $TARGET $SOURCES') + M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES') env.M4(target = 'aaa.out', source = 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*m4*/\n") diff --git a/test/M4/M4COMSTR.py b/test/M4/M4COMSTR.py index 0e14495..a9e91e6 100644 --- a/test/M4/M4COMSTR.py +++ b/test/M4/M4COMSTR.py @@ -31,7 +31,7 @@ the displayed string when m4 is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'm4'], - M4COM = r'%s mym4.py $TARGET $SOURCES', + M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES', M4COMSTR = 'M4ing $TARGET from $SOURCE') env.M4(target = 'aaa.out', source = 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*m4*/\n") diff --git a/test/MSVC/PCHCOM.py b/test/MSVC/PCHCOM.py index 593a1c1..2473391 100644 --- a/test/MSVC/PCHCOM.py +++ b/test/MSVC/PCHCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $MIDLCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - PCHCOM = r'%s mypch.py $TARGET $SOURCES') + PCHCOM = r'%(_python_)s mypch.py $TARGET $SOURCES') env.PCH(target = 'aaa', source = 'aaa.h') -""" % python) +""" % locals()) test.write('aaa.h', "aaa.h\n/*pch*/\n") diff --git a/test/MSVC/PCHCOMSTR.py b/test/MSVC/PCHCOMSTR.py index c5ab9f5..23322d4 100644 --- a/test/MSVC/PCHCOMSTR.py +++ b/test/MSVC/PCHCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when pch is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - PCHCOM = r'%s mypch.py $TARGET $SOURCES', + PCHCOM = r'%(_python_)s mypch.py $TARGET $SOURCES', PCHCOMSTR = 'PCHing $TARGET from $SOURCE') env.PCH(target = 'aaa', source = 'aaa.h') -""" % python) +""" % locals()) test.write('aaa.h', "aaa.h\n/*pch*/\n") diff --git a/test/MSVC/RCCOM.py b/test/MSVC/RCCOM.py index 3262f0c..e881bb5 100644 --- a/test/MSVC/RCCOM.py +++ b/test/MSVC/RCCOM.py @@ -31,7 +31,7 @@ when using MSVC. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES') + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/MSVC/RCCOMSTR.py b/test/MSVC/RCCOMSTR.py index 33e192b..96ccee0 100644 --- a/test/MSVC/RCCOMSTR.py +++ b/test/MSVC/RCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when rc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'msvc'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES', + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES', RCCOMSTR = 'RCing $TARGET from $SOURCE') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/MSVC/generate-rc.py b/test/MSVC/generate-rc.py new file mode 100644 index 0000000..0b3c332 --- /dev/null +++ b/test/MSVC/generate-rc.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test adding a src_builder to the RES builder so that RC files can +be generated. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +fake_rc = test.workpath('fake_rc.py') + +test.write(fake_rc, """\ +import sys +contents = open(sys.argv[2], 'rb').read() +open(sys.argv[1], 'wb').write("fake_rc.py\\n" + contents) +""") + +test.write('SConstruct', """ +def generate_rc(target, source, env): + t = str(target[0]) + s = str(source[0]) + tfp = open(t, 'wb') + tfp.write('generate_rc\\n' + open(s, 'r').read()) + +env = Environment(tools=['msvc'], + RCCOM=r'%(_python_)s %(fake_rc)s $TARGET $SOURCE') +env['BUILDERS']['GenerateRC'] = Builder(action=generate_rc, + suffix='.rc', + src_suffix='.in') +env['BUILDERS']['RES'].src_builder.append('GenerateRC') + +env.RES('my.in') +""" % locals()) + +test.write('my.in', "my.in\n") + +test.run(arguments = '.') + +test.must_match('my.rc', "generate_rc\nmy.in\n") +test.must_match('my.res', "fake_rc.py\ngenerate_rc\nmy.in\n") + +test.pass_test() diff --git a/test/MSVC/msvc.py b/test/MSVC/msvc.py index dd0f5ca..857b6bd 100644 --- a/test/MSVC/msvc.py +++ b/test/MSVC/msvc.py @@ -24,13 +24,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons -import sys -import os.path import os -import TestCmd +import os.path +import re +import sys import time +import TestCmd +import TestSCons + test = TestSCons.TestSCons(match = TestCmd.match_re) if sys.platform != 'win32': @@ -234,30 +236,36 @@ test.must_not_exist(test.workpath('build/StdAfx.obj')) ##### # Test error reporting -test.write('SConstruct',""" -env=Environment() +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """\ +env = Environment() env['PDB'] = File('test.pdb') env['PCH'] = env.PCH('StdAfx.cpp')[0] env.Program('test', 'test.cpp') """) -test.run(status=2, stderr=''' +expect_stderr = r''' scons: \*\*\* The PCHSTOP construction must be defined if PCH is defined. -File "SConstruct", line 5, in \? -''') +File "%s", line 4, in \? +''' % re.escape(SConstruct_path) -test.write('SConstruct',""" -env=Environment() +test.run(status=2, stderr=expect_stderr) + +test.write(SConstruct_path, """\ +env = Environment() env['PDB'] = File('test.pdb') env['PCHSTOP'] = File('StdAfx.h') env['PCH'] = env.PCH('StdAfx.cpp')[0] env.Program('test', 'test.cpp') """) -test.run(status=2, stderr=''' +expect_stderr = r''' scons: \*\*\* The PCHSTOP construction variable must be a string: .+ -File "SConstruct", line 6, in \? -''') +File "%s", line 5, in \? +''' % re.escape(SConstruct_path) + +test.run(status=2, stderr=expect_stderr) test.pass_test() diff --git a/test/MSVS/common-prefix.py b/test/MSVS/common-prefix.py index 6f508c9..d40060c 100644 --- a/test/MSVS/common-prefix.py +++ b/test/MSVS/common-prefix.py @@ -43,7 +43,7 @@ if sys.platform != 'win32': msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform test.skip_test(msg) -expected_vcprojfile = """\ +vcproj_template = """\ \t \t -\t -\t\t\t -\t\t\t -\t\t\t -\t\t\t -\t\t\t -\t\t\t -\t\t -\t\t -\t +%(sln_files)s \t \t @@ -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 +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t +\t\t +\t""" + +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 +\t\t\t +\t\t\t +\t\t +\t\t +\t""" + +test.write(['work2', 'SConstruct'], SConscript_contents % locals()) + +test.run(chdir='work2', arguments="Test.vcproj") + +test.must_exist(test.workpath('work2', 'Test.vcproj')) +vcproj = test.read(['work2', 'Test.vcproj'], 'r') +expected_vcprojfile = vcproj_template % locals() +expect = test.msvs_substitute(expected_vcprojfile, '8.0', 'work2', 'SConstruct') +# don't compare the pickled data +assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj) + + + test.pass_test() diff --git a/test/MSVS/runfile.py b/test/MSVS/runfile.py index 581de64..5638916 100644 --- a/test/MSVS/runfile.py +++ b/test/MSVS/runfile.py @@ -100,7 +100,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') env.MSVSProject(target = 'Test.vcproj', slnguid = '{SLNGUID}', diff --git a/test/MSVS/vs-6.0-files.py b/test/MSVS/vs-6.0-files.py index 135bb7f..ce7ef46 100644 --- a/test/MSVS/vs-6.0-files.py +++ b/test/MSVS/vs-6.0-files.py @@ -184,7 +184,7 @@ Package=<3> SConscript_contents = """\ -env=Environment(MSVS_VERSION = '6.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '6.0') testsrc = ['test.c'] testincs = ['sdk.h'] @@ -278,7 +278,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '6.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '6.0') testsrc = ['test.c'] testincs = ['sdk.h'] diff --git a/test/MSVS/vs-7.0-files.py b/test/MSVS/vs-7.0-files.py index 8c82d1a..8f98166 100644 --- a/test/MSVS/vs-7.0-files.py +++ b/test/MSVS/vs-7.0-files.py @@ -144,7 +144,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '7.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -206,7 +206,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' test.run(chdir='work1', arguments='Test.vcproj') -python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1]) test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') @@ -260,7 +260,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '7.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] diff --git a/test/MSVS/vs-7.1-files.py b/test/MSVS/vs-7.1-files.py index bbe6f1e..3ad2e97 100644 --- a/test/MSVS/vs-7.1-files.py +++ b/test/MSVS/vs-7.1-files.py @@ -146,7 +146,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '7.1') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.1') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -208,7 +208,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' test.run(chdir='work1', arguments='Test.vcproj') -python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1]) test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') @@ -262,7 +262,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '7.1') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.1') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] diff --git a/test/MSVS/vs-8.0-files.py b/test/MSVS/vs-8.0-files.py index 878aa3f..1d3c469 100644 --- a/test/MSVS/vs-8.0-files.py +++ b/test/MSVS/vs-8.0-files.py @@ -153,7 +153,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -215,7 +215,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' test.run(chdir='work1', arguments='Test.vcproj') -python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) +python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1]) test.must_exist(test.workpath('work1', 'Test.vcproj')) vcproj = test.read(['work1', 'Test.vcproj'], 'r') @@ -273,7 +273,7 @@ The real workspace file is here: test.subdir('work3') test.write(['work3', 'SConstruct'], """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] diff --git a/test/MinGW/RCCOM.py b/test/MinGW/RCCOM.py index 4ddcd91..2db0563 100644 --- a/test/MinGW/RCCOM.py +++ b/test/MinGW/RCCOM.py @@ -31,7 +31,7 @@ when using MinGW. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES') + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/MinGW/RCCOMSTR.py b/test/MinGW/RCCOMSTR.py index e095847..96565f1 100644 --- a/test/MinGW/RCCOMSTR.py +++ b/test/MinGW/RCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when rc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(python)s myrc.py $TARGET $SOURCES', + RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES', RCCOMSTR = 'RCing $TARGET from $SOURCE') env.RES(target = 'aaa', source = 'aaa.rc') """ % locals()) diff --git a/test/NodeOps.py b/test/NodeOps.py index 9f548c4..ff3e0ca 100644 --- a/test/NodeOps.py +++ b/test/NodeOps.py @@ -47,13 +47,6 @@ _lib = TestSCons._lib _obj = TestSCons._obj dll_ = TestSCons.dll_ _dll = TestSCons._dll - -if sys.platform == 'win32': - fooflags = '/nologo -DFOO' - barflags = '/nologo -DBAR' -else: - fooflags = '-DFOO' - barflags = '-DBAR' if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' @@ -62,6 +55,10 @@ if string.find(sys.platform, 'irix') > -1: test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCXXFLAGS'] + ' -DFOO' +barflags = e['SHCXXFLAGS'] + ' -DBAR' + test.subdir('bld', 'src', ['src', 'subsrcdir']) sconstruct = r""" diff --git a/test/Object.py b/test/Object.py index 8b9c5e0..da945e3 100644 --- a/test/Object.py +++ b/test/Object.py @@ -46,6 +46,7 @@ env.Program(target = 'prog3', source = ['f1%s', f2, 'f3%s', 'prog.cpp']) """ % (_obj, _obj, _obj, _obj, _obj, _obj)) test.write('f1.c', r""" +#include void f1(void) { @@ -64,6 +65,7 @@ f2(void) """) test.write('f3.c', r""" +#include void f3(void) { @@ -72,6 +74,7 @@ f3(void) """) test.write('f4.c', r""" +#include void f4(void) { @@ -80,6 +83,7 @@ f4(void) """) test.write('f5.c', r""" +#include void f5(void) { diff --git a/test/Options/BoolOption.py b/test/Options/BoolOption.py index ef6491d..7af9bfd 100644 --- a/test/Options/BoolOption.py +++ b/test/Options/BoolOption.py @@ -35,13 +35,15 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import BoolOption opts = Options(args=ARGUMENTS) @@ -59,18 +61,21 @@ print env['profile'] Default(env.Alias('dummy', None)) """) + + test.run() check(['1', '0']) test.run(arguments='warnings=0 profile=no profile=true') check(['0', '1']) -test.run(arguments='warnings=irgendwas', - stderr = """ +expect_stderr = """ scons: *** Error converting option: warnings Invalid value for boolean option: irgendwas -File "SConstruct", line 10, in ? -""", status=2) +File "%(SConstruct_path)s", line 9, in ? +""" % locals() + +test.run(arguments='warnings=irgendwas', stderr = expect_stderr, status=2) diff --git a/test/Options/EnumOption.py b/test/Options/EnumOption.py index c47f7d5..5e29477 100644 --- a/test/Options/EnumOption.py +++ b/test/Options/EnumOption.py @@ -35,13 +35,15 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import EnumOption list_of_libs = Split('x11 gl qt ical') @@ -71,28 +73,33 @@ Default(env.Alias('dummy', None)) test.run(); check(['no', 'gtk', 'xaver']) + test.run(arguments='debug=yes guilib=Motif some=xAVER') check(['yes', 'Motif', 'xaver']) + test.run(arguments='debug=full guilib=KdE some=EiNs') check(['full', 'KdE', 'eins']) -test.run(arguments='debug=FULL', - stderr = """ +expect_stderr = """ scons: *** Invalid value for option debug: FULL -File "SConstruct", line 19, in ? -""", status=2) +File "%(SConstruct_path)s", line 18, in ? +""" % locals() -test.run(arguments='guilib=IrGeNdwas', - stderr = """ +test.run(arguments='debug=FULL', stderr=expect_stderr, status=2) + +expect_stderr = """ scons: *** Invalid value for option guilib: irgendwas -File "SConstruct", line 19, in ? -""", status=2) +File "%(SConstruct_path)s", line 18, in ? +""" % locals() + +test.run(arguments='guilib=IrGeNdwas', stderr=expect_stderr, status=2) -test.run(arguments='some=IrGeNdwas', - stderr = """ +expect_stderr = """ scons: *** Invalid value for option some: irgendwas -File "SConstruct", line 19, in ? -""", status=2) +File "%(SConstruct_path)s", line 18, in ? +""" % locals() + +test.run(arguments='some=IrGeNdwas', stderr=expect_stderr, status=2) test.pass_test() diff --git a/test/Options/ListOption.py b/test/Options/ListOption.py index 5dbe0c3..fddfc5f 100644 --- a/test/Options/ListOption.py +++ b/test/Options/ListOption.py @@ -35,13 +35,16 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') - assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) + r = result[1:len(expect)+1] + assert r == expect, (r, expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import ListOption list_of_libs = Split('x11 gl qt ical') @@ -70,56 +73,69 @@ Default(env.Alias('dummy', None)) test.run() check(['all', '1', 'gl ical qt x11', 'gl ical qt x11']) + test.run(arguments='shared=none') check(['none', '0', '', '']) + test.run(arguments='shared=') check(['none', '0', '', '']) + test.run(arguments='shared=x11,ical') check(['ical,x11', '1', 'ical x11', 'ical x11']) + test.run(arguments='shared=x11,,ical,,') check(['ical,x11', '1', 'ical x11', 'ical x11']) + test.run(arguments='shared=GL') check(['gl', '0', 'gl', 'gl']) + test.run(arguments='shared=QT,GL') check(['gl,qt', '0', 'gl qt', 'gl qt']) -test.run(arguments='shared=foo', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=foo', stderr=expect_stderr, status=2) # be paranoid in testing some more combinations -test.run(arguments='shared=foo,ical', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=foo,ical', stderr=expect_stderr, status=2) -test.run(arguments='shared=ical,foo', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() -test.run(arguments='shared=ical,foo,x11', - stderr = """ +test.run(arguments='shared=ical,foo', stderr=expect_stderr, status=2) + +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=ical,foo,x11', stderr=expect_stderr, status=2) -test.run(arguments='shared=foo,x11,,,bar', - stderr = """ +expect_stderr = """ scons: *** Error converting option: shared Invalid value(s) for option: foo,bar -File "SConstruct", line 15, in ? -""", status=2) +File "%(SConstruct_path)s", line 14, in ? +""" % locals() + +test.run(arguments='shared=foo,x11,,,bar', stderr=expect_stderr, status=2) + + test.write('SConstruct', """ from SCons.Options import ListOption diff --git a/test/Options/PackageOption.py b/test/Options/PackageOption.py index cc520f7..81f7003 100644 --- a/test/Options/PackageOption.py +++ b/test/Options/PackageOption.py @@ -35,13 +35,15 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import PackageOption opts = Options(args=ARGUMENTS) @@ -64,11 +66,12 @@ test.run(arguments='x11=no'); check(['0']) test.run(arguments='x11=0'); check(['0']) test.run(arguments=['x11=%s' % test.workpath()]); check([test.workpath()]) -test.run(arguments='x11=/non/existing/path/', - stderr = """ +expect_stderr = """ scons: *** Path does not exist for option x11: /non/existing/path/ -File "SConstruct", line 11, in ? -""", status=2) +File "%(SConstruct_path)s", line 10, in ? +""" % locals() + +test.run(arguments='x11=/non/existing/path/', stderr=expect_stderr, status=2) diff --git a/test/Options/PathOption.py b/test/Options/PathOption.py index d15f39b..d22071e 100644 --- a/test/Options/PathOption.py +++ b/test/Options/PathOption.py @@ -36,6 +36,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + def check(expect): result = string.split(test.stdout(), '\n') assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect) @@ -46,7 +48,7 @@ test.subdir('lib', 'qt', ['qt', 'lib'], 'nolib' ) workpath = test.workpath() libpath = os.path.join(workpath, 'lib') -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import PathOption qtdir = r'%s' @@ -88,17 +90,20 @@ test.run(arguments=['qtdir=%s' % qtpath, 'qt_libraries=%s' % libpath]) check([qtpath, libpath, libpath]) qtpath = os.path.join(workpath, 'non', 'existing', 'path') -test.run(arguments=['qtdir=%s' % qtpath], - stderr = """ -scons: *** Path for option qtdir does not exist: %s -File "SConstruct", line 12, in ? -""" % qtpath, status=2) -test.run(arguments=['qt_libraries=%s' % qtpath], - stderr = """ -scons: *** Path for option qt_libraries does not exist: %s -File "SConstruct", line 12, in ? -""" % qtpath, status=2) +expect_stderr = """ +scons: *** Path for option qtdir does not exist: %(qtpath)s +File "%(SConstruct_path)s", line 11, in ? +""" % locals() + +test.run(arguments=['qtdir=%s' % qtpath], stderr=expect_stderr, status=2) + +expect_stderr = """ +scons: *** Path for option qt_libraries does not exist: %(qtpath)s +File "%(SConstruct_path)s", line 11, in ? +""" % locals() + +test.run(arguments=['qt_libraries=%s' % qtpath], stderr=expect_stderr, status=2) @@ -149,7 +154,7 @@ test.must_not_exist(non_existing_subdir) -test.write('SConstruct', """\ +test.write(SConstruct_path, """\ opts = Options(args=ARGUMENTS) opts.AddOptions( PathOption('X', 'X variable', r'%s', validator=PathOption.PathIsFile), @@ -162,33 +167,34 @@ print env['X'] Default(env.Alias('dummy', None)) """ % default_file) -test.run(status=2, - stderr=""" -scons: *** File path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % default_file) +expect_stderr = """ +scons: *** File path for option X does not exist: %(default_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(status=2, stderr=expect_stderr) test.write(default_file, "default_file\n") test.run() check([default_file]) -test.run(arguments=['X=%s' % existing_subdir], - status=2, - stderr=""" -scons: *** File path for option X is a directory: %s -File "SConstruct", line 6, in ? -""" % existing_subdir) +expect_stderr = """ +scons: *** File path for option X is a directory: %(existing_subdir)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(arguments=['X=%s' % existing_subdir], status=2, stderr=expect_stderr) test.run(arguments=['X=%s' % existing_file]) check([existing_file]) -test.run(arguments=['X=%s' % non_existing_file], - status=2, - stderr=""" -scons: *** File path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % non_existing_file) +expect_stderr = """ +scons: *** File path for option X does not exist: %(non_existing_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(arguments=['X=%s' % non_existing_file], status=2, stderr=expect_stderr) @@ -205,33 +211,38 @@ print env['X'] Default(env.Alias('dummy', None)) """ % default_subdir) -test.run(status=2, - stderr=""" -scons: *** Directory path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % default_subdir) +expect_stderr = """ +scons: *** Directory path for option X does not exist: %(default_subdir)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(status=2, stderr=expect_stderr) test.subdir(default_subdir) test.run() check([default_subdir]) +expect_stderr = """ +scons: *** Directory path for option X is a file: %(existing_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + test.run(arguments=['X=%s' % existing_file], status=2, - stderr=""" -scons: *** Directory path for option X is a file: %s -File "SConstruct", line 6, in ? -""" % existing_file) + stderr=expect_stderr) test.run(arguments=['X=%s' % existing_subdir]) check([existing_subdir]) +expect_stderr = """ +scons: *** Directory path for option X does not exist: %(non_existing_subdir)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + test.run(arguments=['X=%s' % non_existing_subdir], status=2, - stderr=""" -scons: *** Directory path for option X does not exist: %s -File "SConstruct", line 6, in ? -""" % non_existing_subdir) + stderr=expect_stderr) @@ -251,12 +262,12 @@ Default(env.Alias('dummy', None)) test.run() check([default_subdir]) -test.run(arguments=['X=%s' % existing_file], - status=2, - stderr=""" -scons: *** Path for option X is a file, not a directory: %s -File "SConstruct", line 6, in ? -""" % existing_file) +expect_stderr = """ +scons: *** Path for option X is a file, not a directory: %(existing_file)s +File "%(SConstruct_path)s", line 6, in ? +""" % locals() + +test.run(arguments=['X=%s' % existing_file], status=2, stderr=expect_stderr) test.run(arguments=['X=%s' % existing_subdir]) check([existing_subdir]) diff --git a/test/ParseConfig.py b/test/ParseConfig.py index 55678fe..668d08a 100644 --- a/test/ParseConfig.py +++ b/test/ParseConfig.py @@ -30,7 +30,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,8 +57,8 @@ print "-L foo -L lib_dir -isysroot /tmp -arch ppc -arch i386" test.write('SConstruct', """ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '') -env.ParseConfig([r"%(python)s", r"%(test_config1)s", "--libs --cflags"]) -env.ParseConfig([r"%(python)s", r"%(test_config2)s", "--libs --cflags"]) +env.ParseConfig([r'%(_python_)s', r"%(test_config1)s", "--libs --cflags"]) +env.ParseConfig([r'%(_python_)s', r"%(test_config2)s", "--libs --cflags"]) print env['CPPPATH'] print env['LIBPATH'] print map(lambda x: str(x), env['LIBS']) @@ -67,7 +67,7 @@ print env['CCFLAGS'] test.write('SConstruct2', """ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '', - PYTHON = '%(python)s') + PYTHON = '%(_python_)s') env.ParseConfig(r"$PYTHON %(test_config1)s --libs --cflags") env.ParseConfig(r"$PYTHON %(test_config2)s --libs --cflags") print env['CPPPATH'] @@ -78,7 +78,7 @@ print env['CCFLAGS'] test.write('SConstruct3', """ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '', - PYTHON = '%(python)s') + PYTHON = '%(_python_)s') env.ParseConfig(r"$PYTHON %(test_config3)s --libs --cflags") print env['CPPPATH'] print env['LIBPATH'] diff --git a/test/ParseDepends.py b/test/ParseDepends.py index 9a9910a..e979b91 100644 --- a/test/ParseDepends.py +++ b/test/ParseDepends.py @@ -29,7 +29,7 @@ import string import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,8 +44,8 @@ file.close() """) test.write('SConstruct', """ -Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep") -Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep") +Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep') +Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep') env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir') env.ParseDepends('foo.d') env.ParseDepends('bar.d') @@ -55,7 +55,7 @@ env.Bar(target = 'subdir/f3.out', source = 'f3.in') SConscript('subdir/SConscript', "env") env.Foo(target = 'f5.out', source = 'f5.in') env.Bar(target = 'sub2/f6.out', source = 'f6.in') -""" % (python, python)) +""" % locals()) test.write('foo.d', "f1.out f2.out: %s\n" % os.path.join('subdir', 'foo.dep')) test.write('bar.d', "%s: %s\nf5.out: sub2" % (os.path.join('subdir', 'f3.out'), diff --git a/test/Perforce/P4COM.py b/test/Perforce/P4COM.py index c33254a..11b28e3 100644 --- a/test/Perforce/P4COM.py +++ b/test/Perforce/P4COM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'Perforce'], BUILDERS={'Cat':Builder(action=cat)}, - P4COM='%(python)s my-p4.py $TARGET') + P4COM='%(_python_)s my-p4.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['Perforce', 'sub', 'fff.in'], "Perforce/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-p4.py %(sub_SConscript)s +%(_python_)s my-p4.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-p4.py aaa.in +%(_python_)s my-p4.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-p4.py ccc.in +%(_python_)s my-p4.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-p4.py %(sub_ddd_in)s +%(_python_)s my-p4.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-p4.py %(sub_fff_in)s +%(_python_)s my-p4.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/Perforce/P4COMSTR.py b/test/Perforce/P4COMSTR.py index d9a3bc0..72f05b8 100644 --- a/test/Perforce/P4COMSTR.py +++ b/test/Perforce/P4COMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'Perforce'], BUILDERS={'Cat':Builder(action=cat)}, - P4COM='%(python)s my-p4.py $TARGET', + P4COM='%(_python_)s my-p4.py $TARGET', P4COMSTR='Checking out $TARGET from our fake Perforce') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/Perforce/Perforce.py b/test/Perforce/Perforce.py index f813f10..0133ced 100644 --- a/test/Perforce/Perforce.py +++ b/test/Perforce/Perforce.py @@ -32,7 +32,6 @@ on port 1666, as well as that of course a client must be present. """ import os -import socket import string import TestSCons @@ -41,11 +40,13 @@ class TestPerforce(TestSCons.TestSCons): def __init__(self, *args, **kw): apply(TestSCons.TestSCons.__init__, (self,)+args, kw) - self._p4prog = self.where_is('p4') - if not self._p4prog: + self.p4path = self.where_is('p4') + if not self.p4path: self.skip_test("Could not find 'p4'; skipping test(s).\n") - self.host = socket.gethostname() + #import socket + #self.host = socket.gethostname() + self.host = '127.0.0.1' self.user = os.environ.get('USER') if not self.user: @@ -98,7 +99,7 @@ class TestPerforce(TestSCons.TestSCons): arguments = args[0] args = args[1:] kw['arguments'] = string.join(self.p4portflags + [arguments]) - kw['program'] = self._p4prog + kw['program'] = self.p4path return apply(self.run, args, kw) def substitute(self, s, **kw): @@ -145,8 +146,6 @@ Client: %(client)s Owner: %(user)s -Host: %(host)s - Description: Created by %(user)s. @@ -234,7 +233,9 @@ def cat(env, source, target): for src in source: f.write(open(src, "rb").read()) f.close() -env = Environment(BUILDERS={'Cat':Builder(action=cat)}, +env = Environment(tools = ['default', 'Perforce'], + BUILDERS={'Cat':Builder(action=cat)}, + P4=r'%(p4path)s', P4FLAGS='%(portflag)s -c testclient2') env.Cat('aaa.out', 'foo/aaa.in') env.Cat('bbb.out', 'foo/bbb.in') diff --git a/test/Precious.py b/test/Precious.py index 940fab7..76aa2a4 100644 --- a/test/Precious.py +++ b/test/Precious.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -39,17 +39,18 @@ import sys sys.exit(0) """) +SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out') + test.write('SConstruct', """\ -B = Builder(action = r"%s build.py $TARGET $SOURCES") +B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }, SUBDIR = 'subdir') f1 = env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') env.B(target = 'subdir/f4.out', source = 'f4.in') -env.Precious(f1, 'f2.out', r'%s') +env.Precious(f1, 'f2.out', r'%(SUBDIR_f4_out)s') SConscript('subdir/SConscript', "env") -""" % (python, - os.path.join('$SUBDIR', 'f4.out'))) +""" % locals()) test.write(['subdir', 'SConscript'], """ Import("env") diff --git a/test/Program-j.py b/test/Program-j.py index fe778b3..d8180bb 100644 --- a/test/Program-j.py +++ b/test/Program-j.py @@ -45,6 +45,8 @@ env.Program(target = 'f4', source = 'f4.c') """) test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -55,6 +57,9 @@ main(int argc, char *argv[]) """) test.write('f2.c', r""" +#include +#include + int main(int argc, char *argv[]) { @@ -66,6 +71,8 @@ main(int argc, char *argv[]) test.write('f3.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -76,6 +83,8 @@ main(int argc, char *argv[]) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/Program.py b/test/Program.py index 5b785a3..cf98148 100644 --- a/test/Program.py +++ b/test/Program.py @@ -52,6 +52,8 @@ env.Program('foo5.c') """) test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('f2a.c', r""" +#include +#include void f2a(void) { @@ -70,6 +74,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include void f2b(void) { @@ -78,6 +83,8 @@ f2b(void) """) test.write('f2c.c', r""" +#include +#include extern void f2a(void); extern void f2b(void); int @@ -92,6 +99,7 @@ main(int argc, char *argv[]) """) test.write('f3a.c', r""" +#include void f3a(void) { @@ -100,6 +108,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include void f3b(void) { @@ -108,6 +117,8 @@ f3b(void) """) test.write('f3c.c', r""" +#include +#include extern void f3a(void); extern void f3b(void); int @@ -122,6 +133,8 @@ main(int argc, char *argv[]) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -132,6 +145,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include 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 +#include int main(int argc, char *argv[]) { @@ -162,6 +179,7 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include void f3b(void) { @@ -170,6 +188,8 @@ f3b(void) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -180,6 +200,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include 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 +#include int main(int argc, char *argv[]) { @@ -227,6 +251,8 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include +#include void f3b(void) { @@ -235,6 +261,8 @@ f3b(void) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -245,6 +273,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include 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 +#include int main(int argc, char *argv[]) { @@ -275,6 +307,8 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include +#include void f3b(void) { @@ -283,6 +317,8 @@ f3b(void) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -293,6 +329,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py index f9cb917..ba08739 100644 --- a/test/QT/QTFLAGS.py +++ b/test/QT/QTFLAGS.py @@ -31,7 +31,7 @@ Testing the configuration mechanisms of the 'qt' tool. import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -123,8 +123,8 @@ test.run(chdir=test.workpath('qt','lib'), arguments = '.', QT = test.workpath('qt') QT_LIB = 'myqt' -QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py')) -QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py')) +QT_MOC = '%s %s' % (_python_, test.workpath('qt','bin','mymoc.py')) +QT_UIC = '%s %s' % (_python_, test.workpath('qt','bin','myuic.py')) def createSConstruct(test,place,overrides): test.write(place, """ diff --git a/test/QT/moc-from-header.py b/test/QT/moc-from-header.py index 0bf6873..1dbcd0f 100644 --- a/test/QT/moc-from-header.py +++ b/test/QT/moc-from-header.py @@ -28,6 +28,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Create a moc file from a header file. """ +import os + import TestSCons test = TestSCons.TestSCons() @@ -38,6 +40,10 @@ env = Environment() test.Qt_dummy_installation() +# We'll run some test programs later that need to find our dummy +# Qt library. +os.environ['LD_LIBRARY_PATH'] = test.QT_LIB_DIR + ############################################################################## aaa_exe = 'aaa' + TestSCons._exe diff --git a/test/QT/warnings.py b/test/QT/warnings.py index 7b41360..0fd3f66 100644 --- a/test/QT/warnings.py +++ b/test/QT/warnings.py @@ -29,15 +29,18 @@ Test the Qt tool warnings. """ import os +import re import string import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + test.Qt_dummy_installation() -test.Qt_create_SConstruct('SConstruct') +test.Qt_create_SConstruct(SConstruct_path) test.write('aaa.cpp', r""" #include "my_qobject.h" @@ -77,15 +80,19 @@ test.run(stderr=None, arguments='-n noqtdir=1') moc = test.where_is('moc') if moc: import os.path + qtdir = os.path.dirname(os.path.dirname(moc)) + qtdir = string.replace(qtdir, '\\', '\\\\' ) + expect = """ scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\) -File "SConstruct", line \d+, in \? -""" % string.replace( os.path.dirname(os.path.dirname(moc)), '\\', '\\\\' ) +File "%s", line \d+, in \? +""" % (qtdir, re.escape(SConstruct_path)) else: + expect = """ scons: warning: Could not detect qt, using empty QTDIR -File "SConstruct", line \d+, in \? -""" +File "%s", line \d+, in \? +""" % re.escape(SConstruct_path) test.fail_test(not test.match_re(test.stderr(), expect)) diff --git a/test/RANLIB/RANLIB.py b/test/RANLIB/RANLIB.py index 5002b20..75e860a 100644 --- a/test/RANLIB/RANLIB.py +++ b/test/RANLIB/RANLIB.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe @@ -53,7 +53,7 @@ test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) ranlib = foo.Dictionary('RANLIB') bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], - RANLIB = r'%s wrapper.py ' + ranlib) + RANLIB = r'%(_python_)s wrapper.py ' + ranlib) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -61,9 +61,10 @@ main = foo.Object('main', 'main.c') foo.Program(target = 'f', source = main) bar.Program(target = 'b', source = main) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include void library_function(void) { @@ -72,6 +73,8 @@ library_function(void) """) test.write('bar.c', r""" +#include + void library_function(void) { @@ -80,6 +83,7 @@ library_function(void) """) test.write('main.c', r""" +#include int main(int argc, char *argv[]) { diff --git a/test/RANLIB/RANLIBCOM.py b/test/RANLIB/RANLIBCOM.py index d60a14e..312216b 100644 --- a/test/RANLIB/RANLIBCOM.py +++ b/test/RANLIB/RANLIBCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $RANLIBCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -62,12 +62,12 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n/*ranlib*/\n") test.write('file.2', "file.2\n/*ar*/\n/*ranlib*/\n") diff --git a/test/RANLIB/RANLIBCOMSTR.py b/test/RANLIB/RANLIBCOMSTR.py index 4e03675..6929ac6 100644 --- a/test/RANLIB/RANLIBCOMSTR.py +++ b/test/RANLIB/RANLIBCOMSTR.py @@ -31,7 +31,7 @@ customize the displayed archive indexer string. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -63,21 +63,23 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'ar'], - ARCOM = r'%s myar.py $TARGET $SOURCES', - RANLIBCOM = r'%s myranlib.py $TARGET', + ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES', + RANLIBCOM = r'%(_python_)s myranlib.py $TARGET', RANLIBCOMSTR = 'Indexing $TARGET', LIBPREFIX = '', LIBSUFFIX = '.lib') env.Library(target = 'output', source = ['file.1', 'file.2']) -""" % (python, python)) +""" % locals()) test.write('file.1', "file.1\n/*ar*/\n/*ranlib*/\n") test.write('file.2', "file.2\n/*ar*/\n/*ranlib*/\n") -test.run(stdout = test.wrap_stdout("""\ -%s myar.py output.lib file.1 file.2 +expect = test.wrap_stdout("""\ +%(_python_)s myar.py output.lib file.1 file.2 Indexing output.lib -""" % python)) +""" % locals()) + +test.run(stdout = expect) test.must_match('output.lib', "file.1\nfile.2\n") diff --git a/test/RANLIB/RANLIBFLAGS.py b/test/RANLIB/RANLIBFLAGS.py index 80618ba..08ee967 100644 --- a/test/RANLIB/RANLIBFLAGS.py +++ b/test/RANLIB/RANLIBFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(LIBS = ['foo'], LIBPATH = ['.']) bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], RANLIB = '', - RANLIBFLAGS = foo.subst(r'%s wrapper.py $RANLIB $RANLIBFLAGS')) + RANLIBFLAGS = foo.subst(r'%(_python_)s wrapper.py $RANLIB $RANLIBFLAGS')) foo.Library(target = 'foo', source = 'foo.c') bar.Library(target = 'bar', source = 'bar.c') @@ -58,9 +58,12 @@ main = foo.Object('main', 'main.c') foo.Program(target = 'f', source = main) bar.Program(target = 'b', source = main) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include +#include + void library_function(void) { @@ -69,6 +72,8 @@ library_function(void) """) test.write('bar.c', r""" +#include +#include void library_function(void) { @@ -77,6 +82,8 @@ library_function(void) """) test.write('main.c', r""" +#include + int main(int argc, char *argv[]) { diff --git a/test/RCS/RCS_COCOM.py b/test/RCS/RCS_COCOM.py index a151d69..319a851 100644 --- a/test/RCS/RCS_COCOM.py +++ b/test/RCS/RCS_COCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'RCS'], BUILDERS={'Cat':Builder(action=cat)}, - RCS_COCOM='%(python)s my-rcs-co.py $TARGET') + RCS_COCOM='%(_python_)s my-rcs-co.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['RCS', 'sub', 'fff.in'], "RCS/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-rcs-co.py %(sub_SConscript)s +%(_python_)s my-rcs-co.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-rcs-co.py aaa.in +%(_python_)s my-rcs-co.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-rcs-co.py ccc.in +%(_python_)s my-rcs-co.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-rcs-co.py %(sub_ddd_in)s +%(_python_)s my-rcs-co.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-rcs-co.py %(sub_fff_in)s +%(_python_)s my-rcs-co.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/RCS/RCS_COCOMSTR.py b/test/RCS/RCS_COCOMSTR.py index 9e17418..30a3a57 100644 --- a/test/RCS/RCS_COCOMSTR.py +++ b/test/RCS/RCS_COCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'RCS'], BUILDERS={'Cat':Builder(action=cat)}, - RCS_COCOM='%(python)s my-rcs-co.py $TARGET', + RCS_COCOM='%(_python_)s my-rcs-co.py $TARGET', RCS_COCOMSTR='Checking out $TARGET from our fake RCS') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/RCS/diskcheck.py b/test/RCS/diskcheck.py index 8af2545..78120f6 100644 --- a/test/RCS/diskcheck.py +++ b/test/RCS/diskcheck.py @@ -115,12 +115,13 @@ test.write('bbb.in', "checked-out bbb.in\n") test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") + expect = """\ scons: warning: Ignoring missing SConscript '%s' -File "SConstruct", line 23, in ? +File "%s", line 23, in ? scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop. -""" % os.path.join('sub', 'SConscript') +""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct')) test.run(status=2, stderr=expect) diff --git a/test/RCS/implicit.py b/test/RCS/implicit.py index 362f15a..3223901 100644 --- a/test/RCS/implicit.py +++ b/test/RCS/implicit.py @@ -49,6 +49,8 @@ if not co: test.subdir('RCS') test.write('foo.c', """\ +#include + #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/RPATH.py b/test/RPATH.py index 6ab6eb2..a0ae8c7 100644 --- a/test/RPATH.py +++ b/test/RPATH.py @@ -45,6 +45,7 @@ Program('foo', 'foo.c', LIBS='bar', LIBPATH='bar', RPATH='bar') """) test.write('foo.c', """\ +#include int main() { void bar(); bar(); diff --git a/test/Repository/CPPPATH.py b/test/Repository/CPPPATH.py index 6ec21f3..9db613e 100644 --- a/test/Repository/CPPPATH.py +++ b/test/Repository/CPPPATH.py @@ -53,6 +53,8 @@ test.write(['repository', 'include2', 'foo.h'], r""" """) test.write(['repository', 'foo.c'], r""" +#include +#include #include int main(int argc, char *argv[]) diff --git a/test/Repository/LIBPATH.py b/test/Repository/LIBPATH.py index c4470d2..9216a8b 100644 --- a/test/Repository/LIBPATH.py +++ b/test/Repository/LIBPATH.py @@ -62,6 +62,8 @@ env_yyy.Command('yyy.out', bbb_exe, write_LIBDIRFLAGS) """) test.write(['work', 'aaa.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -72,6 +74,8 @@ main(int argc, char *argv[]) """) test.write(['work', 'bbb.c'], r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/Repository/M4.py b/test/Repository/M4.py index 75fa0de..15d8abb 100644 --- a/test/Repository/M4.py +++ b/test/Repository/M4.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,16 +48,17 @@ sys.stdout.write(string.replace(contents, 'M4', 'mym4.py')) sys.exit(0) """) +mym4_py = test.workpath('mym4.py') opts = "-Y " + test.workpath('repository') test.write(['repository', 'SConstruct'], """\ -env = Environment(M4 = r'%s %s', tools=['default', 'm4']) +env = Environment(M4 = r'%(_python_)s %(mym4_py)s', tools=['default', 'm4']) env.M4(target = 'aaa.x', source = 'aaa.x.m4') SConscript('src/SConscript', "env", build_dir="build") -""" % (python, test.workpath('mym4.py'))) +""" % locals()) test.write(['repository', 'aaa.x.m4'], """\ line 1 diff --git a/test/Repository/Program.py b/test/Repository/Program.py index 93bcb85..eda1202 100644 --- a/test/Repository/Program.py +++ b/test/Repository/Program.py @@ -51,6 +51,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """ % repository) test.write(['repository', 'aaa.c'], r""" +#include void aaa(void) { @@ -59,6 +60,7 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include void bbb(void) { @@ -67,6 +69,9 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include + 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 void bbb(void) { @@ -113,6 +119,7 @@ test.up_to_date(chdir = 'work1', arguments = '.') # test.write(['work1', 'aaa.c'], r""" +#include void aaa(void) { @@ -121,6 +128,8 @@ aaa(void) """) test.write(['work1', 'foo.c'], r""" +#include +#include 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 void aaa(void) { @@ -193,6 +203,7 @@ aaa(void) """) test.write(['repository.old', 'bbb.c'], r""" +#include void bbb(void) { @@ -201,6 +212,8 @@ bbb(void) """) test.write(['repository.old', 'foo.c'], r""" +#include +#include 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 +#include void aaa(void) { @@ -240,6 +255,8 @@ aaa(void) """) test.write(['work2', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -261,6 +278,8 @@ test.up_to_date(chdir = 'work2', arguments = '.') # test.write(['work2', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -269,6 +288,8 @@ aaa(void) """) test.write(['work2', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/StaticLibrary.py b/test/Repository/StaticLibrary.py index 087fa7e..1cf20c3 100644 --- a/test/Repository/StaticLibrary.py +++ b/test/Repository/StaticLibrary.py @@ -66,6 +66,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['repository', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -74,6 +76,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -82,6 +86,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include 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 +#include 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 +#include 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 +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/absolute-path.py b/test/Repository/absolute-path.py index ed360c7..378e321 100644 --- a/test/Repository/absolute-path.py +++ b/test/Repository/absolute-path.py @@ -57,6 +57,8 @@ env.Program('foo', ['aaa.c', r'%s', 'foo.c']) """ % subdir_aaa_c) test.write(['repository', 'src', 'aaa.c'], r""" +#include +#include void src_aaa(void) { @@ -65,6 +67,8 @@ src_aaa(void) """) test.write(['subdir', 'aaa.c'], r""" +#include +#include void subdir_aaa(void) { @@ -73,6 +77,8 @@ subdir_aaa(void) """) test.write(['repository', 'src', 'foo.c'], r""" +#include +#include extern void src_aaa(void); extern void subdir_aaa(void); int diff --git a/test/Repository/include.py b/test/Repository/include.py index 577442a..4575d99 100644 --- a/test/Repository/include.py +++ b/test/Repository/include.py @@ -56,6 +56,8 @@ test.write(['repository', 'bar.h'], r""" """) test.write(['repository', 'foo.c'], r""" +#include +#include #include int main(int argc, char *argv[]) @@ -100,6 +102,8 @@ test.up_to_date(chdir = 'work', arguments = '.') # test.write(['work', 'foo.c'], r""" +#include +#include #include int main(int argc, char *argv[]) diff --git a/test/Repository/link-object.py b/test/Repository/link-object.py index 63c274e..679fa7e 100644 --- a/test/Repository/link-object.py +++ b/test/Repository/link-object.py @@ -52,6 +52,8 @@ env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c']) """ % workpath_repository) test.write(['repository', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -60,6 +62,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -68,6 +72,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include 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 +#include void bbb(void) { diff --git a/test/Repository/multi-dir.py b/test/Repository/multi-dir.py index 4532cc3..ab67c9d 100644 --- a/test/Repository/multi-dir.py +++ b/test/Repository/multi-dir.py @@ -73,6 +73,8 @@ test.write(['repository', 'src', 'include.h'], r""" """) test.write(['repository', 'src', 'main.c'], r""" +#include +#include #include int main(int argc, char *argv[]) diff --git a/test/Repository/no-SConsignFile.py b/test/Repository/no-SConsignFile.py index d838605..95b1749 100644 --- a/test/Repository/no-SConsignFile.py +++ b/test/Repository/no-SConsignFile.py @@ -45,6 +45,7 @@ env.Program('foo', 'src/foo.c') test.write(['src', 'foo.c'], """\ #include +#include #include "foo.h" int main(int argc, char *argv[]) diff --git a/test/Repository/no-repository.py b/test/Repository/no-repository.py index 6dc9add..f9b245e 100644 --- a/test/Repository/no-repository.py +++ b/test/Repository/no-repository.py @@ -50,6 +50,8 @@ env.Program(target = 'foo', source = Split('aaa.c bbb.c foo.c')) """ % no_repository) test.write(['work', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -58,6 +60,8 @@ aaa(void) """) test.write(['work', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -66,6 +70,8 @@ bbb(void) """) test.write(['work', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/signature-order.py b/test/Repository/signature-order.py index 8069b60..99bc56a 100644 --- a/test/Repository/signature-order.py +++ b/test/Repository/signature-order.py @@ -62,6 +62,8 @@ test.write(['repository', 'foo.h'], foo_h_contents) test.write(['repository', 'bar.h'], bar_h_contents) test.write(['repository', 'foo.c'], r""" +#include +#include #include #include int diff --git a/test/Repository/top-level-path.py b/test/Repository/top-level-path.py index 2d4164a..4dccfd5 100644 --- a/test/Repository/top-level-path.py +++ b/test/Repository/top-level-path.py @@ -56,6 +56,8 @@ env.Program('foo', ['aaa.c', '#subdir/aaa.c', 'foo.c']) """) test.write(['repository', 'src', 'aaa.c'], r""" +#include +#include void src_aaa(void) { @@ -64,6 +66,8 @@ src_aaa(void) """) test.write(['repository', 'subdir', 'aaa.c'], r""" +#include +#include void subdir_aaa(void) { @@ -72,6 +76,8 @@ subdir_aaa(void) """) test.write(['repository', 'src', 'foo.c'], r""" +#include +#include extern void src_aaa(void); extern void subdir_aaa(void); int diff --git a/test/Repository/variants.py b/test/Repository/variants.py index f855636..cd4c24a 100644 --- a/test/Repository/variants.py +++ b/test/Repository/variants.py @@ -133,6 +133,8 @@ test.write(['repository', 'src1', 'iii.h'], r""" """) test.write(['repository', 'src1', 'aaa.c'], r""" +#include +#include #include void aaa(void) @@ -142,6 +144,8 @@ aaa(void) """) test.write(['repository', 'src1', 'bbb.c'], r""" +#include +#include #include void bbb(void) @@ -151,6 +155,8 @@ bbb(void) """) test.write(['repository', 'src1', 'main.c'], r""" +#include +#include #include 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 +#include #include #ifdef FOO #define MAIN_OS "FOO" diff --git a/test/Repository/within-repository.py b/test/Repository/within-repository.py index 1cffe81..0b7e844 100644 --- a/test/Repository/within-repository.py +++ b/test/Repository/within-repository.py @@ -53,6 +53,8 @@ env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c']) """ % workpath_repository) test.write(['repository', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -61,6 +63,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -69,6 +73,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include 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 +#include void aaa(void) { @@ -96,6 +104,8 @@ aaa(void) """) test.write(['repository', 'src', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -104,6 +114,8 @@ bbb(void) """) test.write(['repository', 'src', 'bar.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Rpcgen/RPCGEN.py b/test/Rpcgen/RPCGEN.py index 162615b..ea22438 100644 --- a/test/Rpcgen/RPCGEN.py +++ b/test/Rpcgen/RPCGEN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,12 +52,13 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', tools=['default', 'rpcgen']) +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', + tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENCLIENTFLAGS.py b/test/Rpcgen/RPCGENCLIENTFLAGS.py index d8ce226..66ea6df 100644 --- a/test/Rpcgen/RPCGENCLIENTFLAGS.py +++ b/test/Rpcgen/RPCGENCLIENTFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENCLIENTFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENFLAGS.py b/test/Rpcgen/RPCGENFLAGS.py index 951254f..8f6cfff 100644 --- a/test/Rpcgen/RPCGENFLAGS.py +++ b/test/Rpcgen/RPCGENFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENHEADERFLAGS.py b/test/Rpcgen/RPCGENHEADERFLAGS.py index e8d3cb0..411838d 100644 --- a/test/Rpcgen/RPCGENHEADERFLAGS.py +++ b/test/Rpcgen/RPCGENHEADERFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENHEADERFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENSERVICEFLAGS.py b/test/Rpcgen/RPCGENSERVICEFLAGS.py index fbc5c7f..af638ce 100644 --- a/test/Rpcgen/RPCGENSERVICEFLAGS.py +++ b/test/Rpcgen/RPCGENSERVICEFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENSERVICEFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/Rpcgen/RPCGENXDRFLAGS.py b/test/Rpcgen/RPCGENXDRFLAGS.py index dc428a0..6ce0609 100644 --- a/test/Rpcgen/RPCGENXDRFLAGS.py +++ b/test/Rpcgen/RPCGENXDRFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) test.write('SConstruct', """\ -env = Environment(RPCGEN = r'%s myrpcgen.py', +env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py', RPCGENXDRFLAGS = '-x', tools=['default', 'rpcgen']) env.RPCGenHeader('rpcif') env.RPCGenClient('rpcif') env.RPCGenService('rpcif') env.RPCGenXDR('rpcif') -""" % (python,)) +""" % locals()) test.write('rpcif.x', """\ RPCGEN diff --git a/test/SCCS/SCCSCOM.py b/test/SCCS/SCCSCOM.py index 1ba5782..f7a210c 100644 --- a/test/SCCS/SCCSCOM.py +++ b/test/SCCS/SCCSCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'SCCS'], BUILDERS={'Cat':Builder(action=cat)}, - SCCSCOM='%(python)s my-sccs-get.py $TARGET') + SCCSCOM='%(_python_)s my-sccs-get.py $TARGET') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') env.Cat('ccc.out', 'ccc.in') @@ -92,19 +92,19 @@ test.write(['SCCS', 'sub', 'fff.in'], "SCCS/sub/fff.in\n") test.run(arguments = '.', stdout = test.wrap_stdout(read_str = """\ -%(python)s my-sccs-get.py %(sub_SConscript)s +%(_python_)s my-sccs-get.py %(sub_SConscript)s """ % locals(), build_str = """\ -%(python)s my-sccs-get.py aaa.in +%(_python_)s my-sccs-get.py aaa.in cat(["aaa.out"], ["aaa.in"]) cat(["bbb.out"], ["bbb.in"]) -%(python)s my-sccs-get.py ccc.in +%(_python_)s my-sccs-get.py ccc.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -%(python)s my-sccs-get.py %(sub_ddd_in)s +%(_python_)s my-sccs-get.py %(sub_ddd_in)s cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"]) cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"]) -%(python)s my-sccs-get.py %(sub_fff_in)s +%(_python_)s my-sccs-get.py %(sub_fff_in)s cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"]) cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"]) """ % locals())) diff --git a/test/SCCS/SCCSCOMSTR.py b/test/SCCS/SCCSCOMSTR.py index 858e17b..be5d807 100644 --- a/test/SCCS/SCCSCOMSTR.py +++ b/test/SCCS/SCCSCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): f.close() env = Environment(TOOLS = ['default', 'SCCS'], BUILDERS={'Cat':Builder(action=cat)}, - SCCSCOM='%(python)s my-sccs-get.py $TARGET', + SCCSCOM='%(_python_)s my-sccs-get.py $TARGET', SCCSCOMSTR='Checking out $TARGET from our fake SCCS') env.Cat('aaa.out', 'aaa.in') env.Cat('bbb.out', 'bbb.in') diff --git a/test/SCCS/diskcheck.py b/test/SCCS/diskcheck.py index 532ad9c..66566fa 100644 --- a/test/SCCS/diskcheck.py +++ b/test/SCCS/diskcheck.py @@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test transparent checkouts from SCCS files in an SCCS subdirectory. """ +import os.path import string import TestSCons @@ -94,10 +95,10 @@ test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") expect = """\ -scons: warning: Ignoring missing SConscript 'sub/SConscript' -File "SConstruct", line 17, in ? +scons: warning: Ignoring missing SConscript '%s' +File "%s", line 17, in ? scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop. -""" +""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct')) test.run(status=2, stderr=expect) diff --git a/test/SConscript.py b/test/SConscript.py deleted file mode 100644 index 08e41a6..0000000 --- a/test/SConscript.py +++ /dev/null @@ -1,422 +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__" - -import TestSCons - -test = TestSCons.TestSCons() - -test.write('foo.py', "foo = 4\n") - - -test.write('SConstruct', """\ -import os -import foo - -assert foo.foo == 4 - -print "SConstruct", os.getcwd() -SConscript('SConscript') - -x1 = "SConstruct x1" -x2 = "SConstruct x2" -x3,x4 = SConscript('SConscript1', "x1 x2") -assert x3 == "SConscript1 x3", x3 -assert x4 == "SConscript1 x4", x4 - -(x3,x4) = SConscript('SConscript2', ["x1","x2"]) -assert x3 == "SConscript2 x3", x3 -assert x4 == "SConscript2 x4", x4 - -Export("x1 x2") -SConscript('SConscript3') -Import("x1 x2") -assert x1 == "SConscript3 x1", x1 -assert x2 == "SConscript3 x2", x2 - -x1 = "SConstruct x1" -x2 = "SConstruct x2" -Export("x1","x2") -SConscript('SConscript4') -Import("x1"," x2") -assert x1 == "SConscript4 x1", x1 -assert x2 == "SConscript4 x2", x2 - -subdir = Dir('subdir') -script = File('SConscript', subdir) -foo = SConscript(script) -assert foo == "subdir/SConscript foo" - -SConscript('SConscript5') - -import UserList -x7 = "SConstruct x7" -x8 = "SConstruct x8" -x9 = SConscript('SConscript6', UserList.UserList(["x7", "x8"])) -assert x9 == "SConscript6 x9", x9 - -SConscript('SConscript7') -""") - - -test.write('SConscript', """\ -# os should not be automajically imported: -assert not globals().has_key("os") - -import os -print "SConscript " + os.getcwd() -""") - -test.write('SConscript1', """ -Import("x1 x2") -assert x1 == "SConstruct x1", x1 -assert x2 == "SConstruct x2", x2 - -x3 = "SConscript1 x3" -x4 = "SConscript1 x4" -Return("x3 x4") -""") - - -test.write('SConscript2', """\ -Import("x1","x2") -assert x1 == "SConstruct x1", x1 -assert x2 == "SConstruct x2", x2 -x3 = "SConscript2 x3" -x4 = "SConscript2 x4" -Return("x3","x4") -""") - - -test.write('SConscript3', """\ -Import("x1 x2") -assert x1 == "SConstruct x1", x1 -assert x2 == "SConstruct x2", x2 -x1 = "SConscript3 x1" -x2 = "SConscript3 x2" - -x5 = SConscript('SConscript31', "x1") -Import("x6") -assert x5 == "SConscript31 x5", x5 -assert x6 == "SConscript31 x6", x6 - -Export("x1 x2") -""") - - -test.write('SConscript31', """\ -Import("x1 x2") -assert x1 == "SConscript3 x1", x1 -assert x2 == "SConstruct x2", x2 -x5 = "SConscript31 x5" -x6 = "SConscript31 x6" -Export("x6") -Return("x5") -""") - - -test.write('SConscript4', """\ -Import("x1", "x2") -assert x1 == "SConstruct x1", x1 -assert x2 == "SConstruct x2", x2 -x1 = "SConscript4 x1" -x2 = "SConscript4 x2" -Export("x1", "x2") -""") - - -test.subdir('subdir') -test.write(['subdir', 'SConscript'], """\ -foo = 'subdir/SConscript foo' -Return('foo') -""") - - -test.write('SConscript5', """\ -B = Builder(action = 'B') -def scan(): - pass -S = Scanner(function = scan) -A = Action("A") -""") - - -test.write('SConscript6', """\ -Import("x7 x8") -assert x7 == "SConstruct x7", x7 -assert x8 == "SConstruct x8", x8 -x9 = "SConscript6 x9" -Return("x9") -""") - - -test.write('SConscript7', """\ -result1 = ((1, 3), -4) -result2 = ((2, 3), -4) -assert result1 == SConscript(Split('foo/SConscript bar/SConscript')) -assert result1 == SConscript(['foo/SConscript', 'bar/SConscript']) -assert result1 == SConscript([File('foo/SConscript'), File('bar/SConscript')]) -assert result1 == SConscript(dirs = Split('foo bar')) -assert result1 == SConscript(dirs = ['foo', 'bar']) -assert result2 == SConscript(dirs = Split('foo bar'), name = 'subscript') -assert result2 == SConscript(dirs = ['foo', 'bar'], name = 'subscript') -assert result1 == SConscript(dirs = ['foo', Dir('bar')]) -assert result2 == SConscript(dirs = [Dir('foo'), 'bar'], name = 'subscript') -assert 5 == SConscript('w s/SConscript') -assert (-4, 5) == SConscript(['bar/SConscript', 'w s/SConscript']) - -x1 = 3 -x2 = 2 -assert (3, 2) == SConscript(dirs = 'baz', exports = "x1 x2") -assert (3, 2) == SConscript('baz/SConscript', 'x1', exports = 'x2') -assert (3, 2) == SConscript('baz/SConscript', exports = 'x1 x2') -""") - -fooscript = "x = %d; y = 3; Return('x y')\n" -barscript = "x = -4; Return('x')\n" - -test.subdir('foo', 'bar', 'baz', 'w s') -test.write(['foo', 'SConscript'], fooscript % 1) -test.write(['foo', 'subscript'], fooscript % 2) -test.write(['bar', 'SConscript'], barscript) -test.write(['bar', 'subscript'], barscript) -test.write(['baz', 'SConscript'], """\ -Import("x1 x2") -result = (x1, x2) -Return("result") -""") -test.write(['w s', 'SConscript'], "x = 5; Return('x')\n") - - -wpath = test.workpath() - -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/SConscript.py b/test/SConscript/SConscript.py new file mode 100644 index 0000000..268c48e --- /dev/null +++ b/test/SConscript/SConscript.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('foo.py', "foo = 4\n") + + +test.write('SConstruct', """\ +import os +import foo + +assert foo.foo == 4 + +print "SConstruct", os.getcwd() +SConscript('SConscript') + +x1 = "SConstruct x1" +x2 = "SConstruct x2" +x3,x4 = SConscript('SConscript1', "x1 x2") +assert x3 == "SConscript1 x3", x3 +assert x4 == "SConscript1 x4", x4 + +(x3,x4) = SConscript('SConscript2', ["x1","x2"]) +assert x3 == "SConscript2 x3", x3 +assert x4 == "SConscript2 x4", x4 + +Export("x1 x2") +SConscript('SConscript3') +Import("x1 x2") +assert x1 == "SConscript3 x1", x1 +assert x2 == "SConscript3 x2", x2 + +x1 = "SConstruct x1" +x2 = "SConstruct x2" +Export("x1","x2") +SConscript('SConscript4') +Import("x1"," x2") +assert x1 == "SConscript4 x1", x1 +assert x2 == "SConscript4 x2", x2 + +subdir = Dir('subdir') +script = File('SConscript', subdir) +foo = SConscript(script) +assert foo == "subdir/SConscript foo" + +SConscript('SConscript5') + +import UserList +x7 = "SConstruct x7" +x8 = "SConstruct x8" +x9 = SConscript('SConscript6', UserList.UserList(["x7", "x8"])) +assert x9 == "SConscript6 x9", x9 + +SConscript('SConscript7') +""") + + +test.write('SConscript', """\ +# os should not be automajically imported: +assert not globals().has_key("os") + +import os +print "SConscript " + os.getcwd() +""") + +test.write('SConscript1', """ +Import("x1 x2") +assert x1 == "SConstruct x1", x1 +assert x2 == "SConstruct x2", x2 + +x3 = "SConscript1 x3" +x4 = "SConscript1 x4" +Return("x3 x4") +""") + + +test.write('SConscript2', """\ +Import("x1","x2") +assert x1 == "SConstruct x1", x1 +assert x2 == "SConstruct x2", x2 +x3 = "SConscript2 x3" +x4 = "SConscript2 x4" +Return("x3","x4") +""") + + +test.write('SConscript3', """\ +Import("x1 x2") +assert x1 == "SConstruct x1", x1 +assert x2 == "SConstruct x2", x2 +x1 = "SConscript3 x1" +x2 = "SConscript3 x2" + +x5 = SConscript('SConscript31', "x1") +Import("x6") +assert x5 == "SConscript31 x5", x5 +assert x6 == "SConscript31 x6", x6 + +Export("x1 x2") +""") + + +test.write('SConscript31', """\ +Import("x1 x2") +assert x1 == "SConscript3 x1", x1 +assert x2 == "SConstruct x2", x2 +x5 = "SConscript31 x5" +x6 = "SConscript31 x6" +Export("x6") +Return("x5") +""") + + +test.write('SConscript4', """\ +Import("x1", "x2") +assert x1 == "SConstruct x1", x1 +assert x2 == "SConstruct x2", x2 +x1 = "SConscript4 x1" +x2 = "SConscript4 x2" +Export("x1", "x2") +""") + + +test.subdir('subdir') +test.write(['subdir', 'SConscript'], """\ +foo = 'subdir/SConscript foo' +Return('foo') +""") + + +test.write('SConscript5', """\ +B = Builder(action = 'B') +def scan(): + pass +S = Scanner(function = scan) +A = Action("A") +""") + + +test.write('SConscript6', """\ +Import("x7 x8") +assert x7 == "SConstruct x7", x7 +assert x8 == "SConstruct x8", x8 +x9 = "SConscript6 x9" +Return("x9") +""") + + +test.write('SConscript7', """\ +result1 = ((1, 3), -4) +result2 = ((2, 3), -4) +assert result1 == SConscript(Split('foo/SConscript bar/SConscript')) +assert result1 == SConscript(['foo/SConscript', 'bar/SConscript']) +assert result1 == SConscript([File('foo/SConscript'), File('bar/SConscript')]) +assert result1 == SConscript(dirs = Split('foo bar')) +assert result1 == SConscript(dirs = ['foo', 'bar']) +assert result2 == SConscript(dirs = Split('foo bar'), name = 'subscript') +assert result2 == SConscript(dirs = ['foo', 'bar'], name = 'subscript') +assert result1 == SConscript(dirs = ['foo', Dir('bar')]) +assert result2 == SConscript(dirs = [Dir('foo'), 'bar'], name = 'subscript') +assert 5 == SConscript('w s/SConscript') +assert (-4, 5) == SConscript(['bar/SConscript', 'w s/SConscript']) + +x1 = 3 +x2 = 2 +assert (3, 2) == SConscript(dirs = 'baz', exports = "x1 x2") +assert (3, 2) == SConscript('baz/SConscript', 'x1', exports = 'x2') +assert (3, 2) == SConscript('baz/SConscript', exports = 'x1 x2') +""") + +fooscript = "x = %d; y = 3; Return('x y')\n" +barscript = "x = -4; Return('x')\n" + +test.subdir('foo', 'bar', 'baz', 'w s') +test.write(['foo', 'SConscript'], fooscript % 1) +test.write(['foo', 'subscript'], fooscript % 2) +test.write(['bar', 'SConscript'], barscript) +test.write(['bar', 'subscript'], barscript) +test.write(['baz', 'SConscript'], """\ +Import("x1 x2") +result = (x1, x2) +Return("result") +""") +test.write(['w s', 'SConscript'], "x = 5; Return('x')\n") + + +wpath = test.workpath() + +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.pass_test() diff --git a/test/SConscript/SConscriptChdir.py b/test/SConscript/SConscriptChdir.py new file mode 100644 index 0000000..3763378 --- /dev/null +++ b/test/SConscript/SConscriptChdir.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('dir1', 'dir2', 'dir3', 'dir4', 'dir5') + +test.write('SConstruct', """ +env = Environment() +SConscript('dir1/SConscript') +SConscriptChdir(1) +SConscript('dir2/SConscript') +SConscriptChdir(0) +SConscript('dir3/SConscript') +env.SConscriptChdir(1) +SConscript('dir4/SConscript') +env.SConscriptChdir(0) +SConscript('dir5/SConscript') +""") + +test.write(['dir1', 'SConscript'], """ +execfile("create_test.py") +""") + +test.write(['dir2', 'SConscript'], """ +execfile("create_test.py") +""") + +test.write(['dir3', 'SConscript'], """ +import os.path +name = os.path.join('dir3', 'create_test.py') +execfile(name) +""") + +test.write(['dir4', 'SConscript'], """ +execfile("create_test.py") +""") + +test.write(['dir5', 'SConscript'], """ +import os.path +name = os.path.join('dir5', 'create_test.py') +execfile(name) +""") + +for dir in ['dir1', 'dir2', 'dir3','dir4', 'dir5']: + test.write([dir, 'create_test.py'], r""" +f = open("test.txt", "ab") +f.write("This is the %s test.\n") +f.close() +""" % dir) + +test.run(arguments=".", stderr=None) + +test.fail_test(test.read(['dir1', 'test.txt']) != "This is the dir1 test.\n") +test.fail_test(test.read(['dir2', 'test.txt']) != "This is the dir2 test.\n") +test.fail_test(test.read('test.txt') != "This is the dir3 test.\nThis is the dir5 test.\n") +test.fail_test(test.read(['dir4', 'test.txt']) != "This is the dir4 test.\n") + +test.pass_test() diff --git a/test/SConscript/env.py b/test/SConscript/env.py new file mode 100644 index 0000000..0ad0561 --- /dev/null +++ b/test/SConscript/env.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test calling SConscript through a construction environment. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('sub1', 'sub2') + +test.write("SConstruct", """\ +env = Environment(SUB1='sub1', SUB2='sub2') +print "SConstruct" +x = 'xxx' +y = 'yyy' +env.Export(["x", "y"]) +env.SConscript('$SUB1/SConscript') +env.SConscript(dirs=['$SUB2']) +SConscript(['s1', 's2']) +env.SConscript(['s3', 's4']) +""") + +test.write(['sub1', 'SConscript'], """\ +env = Environment() +env.Import("x") +print "sub1/SConscript" +print "x =", x +""") + +test.write(['sub2', 'SConscript'], """\ +env = Environment() +env.Import("y") +print "sub2/SConscript" +print "y =", y +""") + +test.write('s1', "\n") +test.write('s2', "\n") +test.write('s3', "\n") +test.write('s4', "\n") + +expect = """\ +SConstruct +sub1/SConscript +x = xxx +sub2/SConscript +y = yyy +""" + +test.run(arguments = ".", + stdout = test.wrap_stdout(read_str = expect, + build_str = "scons: `.' is up to date.\n")) + +test.write("SConstruct", """\ +def builder(target, source, env): + import SCons.Script.SConscript + assert SCons.Script.SConscript.sconscript_reading == 0 +env = Environment(BUILDERS={'builder':Builder(action=builder)}) +env.builder('test',[]) +import SCons.Script.SConscript +assert SCons.Script.SConscript.sconscript_reading == 1 +""") + +test.pass_test() diff --git a/test/SConscript/src_dir.py b/test/SConscript/src_dir.py new file mode 100644 index 0000000..f18066b --- /dev/null +++ b/test/SConscript/src_dir.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the SConscript() src_dir argument. + +Test case contributed by Dobes Vandermeer. +""" + +import TestSCons + +_exe = TestSCons._exe + +test = TestSCons.TestSCons() + +test.subdir(['build'], + ['samples'], + ['src']) + +test.write(['SConstruct'], """\ +env = Environment() + +for src_dir in ['src','samples']: + SConscript('build/glob_build.py', + src_dir=src_dir, + build_dir='build/output/'+src_dir, + duplicate=0, + exports=['env']) +""") + +test.write(['build', 'glob_build.py'], """\ +from glob import glob +from os.path import join +from os.path import basename +Import('env') + +sources = map(basename, glob(join(str(env.Dir('.').srcnode()),'*.c'))) + +# Trivial example; really I read the configuration file +# their build system uses to generate the vcproj files +for source in sources: + env.Program(source) +""") + +test.write(['samples', 'goodbye.c'], """\ +#include + +int main(int argc, char *argv[]) +{ + printf("Goodbye, world!\\n"); + exit(0); +} +""") + +test.write(['src', 'hello.c'], """\ +#include + +int main(int argc, char *argv[]) +{ + printf("Hello, world!\\n"); + exit(0); +} +""") + +test.run() + +goodbye = test.workpath('build', 'output', 'samples', 'goodbye') +hello = test.workpath('build', 'output', 'src', 'hello') + +test.run(program = goodbye, stdout = "Goodbye, world!\n") + +test.run(program = hello, stdout = "Hello, world!\n") + +test.pass_test() diff --git a/test/SConscript/variables.py b/test/SConscript/variables.py new file mode 100644 index 0000000..34f52a0 --- /dev/null +++ b/test/SConscript/variables.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test importing and exporting variables between SConscript files. +""" + +import TestSCons + +test = TestSCons.TestSCons() + + +# Test exporting all global variables as a list of keys: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +Export(globals().keys()) +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test exporting all global variables as a list of keys in SConscript call: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +SConscript('SConscript', globals().keys()) +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test exporting all global variables as a dictionary: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +Export(globals()) +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test exporting all global variables as dictionary in SConscript call: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +SConscript('SConscript', globals()) +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test export of local variables: +test.write("SConstruct", """ +def f(): + x = 'x' + y = 'zoom' + Export('x', 'y') + +f() +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test export of local variables in SConscript call: +test.write("SConstruct", """ +def f(): + x = 'x' + y = 'zoom' + SConscript('SConscript', ['x', 'y']) +f() +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test export of local variables as a dictionary: +test.write("SConstruct", """ +def f(): + x = 'x' + y = 'zoom' + Export(locals()) + +f() +SConscript('SConscript') +""") + +test.write("SConscript", """ +Import(['x', 'y']) +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +# Test importing all variables: +test.write("SConstruct", """ +x = 'x' +y = 'zoom' +Export('x') +SConscript('SConscript', 'y') +""") + +test.write("SConscript", """ +Import('*') +assert x == 'x' +assert y == 'zoom' +""") + +test.run(arguments = ".") + +test.pass_test() diff --git a/test/SConscript/white-space.py b/test/SConscript/white-space.py new file mode 100644 index 0000000..87eb701 --- /dev/null +++ b/test/SConscript/white-space.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test handling of white space in an SConscript path name. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('white space') +test.write("SConstruct", """\ +SConscript('white space/SConscript') +""") + +test.write(['white space', 'SConscript'], """\ +print "`white space/SConscript'" +""") + +expect = test.wrap_stdout(read_str = "`white space/SConscript'\n", + build_str = "scons: `.' is up to date.\n") + +test.run(arguments = ".", stdout = expect) + + +test.pass_test() diff --git a/test/SConsignFile.py b/test/SConsignFile.py index 46d0954..e2b8053 100644 --- a/test/SConsignFile.py +++ b/test/SConsignFile.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,13 +45,13 @@ file.close() # test.write(['work1', 'SConstruct'], """ SConsignFile() -B = Builder(action = "%s ../build.py $TARGETS $SOURCES") +B = Builder(action = '%(_python_)s ../build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'subdir/f3.out', source = 'subdir/f3.in') env.B(target = 'subdir/f4.out', source = 'subdir/f4.in') -""" % python) +""" % locals()) test.write(['work1', 'f1.in'], "work1/f1.in\n") test.write(['work1', 'f2.in'], "work1/f2.in\n") @@ -79,13 +79,13 @@ test.must_not_exist(test.workpath('work1', 'subdir', '.sconsign')) test.write(['work2', 'SConstruct'], """ e = Environment(XXX = 'scons') e.SConsignFile('my_${XXX}ign') -B = Builder(action = "%s ../build.py $TARGETS $SOURCES") +B = Builder(action = '%(_python_)s ../build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f5.out', source = 'f5.in') env.B(target = 'f6.out', source = 'f6.in') env.B(target = 'subdir/f7.out', source = 'subdir/f7.in') env.B(target = 'subdir/f8.out', source = 'subdir/f8.in') -""" % python) +""" % locals()) test.write(['work2', 'f5.in'], "work2/f5.in\n") test.write(['work2', 'f6.in'], "work2/f6.in\n") diff --git a/test/SHELL.py b/test/SHELL.py index 7dda321..915dbce 100644 --- a/test/SHELL.py +++ b/test/SHELL.py @@ -35,6 +35,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -68,7 +69,8 @@ os.chmod(my_shell, 0755) test.write('SConstruct', """\ env = Environment(SHELL = r'%(my_shell)s') -env.Command('file.out', 'file.in', "%(python)s fake_cat_program $TARGET $SOURCES") +env.Command('file.out', 'file.in', + 'r%(_python_)s fake_cat_program $TARGET $SOURCES') """ % locals()) test.write('file.in', "file.in\n") diff --git a/test/SHLIBPREFIX.py b/test/SHLIBPREFIX.py index 352f217..87b92fa 100644 --- a/test/SHLIBPREFIX.py +++ b/test/SHLIBPREFIX.py @@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c') """) test.write('foo.c', r""" +#include void foo(void) { diff --git a/test/SHLIBSUFFIX.py b/test/SHLIBSUFFIX.py index 94c2984..dc88e3b 100644 --- a/test/SHLIBSUFFIX.py +++ b/test/SHLIBSUFFIX.py @@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c') """) test.write('foo.c', r""" +#include void foo(void) { diff --git a/test/SPAWN.py b/test/SPAWN.py index e6eb65e..f73ab11 100644 --- a/test/SPAWN.py +++ b/test/SPAWN.py @@ -30,7 +30,7 @@ Test the SPAWN construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,10 +45,14 @@ ofp.close() test.write('SConstruct', """ import os import string +import sys def my_spawn(sh, escape, cmd, args, env): - os.system(string.join(args + ['extra.txt'])) + s = string.join(args + ['extra.txt']) + if sys.platform in ['win32']: + s = '"' + s + '"' + os.system(s) env = Environment(SPAWN = my_spawn) -env.Command('file.out', 'file.in', "%(python)s cat.py $TARGET $SOURCES") +env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES') env = Environment() """ % locals()) diff --git a/test/SWIG/SWIG.py b/test/SWIG/SWIG.py index 65ecf2b..0fb1da4 100644 --- a/test/SWIG/SWIG.py +++ b/test/SWIG/SWIG.py @@ -35,8 +35,10 @@ if sys.platform =='darwin': # so we link to a framework version. However, testing must also # use the same version, or else you get interpreter errors. python = "/System/Library/Frameworks/Python.framework/Versions/Current/bin/python" + _python_ = '"' + python + '"' else: python = TestSCons.python + _python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj @@ -68,11 +70,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(tools=['default', 'swig'], SWIG = r'%s myswig.py') +env = Environment(tools=['default', 'swig'], SWIG = r'%(_python_)s myswig.py') env.Program(target = 'test1', source = 'test1.i') env.CFile(target = 'test2', source = 'test2.i') env.Copy(SWIGFLAGS = '-c++').Program(target = 'test3', source = 'test3.i') -""" % (python)) +""" % locals()) test.write('test1.i', r""" int @@ -143,14 +145,13 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', - SHCCFLAGS='', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', ) swig = foo.Dictionary('SWIG') -bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig) +bar = foo.Copy(SWIG = r'%(_python_)s wrapper.py ' + swig) foo.LoadableModule(target = 'foo', source = ['foo.c', 'foo.i']) bar.LoadableModule(target = 'bar', source = ['bar.c', 'bar.i']) """ % locals()) @@ -226,7 +227,6 @@ This is bar.c! test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', - SHCCFLAGS='', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', @@ -252,14 +252,13 @@ foo.LoadableModule(target = 'modulename', source = ['module.i']) test.write('SConstruct', """ foo = Environment(SWIGFLAGS='-python', CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/', - SHCCFLAGS='', LDMODULEPREFIX='%(ldmodule_prefix)s', LDMODULESUFFIX='%(_dll)s', FRAMEWORKSFLAGS='%(frameworks)s', ) swig = foo.Dictionary('SWIG') -bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig) +bar = foo.Copy(SWIG = r'%(_python_)s wrapper.py ' + swig) foo.CFile(target = 'dependent', source = ['dependent.i']) """ % locals()) diff --git a/test/SWIG/SWIGCOM.py b/test/SWIG/SWIGCOM.py index 22e217a..20d2d5d 100644 --- a/test/SWIG/SWIGCOM.py +++ b/test/SWIG/SWIGCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $SWIGCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'swig'], - SWIGCOM = r'%s myswig.py $TARGET $SOURCES') + SWIGCOM = r'%(_python_)s myswig.py $TARGET $SOURCES') env.CFile(target = 'aaa', source = 'aaa.i') env.CXXFile(target = 'bbb', source = 'bbb.i', SWIGFLAGS='-c++') -""" % python) +""" % locals()) test.write('aaa.i', "aaa.i\n/*swig*/\n") test.write('bbb.i', "bbb.i\n/*swig*/\n") diff --git a/test/SWIG/SWIGCOMSTR.py b/test/SWIG/SWIGCOMSTR.py index 3ffcdbf..b991d77 100644 --- a/test/SWIG/SWIGCOMSTR.py +++ b/test/SWIG/SWIGCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when swig is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'swig'], - SWIGCOM = r'%s myswig.py $TARGET $SOURCES', + SWIGCOM = r'%(_python_)s myswig.py $TARGET $SOURCES', SWIGCOMSTR = 'Swigging $TARGET from $SOURCE') env.CFile(target = 'aaa', source = 'aaa.i') env.CXXFile(target = 'bbb', source = 'bbb.i', SWIGFLAGS='-c++') -""" % python) +""" % locals()) test.write('aaa.i', "aaa.i\n/*swig*/\n") test.write('bbb.i', "bbb.i\n/*swig*/\n") diff --git a/test/Scanner-exception.py b/test/Scanner-exception.py deleted file mode 100644 index 7615888..0000000 --- a/test/Scanner-exception.py +++ /dev/null @@ -1,115 +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__" - -import string -import sys -import TestSCons - -python = TestSCons.python - -test = TestSCons.TestSCons() - -# Execute a subsidiary SConscript just to make sure we can -# get at the SCanners keyword from there. - -test.write('SConstruct', """ -SConscript('SConscript') -""") - -test.write('SConscript', """ -import re - -include_re = re.compile(r'^include\s+(\S+)$', re.M) -exception_re = re.compile(r'^exception\s+(.+)$', re.M) - -def kfile_scan(node, env, target, arg): - contents = node.get_contents() - exceptions = exception_re.findall(contents) - if exceptions: - raise "kfile_scan error: %s" % exceptions[0] - includes = include_re.findall(contents) - return includes - -kscan = Scanner(name = 'kfile', - function = kfile_scan, - argument = None, - recursive = 1, - skeys = ['.k']) - -def process(outf, inf): - for line in inf.readlines(): - if line[:8] == 'include ': - file = line[8:-1] - process(outf, open(file, 'rb')) - else: - outf.write(line) - -def cat(env, source, target): - target = str(target[0]) - source = map(str, source) - - outf = open(target, 'wb') - for src in source: - process(outf, open(src, 'rb')) - outf.close() - -env = Environment(BUILDERS={'Cat':Builder(action=cat)}) -env.Append(SCANNERS = [kscan]) - -env.Cat('foo', 'foo.k') - -bar_in = File('bar.in') -env.Cat('bar', bar_in) -bar_in.source_scanner = kscan -""") - -test.write('foo.k', -"""foo.k 1 line 1 -include xxx -include yyy -foo.k 1 line 4 -""") - -test.write('bar.in', -"""include yyy -bar.in 1 line 2 -bar.in 1 line 3 -include zzz -""") - -test.write('xxx', "xxx 1\n") - -test.write('yyy', "exception yyy 1\n") - -test.write('zzz', "zzz 1\n") - -test.run(arguments = '.', - status = 2, - stderr = """\ -scons: *** kfile_scan error: yyy 1 -""") - -test.pass_test() diff --git a/test/Scanner.py b/test/Scanner.py deleted file mode 100644 index 6e64c03..0000000 --- a/test/Scanner.py +++ /dev/null @@ -1,315 +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__" - -import sys -import TestSCons - -python = TestSCons.python - -test = TestSCons.TestSCons() - -test.write('build.py', r""" -import sys -input = open(sys.argv[1], 'rb') -output = open(sys.argv[2], 'wb') - -def process(infp, outfp): - for line in infp.readlines(): - if line[:8] == 'include ': - file = line[8:-1] - process(open(file, 'rb'), outfp) - elif line[:8] == 'getfile ': - outfp.write('include ') - outfp.write(line[8:]) - # note: converted, but not acted upon - else: - outfp.write(line) - -process(input, output) - -sys.exit(0) -""") - -# Execute a subsidiary SConscript just to make sure we can -# get at the Scanner keyword from there. - -test.write('SConstruct', """ -SConscript('SConscript') -""") - -test.write('SConscript', """ -import re - -include_re = re.compile(r'^include\s+(\S+)$', re.M) - -def kfile_scan(node, env, scanpaths, arg): - contents = node.get_contents() - includes = include_re.findall(contents) - return includes - -kscan = Scanner(name = 'kfile', - function = kfile_scan, - argument = None, - skeys = ['.k']) - -env = Environment(K2SCAN=kfile_scan) - -k2scan = env.Scanner(name = 'k2', - # We'd like to do the following, but it will take - # some major surgery to subst() and subst_list(), - # so comment it out for now. - # function = '$K2SCAN', - function = kfile_scan, - argument = None, - skeys = ['.k2']) - -########################################################## -# Test scanner as found automatically from the environment -# (backup_source_scanner) - -env = Environment() -env.Append(SCANNERS = kscan) - -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') - -########################################################## -# Test specifying a specific source scanner for a target Node - -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') - -########################################################## -# Test specifying a source scanner for a Builder that gets -# automatically applied to targets generated from that Builder - -import string - -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', - src_suffix='.lork', - suffix='.blork', - source_scanner=kscan) -blorkbld = Builder(action=blork, - src_suffix='.blork', - suffix='.ork') - -env.Append(BUILDERS={'BLORK':blorkbld, 'KB':kbld}) - -blork = env.KB('moo.lork') -ork = env.BLORK(blork) -Alias('make_ork', ork) - -""" % {'python': python}) - -test.write('foo.k', -"""foo.k 1 line 1 -include xxx -include yyy -foo.k 1 line 4 -""") - -test.write('bar.in', -"""include yyy -bar.in 1 line 2 -bar.in 1 line 3 -include zzz -""") - -test.write('junk.k2', -"""include yyy -junk.k2 1 line 2 -junk.k2 1 line 3 -include zzz -""") - -test.write('moo.lork', -"""include xxx -moo.lork 1 line 2 -include yyy -moo.lork 1 line 4 -include moo.inc -""") - -test.write('moo.inc', -"""getfile zzz -""") - -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 -blork(["moo.ork"], ["moo.blork"]) -""" % {'python':python})) - -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") -test.must_match('junk', "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") -test.must_match('moo.ork', "xxx 1\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\ninclude zzz\n") - -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 -blork(["moo.ork"], ["moo.blork"]) -""" % {'python':python})) - -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") -test.must_match('junk', "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") -test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\ninclude zzz\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 -blork(["moo.ork"], ["moo.blork"]) -""" % {'python':python})) - -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") -test.must_match('junk', "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") -test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\ninclude zzz\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})) - -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") -test.must_match('junk', "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 2\n") -test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\ninclude zzz\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/Scanner.py b/test/Scanner/Scanner.py new file mode 100644 index 0000000..09c5680 --- /dev/null +++ b/test/Scanner/Scanner.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('build.py', r""" +import sys +input = open(sys.argv[1], 'rb') +output = open(sys.argv[2], 'wb') + +def process(infp, outfp): + for line in infp.readlines(): + if line[:8] == 'include ': + file = line[8:-1] + process(open(file, 'rb'), outfp) + elif line[:8] == 'getfile ': + outfp.write('include ') + outfp.write(line[8:]) + # note: converted, but not acted upon + else: + outfp.write(line) + +process(input, output) + +sys.exit(0) +""") + +# Execute a subsidiary SConscript just to make sure we can +# get at the Scanner keyword from there. + +test.write('SConstruct', """ +SConscript('SConscript') +""") + +test.write('SConscript', """ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) + +def kfile_scan(node, env, scanpaths, arg): + contents = node.get_contents() + includes = include_re.findall(contents) + return includes + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + skeys = ['.k']) + +env = Environment(K2SCAN=kfile_scan) + +k2scan = env.Scanner(name = 'k2', + # We'd like to do the following, but it will take + # some major surgery to subst() and subst_list(), + # so comment it out for now. + # function = '$K2SCAN', + function = kfile_scan, + argument = None, + skeys = ['.k2']) + +########################################################## +# Test scanner as found automatically from the environment +# (backup_source_scanner) + +env = Environment() +env.Append(SCANNERS = kscan) + +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') + +########################################################## +# Test specifying a specific source scanner for a target Node + +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') + +########################################################## +# Test specifying a source scanner for a Builder that gets +# automatically applied to targets generated from that Builder + +import string + +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', + src_suffix='.lork', + suffix='.blork', + source_scanner=kscan) +blorkbld = Builder(action=blork, + src_suffix='.blork', + suffix='.ork') + +env.Append(BUILDERS={'BLORK':blorkbld, 'KB':kbld}) + +blork = env.KB('moo.lork') +ork = env.BLORK(blork) +Alias('make_ork', ork) + +""" % locals()) + +test.write('foo.k', +"""foo.k 1 line 1 +include xxx +include yyy +foo.k 1 line 4 +""") + +test.write('bar.in', +"""include yyy +bar.in 1 line 2 +bar.in 1 line 3 +include zzz +""") + +test.write('junk.k2', +"""include yyy +junk.k2 1 line 2 +junk.k2 1 line 3 +include zzz +""") + +test.write('moo.lork', +"""include xxx +moo.lork 1 line 2 +include yyy +moo.lork 1 line 4 +include moo.inc +""") + +test.write('moo.inc', +"""getfile zzz +""") + +test.write('xxx', "xxx 1\n") +test.write('yyy', "yyy 1\n") +test.write('zzz', "zzz 1\n") + +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"]) +""" % 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") +test.must_match('junk', "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") +test.must_match('moo.ork', "xxx 1\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\ninclude zzz\n") + +test.up_to_date(arguments = '.') + +test.write('xxx', "xxx 2\n") + +expect = test.wrap_stdout("""\ +%(_python_)s build.py foo.k foo +%(_python_)s build.py moo.lork moo.blork +blork(["moo.ork"], ["moo.blork"]) +""" % 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") +test.must_match('junk', "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") +test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\ninclude zzz\n") + +test.write('yyy', "yyy 2\n") + +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"]) +""" % 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") +test.must_match('junk', "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n") +test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\ninclude zzz\n") + +test.write('zzz', "zzz 2\n") + +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") +test.must_match('junk', "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 2\n") +test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\ninclude zzz\n") + +test.up_to_date(arguments = 'foo') + +test.pass_test() diff --git a/test/Scanner/empty-implicit.py b/test/Scanner/empty-implicit.py new file mode 100644 index 0000000..2112fd8 --- /dev/null +++ b/test/Scanner/empty-implicit.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that Scanners are not called if a previous --implicit-cache +run stored an empty list of implicit dependencies. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', r""" +import os.path + +def scan(node, env, envkey, arg): + print 'XScanner: node =', os.path.split(str(node))[1] + return [] + +def exists_check(node, env): + return os.path.exists(str(node)) + +XScanner = Scanner(name = 'XScanner', + function = scan, + argument = None, + scan_check = exists_check, + skeys = ['.x']) + +def echo(env, target, source): + t = os.path.split(str(target[0]))[1] + s = os.path.split(str(source[0]))[1] + print 'create %s from %s' % (t, s) + open(t, 'wb').write(open(s, 'rb').read()) + +Echo = Builder(action = Action(echo, None), + src_suffix = '.x', + suffix = '.x') + +env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner]) + +f1 = env.Echo(source=['f1_in'], target=['f1_out']) +""") + +test.write('f1_in.x', 'f1_in.x\n') + +expect = test.wrap_stdout("""\ +XScanner: node = f1_in.x +create f1_out.x from f1_in.x +""") + +test.run(arguments = '--implicit-cache .', stdout = expect) + +# Run it again, and the output must contain only the "up to date" message, +# *not* the line printed by the XScanner function. + +test.up_to_date(options = '--implicit-cache', arguments = '.') + +test.pass_test() diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py new file mode 100644 index 0000000..7615888 --- /dev/null +++ b/test/Scanner/exception.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import string +import sys +import TestSCons + +python = TestSCons.python + +test = TestSCons.TestSCons() + +# Execute a subsidiary SConscript just to make sure we can +# get at the SCanners keyword from there. + +test.write('SConstruct', """ +SConscript('SConscript') +""") + +test.write('SConscript', """ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) +exception_re = re.compile(r'^exception\s+(.+)$', re.M) + +def kfile_scan(node, env, target, arg): + contents = node.get_contents() + exceptions = exception_re.findall(contents) + if exceptions: + raise "kfile_scan error: %s" % exceptions[0] + includes = include_re.findall(contents) + return includes + +kscan = Scanner(name = 'kfile', + function = kfile_scan, + argument = None, + recursive = 1, + skeys = ['.k']) + +def process(outf, inf): + for line in inf.readlines(): + if line[:8] == 'include ': + file = line[8:-1] + process(outf, open(file, 'rb')) + else: + outf.write(line) + +def cat(env, source, target): + target = str(target[0]) + source = map(str, source) + + outf = open(target, 'wb') + for src in source: + process(outf, open(src, 'rb')) + outf.close() + +env = Environment(BUILDERS={'Cat':Builder(action=cat)}) +env.Append(SCANNERS = [kscan]) + +env.Cat('foo', 'foo.k') + +bar_in = File('bar.in') +env.Cat('bar', bar_in) +bar_in.source_scanner = kscan +""") + +test.write('foo.k', +"""foo.k 1 line 1 +include xxx +include yyy +foo.k 1 line 4 +""") + +test.write('bar.in', +"""include yyy +bar.in 1 line 2 +bar.in 1 line 3 +include zzz +""") + +test.write('xxx', "xxx 1\n") + +test.write('yyy', "exception yyy 1\n") + +test.write('zzz', "zzz 1\n") + +test.run(arguments = '.', + status = 2, + stderr = """\ +scons: *** kfile_scan error: yyy 1 +""") + +test.pass_test() diff --git a/test/Scanner/generated.py b/test/Scanner/generated.py new file mode 100644 index 0000000..36f35f6 --- /dev/null +++ b/test/Scanner/generated.py @@ -0,0 +1,427 @@ +#!/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 only scan generated .h files once. + +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 + +import TestCmd +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('reftree', + ['reftree', 'include'], + 'src', + ['src', 'lib_geng']) + +test.write('SConstruct', """\ +### +### QQQ !@#$!@#$! I need to move the SConstruct file to be "above" +### both the source and install dirs, or the install dependencies +### don't seem to work well! ARRGH!!!! +### + +experimenttop = r"%s" + +import os +import os.path +import string +import Mylib + +BStaticLibMerge = Builder(generator = Mylib.Gen_StaticLibMerge) +builders = Environment().Dictionary('BUILDERS') +builders["StaticLibMerge"] = BStaticLibMerge + +env = Environment(BUILDERS = builders) +e = env.Dictionary() # Slightly easier to type + +global_env = env +e["GlobalEnv"] = global_env + +e["REF_INCLUDE"] = os.path.join(experimenttop, "reftree", "include") +e["REF_LIB"] = os.path.join(experimenttop, "reftree", "lib") +e["EXPORT_INCLUDE"] = os.path.join(experimenttop, "export", "include") +e["EXPORT_LIB"] = os.path.join(experimenttop, "export", "lib") +e["INSTALL_BIN"] = os.path.join(experimenttop, "install", "bin") + +build_dir = os.path.join(experimenttop, "tmp-bld-dir") +src_dir = os.path.join(experimenttop, "src") + +env.Append(CPPPATH = [e["EXPORT_INCLUDE"]]) +env.Append(CPPPATH = [e["REF_INCLUDE"]]) +Mylib.AddLibDirs(env, "/via/Mylib.AddLibPath") +env.Append(LIBPATH = [e["EXPORT_LIB"]]) +env.Append(LIBPATH = [e["REF_LIB"]]) + +Mylib.Subdirs(env, "src") +""" % test.workpath()) + +test.write('Mylib.py', """\ +import os +import string +import re + +def Subdirs(env, dirlist): + for file in _subconf_list(dirlist): + env.SConscript(file, "env") + +def _subconf_list(dirlist): + return map(lambda x: os.path.join(x, "SConscript"), string.split(dirlist)) + +def StaticLibMergeMembers(local_env, libname, hackpath, files): + for file in string.split(files): + # QQQ Fix limits in grok'ed regexp + tmp = re.sub(".c$", ".o", file) + objname = re.sub(".cpp", ".o", tmp) + local_env.Object(target = objname, source = file) + e = 'local_env["GlobalEnv"].Append(%s = ["%s"])' % (libname, os.path.join(hackpath, objname)) + exec(e) + +def CreateMergedStaticLibrary(env, libname): + objpaths = env["GlobalEnv"][libname] + libname = "lib%s.a" % (libname) + env.StaticLibMerge(target = libname, source = objpaths) + +# I put the main body of the generator code here to avoid +# namespace problems +def Gen_StaticLibMerge(source, target, env, for_signature): + target_string = "" + for t in target: + target_string = str(t) + subdir = os.path.dirname(target_string) + srclist = [] + for src in source: + srclist.append(src) + return [["ar", "cq"] + target + srclist, ["ranlib"] + target] + +def StaticLibrary(env, target, source): + env.StaticLibrary(target, string.split(source)) + +def SharedLibrary(env, target, source): + env.SharedLibrary(target, string.split(source)) + +def ExportHeader(env, headers): + env.Install(dir = env["EXPORT_INCLUDE"], source = string.split(headers)) + +def ExportLib(env, libs): + env.Install(dir = env["EXPORT_LIB"], source = string.split(libs)) + +def InstallBin(env, bins): + env.Install(dir = env["INSTALL_BIN"], source = string.split(bins)) + +def Program(env, target, source): + env.Program(target, string.split(source)) + +def AddCFlags(env, str): + env.Append(CPPFLAGS = " " + str) + +# QQQ Synonym needed? +#def AddCFLAGS(env, str): +# AddCFlags(env, str) + +def AddIncludeDirs(env, str): + env.Append(CPPPATH = string.split(str)) + +def AddLibs(env, str): + env.Append(LIBS = string.split(str)) + +def AddLibDirs(env, str): + env.Append(LIBPATH = string.split(str)) + +""") + +test.write(['reftree', 'include', 'lib_a.h'], """\ +char *a_letter(void); +""") + +test.write(['reftree', 'include', 'lib_b.h'], """\ +char *b_letter(void); +""") + +test.write(['reftree', 'include', 'lib_ja.h'], """\ +char *j_letter_a(void); +""") + +test.write(['reftree', 'include', 'lib_jb.h.intentionally-moved'], """\ +char *j_letter_b(void); +""") + +test.write(['src', 'SConscript'], """\ +# --- Begin SConscript boilerplate --- +import Mylib +Import("env") + +#env = env.Copy() # Yes, clobber intentionally +#Make environment changes, such as: Mylib.AddCFlags(env, "-g -D_TEST") +#Mylib.Subdirs(env, "lib_a lib_b lib_mergej prog_x") +Mylib.Subdirs(env, "lib_geng") + +env = env.Copy() # Yes, clobber intentionally +# --- End SConscript boilerplate --- + +""") + +test.write(['src', 'lib_geng', 'SConscript'], """\ +# --- Begin SConscript boilerplate --- +import string +import sys +import Mylib +Import("env") + +#env = env.Copy() # Yes, clobber intentionally +#Make environment changes, such as: Mylib.AddCFlags(env, "-g -D_TEST") +#Mylib.Subdirs(env, "foo_dir") + +env = env.Copy() # Yes, clobber intentionally +# --- End SConscript boilerplate --- + +Mylib.AddCFlags(env, "-DGOOFY_DEMO") +Mylib.AddIncludeDirs(env, ".") + +# 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 + +# Icky code to set up process environment for "make" +# I really ought to drop this into Mylib.... + +fromdict = env.Dictionary() +todict = env["ENV"] +import SCons.Util +import re +for k in fromdict.keys(): + if k != "ENV" and k != "SCANNERS" and k != "CFLAGS" and k != "CXXFLAGS" \ + and not SCons.Util.is_Dict(fromdict[k]): + # The next line can fail on some systems because it would try to + # do env.subst on: + # $RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} ... + # When $TARGET is None, so $TARGET.attributes would throw an + # exception. + f = fromdict[k] + if SCons.Util.is_String(f) and \ + string.find(f, "TARGET") == -1 and \ + string.find(f, "SOURCE") == -1: + todict[k] = env.subst(f) +todict["CFLAGS"] = fromdict["CPPFLAGS"] + " " + \ + string.join(map(lambda x: "-I" + x, env["CPPPATH"])) + " " + \ + string.join(map(lambda x: "-L" + x, env["LIBPATH"])) +todict["CXXFLAGS"] = todict["CFLAGS"] + +generated_hdrs = "libg_gx.h libg_gy.h libg_gz.h" +static_hdrs = "libg_w.h" +#exported_hdrs = generated_hdrs + " " + static_hdrs +exported_hdrs = static_hdrs +lib_name = "g" +lib_fullname = env.subst("${LIBPREFIX}g${LIBSUFFIX}") +lib_srcs = string.split("libg_1.c libg_2.c libg_3.c") +import re +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 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(".") +#cmd_justlib = "cd %s ; make" % Dir(".") + +_ws = re.compile('\s') + +def escape(s): + if _ws.search(s): + s = '"' + s + '"' + return s + +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? +# Why? +# +# SCons bug?? + +env.Command(string.split(generated_hdrs), + ["MAKE-HEADER.py"], + cmd_generated) +recurse_env.Command([lib_fullname] + lib_objs, + lib_srcs + string.split(generated_hdrs + " " + static_hdrs), + cmd_justlib) +""") + +test.write(['src', 'lib_geng', 'MAKE-HEADER.py'], """\ +#!/usr/bin/env python + +import os +import os.path +import sys + +# chdir to the directory in which this script lives +os.chdir(os.path.split(sys.argv[0])[0]) + +for h in ['libg_gx.h', 'libg_gy.h', 'libg_gz.h']: + open(h, 'w').write('') +""") + +test.write(['src', 'lib_geng', 'SConstruct'], """\ +import os + +Scanned = {} + +def write_out(file, dict): + keys = dict.keys() + keys.sort() + f = open(file, 'wb') + for k in keys: + file = os.path.split(k)[1] + f.write(file + ": " + str(dict[k]) + "\\n") + f.close() + +orig_function = CScan.scan + +def MyCScan(node, paths, orig_function=orig_function): + deps = orig_function(node, paths) + + global Scanned + n = str(node) + try: + Scanned[n] = Scanned[n] + 1 + except KeyError: + Scanned[n] = 1 + write_out(r'%s', Scanned) + + return deps + +CScan.scan = MyCScan + +env = Environment(CPPPATH = ".") +l = env.StaticLibrary("g", Split("libg_1.c libg_2.c libg_3.c")) +Default(l) +""" % test.workpath('MyCScan.out')) + +# These were the original shell script and Makefile from SLF's original +# 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(['src', 'lib_geng', 'MAKE-HEADER.sh'], """\ +##!/bin/sh +# +#exec touch $* +#""") +# +#test.write(['src', 'lib_geng', 'Makefile'], """\ +#all: libg.a +# +#GEN_HDRS = libg_gx.h libg_gy.h libg_gz.h +#STATIC_HDRS = libg_w.h +# +#$(GEN_HDRS): generated +# +#generated: MAKE-HEADER.sh +# sh ./MAKE-HEADER.sh $(GEN_HDRS) +# +#libg.a: libg_1.o libg_2.o libg_3.o +# ar r libg.a libg_1.o libg_2.o libg_3.o +# +#libg_1.c: $(STATIC_HDRS) $(GEN_HDRS) +#libg_2.c: $(STATIC_HDRS) $(GEN_HDRS) +#libg_3.c: $(STATIC_HDRS) $(GEN_HDRS) +# +#clean: +# -rm -f $(GEN_HDRS) +# -rm -f libg.a *.o core core.* +#""") + +test.write(['src', 'lib_geng', 'libg_w.h'], """\ +""") + +test.write(['src', 'lib_geng', 'libg_1.c'], """\ +#include +#include + +int g_1() +{ + return 1; +} +""") + +test.write(['src', 'lib_geng', 'libg_2.c'], """\ +#include +#include +#include +#include + +int g_2() +{ + return 2; +} +""") + +test.write(['src', 'lib_geng', 'libg_3.c'], """\ +#include +#include + +int g_3() +{ + return 3; +} +""") + +test.run(stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) + +# XXX Note that the generated .h files still get scanned twice, +# once before they're generated and once after. That's the +# next thing to fix here. + +test.must_match("MyCScan.out", """\ +libg_1.c: 1 +libg_2.c: 1 +libg_3.c: 1 +libg_gx.h: 1 +libg_gy.h: 1 +libg_gz.h: 1 +libg_w.h: 1 +""") + +test.pass_test() diff --git a/test/Scanner/multi-env.py b/test/Scanner/multi-env.py new file mode 100644 index 0000000..514fbca --- /dev/null +++ b/test/Scanner/multi-env.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + + +""" +Verifies that using the same source file in different environments +will get the proper scanner for the environment being used. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + + +test.write('SConstruct', """ +import re + +include_re = re.compile(r'^include\s+(\S+)$', re.M) +input_re = re.compile(r'^input\s+(\S+)$', re.M) + +scan1 = Scanner(name = 'Include', + function = lambda N,E,P,A: A.findall(N.get_contents()), + argument = include_re, + skeys = ['.inp']) + +scan2 = Scanner(name = 'Input', + function = lambda N,E,P,A: A.findall(N.get_contents()), + argument = input_re, + skeys = ['.inp']) + +env1 = Environment() +env2 = Environment() + +env1.Append(SCANNERS=scan1) +env2.Append(SCANNERS=scan2) + +env1.Command('frog.1', 'frog.inp', r'%(_python_)s do_incl.py $TARGET $SOURCES') +env2.Command('frog.2', 'frog.inp', r'%(_python_)s do_inp.py $TARGET $SOURCES') + +""" % locals()) + +process = r""" +import sys + +def process(infp, outfp): + prefix = '%(command)s ' + l = len(prefix) + for line in infp.readlines(): + if line[:l] == prefix: + process(open(line[l:-1], 'rb'), outfp) + else: + outfp.write(line) + +process(open(sys.argv[2], 'rb'), + open(sys.argv[1], 'wb')) +sys.exit(0) +""" + +test.write('do_incl.py', process % { 'command' : 'include' }) +test.write('do_inp.py', process % { 'command' : 'input' }) + +test.write('frog.inp', """\ +include sound1 +input sound2 +""") + +test.write('sound1', 'croak\n') +test.write('sound2', 'ribbet\n') + +expect = test.wrap_stdout("""\ +%(_python_)s do_incl.py frog.1 frog.inp +%(_python_)s do_inp.py frog.2 frog.inp +""" % locals()) + +test.run(arguments='.', stdout=expect) + +test.must_match('frog.1', 'croak\ninput sound2\n') +test.must_match('frog.2', 'include sound1\nribbet\n') + +test.write('sound2', 'rudeep\n') + +expect = test.wrap_stdout("""\ +%(_python_)s do_inp.py frog.2 frog.inp +""" % locals()) + +test.run(arguments='.', stdout=expect) + +test.must_match('frog.1', 'croak\ninput sound2\n') +test.must_match('frog.2', 'include sound1\nrudeep\n') + +test.pass_test() diff --git a/test/Scanner/parallel-rescan.py b/test/Scanner/parallel-rescan.py new file mode 100644 index 0000000..4a1f27e --- /dev/null +++ b/test/Scanner/parallel-rescan.py @@ -0,0 +1,72 @@ +#!/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 when a source file is generated and the -j option is used, +the source file correctly gets re-scanned for implicit dependencies +after it's built. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +env = Environment() +env['BUILDERS']['COPY'] = Builder(action = Copy("$TARGET", "$SOURCE")) + +env.COPY('a.c', 'a.in') +env.COPY('b.c', 'b.in') + +env.StaticLibrary('lib', ['a.c', 'b.c']) +""") + +test.write("a.in", """\ +#include "a.h" +""") + +test.write("b.in", """\ +#include "b.h" +""") + +test.write("a.h", """\ +char *A_FILE = "b.in"; +""") + +test.write("b.h", """\ +char *B_FILE = "b.in"; +""") + +test.run(arguments = '-j4 .', + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) + +# If the dependencies weren't re-scanned properly, the .h files won't +# show up in the previous run's dependency lists, and the .o files and +# library will get rebuilt here. +test.up_to_date(arguments = '.') + +test.pass_test() diff --git a/test/Scanner/scan-once.py b/test/Scanner/scan-once.py new file mode 100644 index 0000000..7e02dd2 --- /dev/null +++ b/test/Scanner/scan-once.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that Scanners are called just once. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', r""" +import os.path + +def scan(node, env, envkey, arg): + print 'XScanner: node =', os.path.split(str(node))[1] + return [] + +def exists_check(node, env): + return os.path.exists(str(node)) + +XScanner = Scanner(name = 'XScanner', + function = scan, + argument = None, + scan_check = exists_check, + skeys = ['.x']) + +def echo(env, target, source): + t = os.path.split(str(target[0]))[1] + s = os.path.split(str(source[0]))[1] + print 'create %s from %s' % (t, s) + +Echo = Builder(action = Action(echo, None), + src_suffix = '.x', + suffix = '.x') + +env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner]) + +f1 = env.Echo(source=['file1'], target=['file2']) +f2 = env.Echo(source=['file2'], target=['file3']) +f3 = env.Echo(source=['file3'], target=['file4']) +""") + +test.write('file1.x', 'file1.x\n') + +test.run(stdout = test.wrap_stdout("""\ +XScanner: node = file1.x +create file2.x from file1.x +create file3.x from file2.x +create file4.x from file3.x +""")) + +test.write('file2.x', 'file2.x\n') + +test.run(stdout = test.wrap_stdout("""\ +XScanner: node = file1.x +XScanner: node = file2.x +create file3.x from file2.x +create file4.x from file3.x +""")) + +test.write('file3.x', 'file3.x\n') + +test.run(stdout = test.wrap_stdout("""\ +XScanner: node = file1.x +XScanner: node = file2.x +XScanner: node = file3.x +create file4.x from file3.x +""")) + +test.pass_test() diff --git a/test/SharedLibrary.py b/test/SharedLibrary.py index d9b0350..f8447ca 100644 --- a/test/SharedLibrary.py +++ b/test/SharedLibrary.py @@ -94,6 +94,8 @@ EXPORTS """) test.write('f2a.c', r""" +#include + void f2a(void) { @@ -102,6 +104,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include void f2b(void) { @@ -131,6 +134,7 @@ EXPORTS """) test.write('f3a.c', r""" +#include void f3a(void) { @@ -139,6 +143,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include void f3b(void) { @@ -168,6 +173,7 @@ EXPORTS """) test.write('prog.c', r""" +#include void f1(void); void f2a(void); void f2b(void); @@ -253,6 +259,7 @@ EXPORTS """) test.write('progbar.c', r""" +#include void f4(void); int main(int argc, char *argv[]) diff --git a/test/TAR/TAR.py b/test/TAR/TAR.py index 9d5a617..c82e227 100644 --- a/test/TAR/TAR.py +++ b/test/TAR/TAR.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,12 +60,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(tools = ['tar'], TAR = r'%s mytar.py') +env = Environment(tools = ['tar'], TAR = r'%(_python_)s mytar.py') env.Tar(target = 'aaa.tar', source = ['file1', 'file2']) env.Tar(target = 'aaa.tar', source = 'file3') env.Tar(target = 'bbb', source = 'sub1') env.Tar(target = 'bbb', source = 'file4') -""" % python) +""" % locals()) test.write('file1', "file1\n") test.write('file2', "file2\n") @@ -98,7 +98,7 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment() tar = foo.Dictionary('TAR') -bar = Environment(TAR = r'%s wrapper.py ' + tar) +bar = Environment(TAR = r'%(_python_)s wrapper.py ' + tar) f3 = Environment(TARFLAGS = '-c -z', TARSUFFIX = '.tar.gz') f4 = Environment(TARFLAGS = '-c -z', TARSUFFIX = '.tgz') f5 = Environment(TARFLAGS = '-c -z') @@ -112,7 +112,7 @@ f4.Tar(target = 'f4', source = 'file19') f4.Tar(target = 'f4', source = ['file20', 'file21']) f5.Tar(target = 'f5.tgz', source = 'file22') f5.Tar(target = 'f5.tgz', source = ['file23', 'file24']) -""" % python) +""" % locals()) for f in ['file10', 'file11', 'file12', 'file13', 'file14', 'file15', diff --git a/test/TAR/TARCOM.py b/test/TAR/TARCOM.py index f6e36e7..a39dd22 100644 --- a/test/TAR/TARCOM.py +++ b/test/TAR/TARCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['tar'], - TARCOM = r'%(python)s mytar.py $TARGET $SOURCE') + TARCOM = r'%(_python_)s mytar.py $TARGET $SOURCE') env.Tar('test1.tar', 'test1.in') """ % locals()) diff --git a/test/TAR/TARCOMSTR.py b/test/TAR/TARCOMSTR.py index 2bd3813..eee9b16 100644 --- a/test/TAR/TARCOMSTR.py +++ b/test/TAR/TARCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when tar is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['tar'], - TARCOM = r'%s mytar.py $TARGET $SOURCES', + TARCOM = r'%(_python_)s mytar.py $TARGET $SOURCES', TARCOMSTR = 'Taring $TARGET from $SOURCE') env.Tar('aaa.tar', 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*tar*/\n") diff --git a/test/TAR/TARFLAGS.py b/test/TAR/TARFLAGS.py index 2cda502..c592fe0 100644 --- a/test/TAR/TARFLAGS.py +++ b/test/TAR/TARFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -64,12 +64,14 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(tools = ['tar'], TAR = r'%s mytar.py', TARFLAGS = '-x') +env = Environment(tools = ['tar'], + TAR = r'%(_python_)s mytar.py', + TARFLAGS = '-x') env.Tar(target = 'aaa.tar', source = ['file1', 'file2']) env.Tar(target = 'aaa.tar', source = 'file3') env.Tar(target = 'bbb', source = 'sub1') env.Tar(target = 'bbb', source = 'file4') -""" % python) +""" % locals()) test.write('file1', "file1\n") test.write('file2', "file2\n") @@ -104,12 +106,12 @@ os.system(string.join(sys.argv[1:], " ")) foo = Environment() tar = foo['TAR'] bar = Environment(TAR = '', - TARFLAGS = r'%s wrapper.py ' + tar + ' -c -b 1') + TARFLAGS = r'%(_python_)s wrapper.py ' + tar + ' -c -b 1') foo.Tar(target = 'foo.tar', source = ['file10', 'file11']) foo.Tar(target = 'foo.tar', source = 'file12') bar.Tar(target = 'bar.tar', source = ['file13', 'file14']) bar.Tar(target = 'bar.tar', source = 'file15') -""" % python) +""" % locals()) test.write('file10', "file10\n") test.write('file11', "file11\n") diff --git a/test/TARGET-dir.py b/test/TARGET-dir.py index c599a16..09f20f0 100644 --- a/test/TARGET-dir.py +++ b/test/TARGET-dir.py @@ -68,6 +68,9 @@ test.write(['src', 'foo.h.in'], """\ """) test.write(['src', 'foo.c'], """\ +#include +#include + #include int diff --git a/test/TEX/LATEX.py b/test/TEX/LATEX.py index 2544696..0636109 100644 --- a/test/TEX/LATEX.py +++ b/test/TEX/LATEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,10 +59,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LATEX = r'%s mylatex.py', tools=['latex']) +env = Environment(LATEX = r'%(_python_)s mylatex.py', tools=['latex']) env.DVI(target = 'test1.dvi', source = 'test1.ltx') env.DVI(target = 'test2.dvi', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -113,14 +113,14 @@ foo = Environment(ENV = ENV) latex = foo.Dictionary('LATEX') makeindex = foo.Dictionary('MAKEINDEX') bar = Environment(ENV = ENV, - LATEX = r'%s wrapper.py ' + latex, + LATEX = r'%(_python_)s wrapper.py ' + latex, MAKEINDEX = r' wrapper.py ' + makeindex) foo.DVI(target = 'foo.dvi', source = 'foo.ltx') bar.DVI(target = 'bar', source = 'bar.latex') bar.DVI(target = 'makeindex', source = 'makeindex.tex') foo.DVI(target = 'latexi', source = 'latexi.tex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/LATEXCOM.py b/test/TEX/LATEXCOM.py index 803d26d..a5044ae 100644 --- a/test/TEX/LATEXCOM.py +++ b/test/TEX/LATEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['latex'], - LATEXCOM = r'%(python)s mylatex.py $TARGET $SOURCE') + LATEXCOM = r'%(_python_)s mylatex.py $TARGET $SOURCE') env.DVI('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/LATEXCOMSTR.py b/test/TEX/LATEXCOMSTR.py index 5e31301..08fcccb 100644 --- a/test/TEX/LATEXCOMSTR.py +++ b/test/TEX/LATEXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['latex'], - LATEXCOM = r'%(python)s mylatex.py $TARGET $SOURCE', + LATEXCOM = r'%(_python_)s mylatex.py $TARGET $SOURCE', LATEXCOMSTR = 'Building $TARGET from $SOURCE') env.DVI('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/LATEXFLAGS.py b/test/TEX/LATEXFLAGS.py index fa2348f..b887038 100644 --- a/test/TEX/LATEXFLAGS.py +++ b/test/TEX/LATEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,10 +55,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LATEX = r'%s mylatex.py', LATEXFLAGS = '-x', tools=['latex']) +env = Environment(LATEX = r'%(_python_)s mylatex.py', + LATEXFLAGS = '-x', + tools=['latex']) env.DVI(target = 'test1.dvi', source = 'test1.ltx') env.Copy(LATEXFLAGS = '-t').DVI(target = 'test2.dvi', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -92,10 +94,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, LATEXFLAGS = '--output-comment Commentary') latex = foo.Dictionary('LATEX') -bar = Environment(ENV = ENV, LATEX = r'%s wrapper.py ' + latex) +bar = Environment(ENV = ENV, LATEX = r'%(_python_)s wrapper.py ' + latex) foo.DVI(target = 'foo.dvi', source = 'foo.ltx') bar.DVI(target = 'bar', source = 'bar.latex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/PDFLATEX.py b/test/TEX/PDFLATEX.py index 015db56..e1cf00e 100644 --- a/test/TEX/PDFLATEX.py +++ b/test/TEX/PDFLATEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,10 +59,10 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFLATEX = r'%s mypdflatex.py', tools=['pdflatex']) +env = Environment(PDFLATEX = r'%(_python_)s mypdflatex.py', tools=['pdflatex']) env.PDF(target = 'test1.pdf', source = 'test1.ltx') env.PDF(target = 'test2.pdf', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -110,10 +110,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) pdflatex = foo.Dictionary('PDFLATEX') -bar = Environment(ENV = ENV, PDFLATEX = r'%s wrapper.py ' + pdflatex) +bar = Environment(ENV = ENV, PDFLATEX = r'%(_python_)s wrapper.py ' + pdflatex) foo.PDF(target = 'foo.pdf', source = 'foo.ltx') bar.PDF(target = 'bar', source = 'bar.latex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/PDFLATEXCOM.py b/test/TEX/PDFLATEXCOM.py index f46ed37..1ce2642 100644 --- a/test/TEX/PDFLATEXCOM.py +++ b/test/TEX/PDFLATEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdflatex'], - PDFLATEXCOM = r'%(python)s mypdflatex.py $TARGET $SOURCE') + PDFLATEXCOM = r'%(_python_)s mypdflatex.py $TARGET $SOURCE') env.PDF('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/PDFLATEXCOMSTR.py b/test/TEX/PDFLATEXCOMSTR.py index 94cf121..284a52a 100644 --- a/test/TEX/PDFLATEXCOMSTR.py +++ b/test/TEX/PDFLATEXCOMSTR.py @@ -35,7 +35,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdflatex'], - PDFLATEXCOM = r'%(python)s mypdflatex.py $TARGET $SOURCE', + PDFLATEXCOM = r'%(_python_)s mypdflatex.py $TARGET $SOURCE', PDFLATEXCOMSTR = 'Building $TARGET from $SOURCE') env.PDF('test1', 'test1.latex') """ % locals()) diff --git a/test/TEX/PDFLATEXFLAGS.py b/test/TEX/PDFLATEXFLAGS.py index 0b6a9fc..a3948fe 100644 --- a/test/TEX/PDFLATEXFLAGS.py +++ b/test/TEX/PDFLATEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,10 +55,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFLATEX = r'%s mypdflatex.py', PDFLATEXFLAGS = '-x', tools=['pdflatex']) +env = Environment(PDFLATEX = r'%(_python_)s mypdflatex.py', + PDFLATEXFLAGS = '-x', + tools=['pdflatex']) env.PDF(target = 'test1.pdf', source = 'test1.ltx') env.Copy(PDFLATEXFLAGS = '-t').PDF(target = 'test2.pdf', source = 'test2.latex') -""" % python) +""" % locals()) test.write('test1.ltx', r"""This is a .ltx test. \end @@ -92,10 +94,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, PDFLATEXFLAGS = '--output-comment Commentary') pdflatex = foo.Dictionary('PDFLATEX') -bar = Environment(ENV = ENV, PDFLATEX = r'%s wrapper.py ' + pdflatex) +bar = Environment(ENV = ENV, PDFLATEX = r'%(_python_)s wrapper.py ' + pdflatex) foo.PDF(target = 'foo.pdf', source = 'foo.ltx') bar.PDF(target = 'bar', source = 'bar.latex') -""" % python) +""" % locals()) latex = r""" \documentclass{letter} diff --git a/test/TEX/PDFTEX.py b/test/TEX/PDFTEX.py index 5b99c23..ad77b8a 100644 --- a/test/TEX/PDFTEX.py +++ b/test/TEX/PDFTEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFTEX = r'%s mypdftex.py', tools=['pdftex']) +env = Environment(PDFTEX = r'%(_python_)s mypdftex.py', tools=['pdftex']) env.PDF(target = 'test.pdf', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -97,10 +97,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) pdftex = foo.Dictionary('PDFTEX') -bar = Environment(ENV = ENV, PDFTEX = r'%s wrapper.py ' + pdftex) +bar = Environment(ENV = ENV, PDFTEX = r'%(_python_)s wrapper.py ' + pdftex) foo.PDF(target = 'foo.pdf', source = 'foo.tex') bar.PDF(target = 'bar', source = 'bar.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/TEX/PDFTEXCOM.py b/test/TEX/PDFTEXCOM.py index 2a7f06b..f760125 100644 --- a/test/TEX/PDFTEXCOM.py +++ b/test/TEX/PDFTEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdftex'], - PDFTEXCOM = r'%(python)s mypdftex.py $TARGET $SOURCE') + PDFTEXCOM = r'%(_python_)s mypdftex.py $TARGET $SOURCE') env.PDF('test1') """ % locals()) diff --git a/test/TEX/PDFTEXCOMSTR.py b/test/TEX/PDFTEXCOMSTR.py index dbb7b39..ac32ae1 100644 --- a/test/TEX/PDFTEXCOMSTR.py +++ b/test/TEX/PDFTEXCOMSTR.py @@ -35,7 +35,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['pdftex'], - PDFTEXCOM = r'%(python)s mypdftex.py $TARGET $SOURCE', + PDFTEXCOM = r'%(_python_)s mypdftex.py $TARGET $SOURCE', PDFTEXCOMSTR = 'Building $TARGET from $SOURCE') env.PDF('test1') """ % locals()) diff --git a/test/TEX/PDFTEXFLAGS.py b/test/TEX/PDFTEXFLAGS.py index 1a0f8df..94c5466 100644 --- a/test/TEX/PDFTEXFLAGS.py +++ b/test/TEX/PDFTEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,9 +55,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(PDFTEX = r'%s mypdftex.py', PDFTEXFLAGS = '-x', tools=['pdftex']) +env = Environment(PDFTEX = r'%(_python_)s mypdftex.py', + PDFTEXFLAGS = '-x', + tools=['pdftex']) env.PDF(target = 'test.pdf', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -85,10 +87,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, PDFTEXFLAGS = '--output-comment Commentary') pdftex = foo.Dictionary('PDFTEX') -bar = Environment(ENV = ENV, PDFTEX = r'%s wrapper.py ' + pdftex) +bar = Environment(ENV = ENV, PDFTEX = r'%(_python_)s wrapper.py ' + pdftex) foo.PDF(target = 'foo.pdf', source = 'foo.tex') bar.PDF(target = 'bar', source = 'bar.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py index 4645c7c..7ea359b 100644 --- a/test/TEX/TEX.py +++ b/test/TEX/TEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', tools=['tex']) +env = Environment(TEX = r'%(_python_)s mytex.py', tools=['tex']) env.DVI(target = 'test.dvi', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -97,14 +97,14 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) tex = foo.Dictionary('TEX') -bar = Environment(ENV = ENV, TEX = r'%s wrapper.py ' + tex) +bar = Environment(ENV = ENV, TEX = r'%(_python_)s wrapper.py ' + tex) foo.DVI(target = 'foo.dvi', source = 'foo.tex') foo.DVI(target = 'foo-latex.dvi', source = 'foo-latex.tex') bar.DVI(target = 'bar', source = 'bar.tex') bar.DVI(target = 'bar-latex', source = 'bar-latex.tex') foo.DVI('rerun.tex') foo.DVI('bibtex-test.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/TEX/TEXCOM.py b/test/TEX/TEXCOM.py index 4957427..cf887a4 100644 --- a/test/TEX/TEXCOM.py +++ b/test/TEX/TEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['tex'], - TEXCOM = r'%(python)s mytex.py $TARGET $SOURCE') + TEXCOM = r'%(_python_)s mytex.py $TARGET $SOURCE') env.DVI('test1') """ % locals()) diff --git a/test/TEX/TEXCOMSTR.py b/test/TEX/TEXCOMSTR.py index 81e7123..66c2602 100644 --- a/test/TEX/TEXCOMSTR.py +++ b/test/TEX/TEXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['tex'], - TEXCOM = r'%(python)s mytex.py $TARGET $SOURCE', + TEXCOM = r'%(_python_)s mytex.py $TARGET $SOURCE', TEXCOMSTR = 'Building $TARGET from $SOURCE') env.DVI('test1') """ % locals()) diff --git a/test/TEX/TEXFLAGS.py b/test/TEX/TEXFLAGS.py index 7bd602f..c27ffe5 100644 --- a/test/TEX/TEXFLAGS.py +++ b/test/TEX/TEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,9 +55,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(TEX = r'%s mytex.py', TEXFLAGS = '-x', tools=['tex']) +env = Environment(TEX = r'%(_python_)s mytex.py', + TEXFLAGS = '-x', + tools=['tex']) env.DVI(target = 'test.dvi', source = 'test.tex') -""" % python) +""" % locals()) test.write('test.tex', r"""This is a test. \end @@ -85,10 +87,10 @@ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV, TEXFLAGS = '--output-comment Commentary') tex = foo.Dictionary('TEX') -bar = Environment(ENV = ENV, TEX = r'%s wrapper.py ' + tex) +bar = Environment(ENV = ENV, TEX = r'%(_python_)s wrapper.py ' + tex) foo.DVI(target = 'foo.dvi', source = 'foo.tex') bar.DVI(target = 'bar', source = 'bar.tex') -""" % python) +""" % locals()) tex = r""" This is the %s TeX file. diff --git a/test/Value.py b/test/Value.py index 46f8232..85fcbd1 100644 --- a/test/Value.py +++ b/test/Value.py @@ -31,6 +31,8 @@ import sys import TestSCons import TestCmd +_python_ = TestSCons._python_ + test = TestSCons.TestSCons(match=TestCmd.match_re) # Run all of the tests with both types of source signature @@ -55,13 +57,25 @@ def create(target, source, env): env = Environment() env['BUILDERS']['B'] = Builder(action = create) -env['BUILDERS']['S'] = Builder(action = "%(python)s put $SOURCES into $TARGET") +env['BUILDERS']['S'] = Builder(action = '%(_python_)s put $SOURCES into $TARGET') env.B('f1.out', Value(P)) env.B('f2.out', env.Value(L)) env.B('f3.out', Value(C)) env.S('f4.out', Value(L)) -""" % {'source_signature':source_signature, - 'python':TestSCons.python}) + +def create_value (target, source, env): + target[0].write(source[0].get_contents ()) + +def create_value_file (target, source, env): + open(str(target[0]), 'wb').write(source[0].read()) + +env['BUILDERS']['B2'] = Builder(action = create_value) +env['BUILDERS']['B3'] = Builder(action = create_value_file) + +V = Value('my value') +env.B2(V, 'f3.out') +env.B3('f5.out', V) +""" % locals()) test.write('put', """ import os @@ -73,18 +87,25 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) test.run(arguments='-c') test.run() + out7 = """create_value(["'my value'"], ["f3.out"])""" + out8 = """create_value_file(["f5.out"], ["'my value'"])""" + out1 = """create(["f1.out"], ["'/usr/local'"])""" out2 = """create(["f2.out"], ["10"])""" out3 = """create\\(\\["f3.out"\\], \\["<.*.Custom instance at """ #" <- unconfuses emacs syntax highlighting + test.fail_test(string.find(test.stdout(), out1) == -1) test.fail_test(string.find(test.stdout(), out2) == -1) + test.fail_test(string.find(test.stdout(), out7) == -1) + test.fail_test(string.find(test.stdout(), out8) == -1) test.fail_test(re.search(out3, test.stdout()) == None) test.must_match('f1.out', "/usr/local") test.must_match('f2.out', "10") test.must_match('f3.out', "C=/usr/local") test.must_match('f4.out', '10') + test.must_match('f5.out', "C=/usr/local") test.up_to_date(arguments='.') @@ -111,6 +132,8 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) test.fail_test(string.find(test.stdout(), out4) == -1) test.fail_test(string.find(test.stdout(), out5) != -1) + test.fail_test(string.find(test.stdout(), out7) == -1) + test.fail_test(string.find(test.stdout(), out8) == -1) test.fail_test(re.search(out6, test.stdout()) == None) test.up_to_date('prefix=/var', '.') @@ -119,5 +142,6 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) test.must_match('f2.out', "4") test.must_match('f3.out', "C=/var") test.must_match('f4.out', "4") + test.must_match('f5.out', "C=/var") test.pass_test() diff --git a/test/YACC/YACC.py b/test/YACC/YACC.py index 9be1934..d3bc679 100644 --- a/test/YACC/YACC.py +++ b/test/YACC/YACC.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe if sys.platform == 'win32': @@ -64,10 +64,10 @@ sys.exit(0) test.write('SConstruct', """ -env = Environment(YACC = r'%s myyacc.py', tools=['default', 'yacc']) +env = Environment(YACC = r'%(_python_)s myyacc.py', tools=['default', 'yacc']) env.Program(target = 'aaa', source = 'aaa.y') env.Program(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', r""" int @@ -113,13 +113,13 @@ os.system(string.join(sys.argv[1:], " ")) test.write('SConstruct', """ foo = Environment(YACCFLAGS='-d') yacc = foo.Dictionary('YACC') -bar = Environment(YACC = r'%s wrapper.py ' + yacc) +bar = Environment(YACC = r'%(_python_)s wrapper.py ' + yacc) foo.Program(target = 'foo', source = 'foo.y') bar.Program(target = 'bar', source = 'bar.y') foo.Program(target = 'hello', source = ['hello.cpp']) foo.CXXFile(target = 'file.cpp', source = ['file.yy'], YACCFLAGS='-d') foo.CFile(target = 'not_foo', source = 'foo.y') -""" % python) +""" % locals()) yacc = r""" %%{ diff --git a/test/YACC/YACCCOM.py b/test/YACC/YACCCOM.py index 5f7cd38..1425eb8 100644 --- a/test/YACC/YACCCOM.py +++ b/test/YACC/YACCCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $YACCCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACCCOM = r'%s myyacc.py $TARGET $SOURCES') + YACCCOM = r'%(_python_)s myyacc.py $TARGET $SOURCES') env.CFile(target = 'aaa', source = 'aaa.y') env.CFile(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', "aaa.y\n/*yacc*/\n") test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n") diff --git a/test/YACC/YACCCOMSTR.py b/test/YACC/YACCCOMSTR.py index cfb48b7..b2c128d 100644 --- a/test/YACC/YACCCOMSTR.py +++ b/test/YACC/YACCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when yacc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACCCOM = r'%s myyacc.py $TARGET $SOURCES', + YACCCOM = r'%(_python_)s myyacc.py $TARGET $SOURCES', YACCCOMSTR = 'Yaccing $TARGET from $SOURCE') env.CFile(target = 'aaa', source = 'aaa.y') env.CFile(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', "aaa.y\n/*yacc*/\n") test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n") diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 2779597..a94bc8f 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe if sys.platform == 'win32': @@ -62,9 +62,11 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(YACC = r'%s myyacc.py', YACCFLAGS = '-x', tools=['yacc', '%s', '%s']) +env = Environment(YACC = r'%(_python_)s myyacc.py', + YACCFLAGS = '-x', + tools=['yacc', '%(linker)s', '%(compiler)s']) env.Program(target = 'aaa', source = 'aaa.y') -""" % (python, linker, compiler)) +""" % locals()) test.write('aaa.y', r""" int diff --git a/test/YACC/YACCHFILESUFFIX.py b/test/YACC/YACCHFILESUFFIX.py index 389018f..231472d 100644 --- a/test/YACC/YACCHFILESUFFIX.py +++ b/test/YACC/YACCHFILESUFFIX.py @@ -31,7 +31,7 @@ utility that writes to an odd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,12 +58,12 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACC = r'%s myyacc.py', + YACC = r'%(_python_)s myyacc.py', YACCFLAGS = '-d', YACCHFILESUFFIX = '.hsuffix') env.CFile(target = 'aaa', source = 'aaa.y') env.CFile(target = 'bbb', source = 'bbb.yacc') -""" % python) +""" % locals()) test.write('aaa.y', "aaa.y\n/*yacc*/\n") test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n") diff --git a/test/YACC/YACCHXXFILESUFFIX.py b/test/YACC/YACCHXXFILESUFFIX.py index b564d5e..182f08b 100644 --- a/test/YACC/YACCHXXFILESUFFIX.py +++ b/test/YACC/YACCHXXFILESUFFIX.py @@ -31,7 +31,7 @@ utility that writes to an odd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,11 +58,11 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'yacc'], - YACC = r'%s myyacc.py', + YACC = r'%(_python_)s myyacc.py', YACCFLAGS = '-d', YACCHXXFILESUFFIX = '.hxxsuffix') env.CXXFile(target = 'aaa', source = 'aaa.yy') -""" % python) +""" % locals()) test.write('aaa.yy', "aaa.yy\n/*yacc*/\n") diff --git a/test/ZIP/ZIP.py b/test/ZIP/ZIP.py index 33c54dd..646677d 100644 --- a/test/ZIP/ZIP.py +++ b/test/ZIP/ZIP.py @@ -31,7 +31,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -66,12 +66,12 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools = ['zip'], - ZIPCOM = r'%s myzip.py $TARGET $SOURCES') + ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCES') env.Zip(target = 'aaa.zip', source = ['file1', 'file2']) env.Zip(target = 'aaa.zip', source = 'file3') env.Zip(target = 'bbb', source = 'sub1') env.Zip(target = 'bbb', source = 'file4') -""" % python) +""" % locals()) test.write('file1', "file1\n") test.write('file2', "file2\n") diff --git a/test/ZIP/ZIPCOM.py b/test/ZIP/ZIPCOM.py index 42b8cff..460abe4 100644 --- a/test/ZIP/ZIPCOM.py +++ b/test/ZIP/ZIPCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(TOOLS = ['zip'], - ZIPCOM = r'%(python)s myzip.py $TARGET $SOURCE') + ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCE') env.Zip('test1.zip', 'test1.in') """ % locals()) diff --git a/test/ZIP/ZIPCOMSTR.py b/test/ZIP/ZIPCOMSTR.py index 0ee90fd..5284d0a 100644 --- a/test/ZIP/ZIPCOMSTR.py +++ b/test/ZIP/ZIPCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when zip is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['zip'], - ZIPCOM = r'%s myzip.py $TARGET $SOURCES', + ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCES', ZIPCOMSTR = 'Zipping $TARGET from $SOURCE') env.Zip('aaa.zip', 'aaa.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n/*zip*/\n") diff --git a/test/bad-variables.py b/test/bad-variables.py index 59fc184..cb6b357 100644 --- a/test/bad-variables.py +++ b/test/bad-variables.py @@ -33,17 +33,24 @@ import TestSCons test = TestSCons.TestSCons() -test.write('SConstruct', """\ +SConstruct_path = test.workpath('SConstruct') +SConscript_path = test.workpath('SConscript') + +test.write(SConstruct_path, """\ env = Environment() env['foo-bar'] = 1 """) -test.run(arguments = '.', status = 2, stderr=""" +expect_stderr = """ scons: *** Illegal construction variable `foo-bar' -File "SConstruct", line 2, in ? -""") +File "%(SConstruct_path)s", line 2, in ? +""" % locals() + +test.run(arguments='.', status=2, stderr=expect_stderr) + -test.write('SConstruct', """\ + +test.write(SConstruct_path, """\ SConscript('SConscript') """) @@ -52,9 +59,11 @@ env = Environment() env['foo(bar)'] = 1 """) -test.run(arguments = '.', status = 2, stderr=""" +expect_stderr = """ scons: *** Illegal construction variable `foo(bar)' -File "SConscript", line 2, in ? -""") +File "%(SConscript_path)s", line 2, in ? +""" % locals() + +test.run(arguments='.', status=2, stderr=expect_stderr) test.pass_test() diff --git a/test/builderrors.py b/test/builderrors.py index 4eb6bfa..8c7c4ab 100644 --- a/test/builderrors.py +++ b/test/builderrors.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -47,13 +47,13 @@ sys.exit(exitval) """) test.write(['one', 'SConstruct'], """ -B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES') env = Environment(BUILDERS = { 'B0' : B0, 'B1' : B1 }) env.B1(target = 'f1.out', source = 'f1.in') env.B0(target = 'f2.out', source = 'f2.in') env.B0(target = 'f3.out', source = 'f3.in') -""" % (python, python)) +""" % locals()) test.write(['one', 'f1.in'], "one/f1.in\n") test.write(['one', 'f2.in'], "one/f2.in\n") @@ -67,13 +67,13 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) test.fail_test(os.path.exists(test.workpath('f3.out'))) test.write(['two', 'SConstruct'], """ -B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES') env = Environment(BUILDERS = { 'B0': B0, 'B1' : B1 }) env.B0(target = 'f1.out', source = 'f1.in') env.B1(target = 'f2.out', source = 'f2.in') env.B0(target = 'f3.out', source = 'f3.in') -""" % (python, python)) +""" % locals()) test.write(['two', 'f1.in'], "two/f1.in\n") test.write(['two', 'f2.in'], "two/f2.in\n") @@ -87,13 +87,13 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) test.fail_test(os.path.exists(test.workpath('f3.out'))) test.write(['three', 'SConstruct'], """ -B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES') env = Environment(BUILDERS = { 'B0' : B0, 'B1': B1 }) env.B0(target = 'f1.out', source = 'f1.in') env.B0(target = 'f2.out', source = 'f2.in') env.B1(target = 'f3.out', source = 'f3.in') -""" % (python, python)) +""" % locals()) test.write(['three', 'f1.in'], "three/f1.in\n") test.write(['three', 'f2.in'], "three/f2.in\n") @@ -120,4 +120,62 @@ err = test.stderr() test.fail_test(string.find(err, 'Exception') != -1 or \ string.find(err, 'Traceback') != -1) + +# Test ETOOLONG (arg list too long). This is not in exitvalmap, +# but that shouldn't cause a scons traceback. +long_cmd = 'xyz ' + "foobarxyz" * 100000 +test.write('SConstruct', """ +env=Environment() +if env['PLATFORM'] == 'posix': + from SCons.Platform.posix import fork_spawn + env['SPAWN'] = fork_spawn +env.Command(target='longcmd.out', source=[], action='echo %s') +"""%long_cmd) + +test.run(status=2, stderr=None) +err = test.stderr() +test.fail_test(string.find(err, 'Exception') != -1 or \ + string.find(err, 'Traceback') != -1) +# Python 1.5.2 on a FC3 system doesn't even get to the exitvalmap +# because it fails with "No such file or directory." Just comment +# this out for now, there are plenty of other good tests below. +#test.fail_test(string.find(err, "too long") == -1 and # posix +# string.find(err, "nvalid argument") == -1) # win32 + + +# Test bad shell ('./one' is a dir, so it can't be used as a shell). +# This will also give an exit status not in exitvalmap, +# with error "Permission denied". +test.write('SConstruct', """ +env=Environment() +if env['PLATFORM'] == 'posix': + from SCons.Platform.posix import fork_spawn + env['SPAWN'] = fork_spawn +env['SHELL'] = 'one' +env.Command(target='badshell.out', source=[], action='foo') +""") + +test.run(status=2, stderr=None) +err = test.stderr() +test.fail_test(string.find(err, 'Exception') != -1 or \ + string.find(err, 'Traceback') != -1) +test.fail_test(string.find(err, "ermission") == -1 and \ + string.find(err, "such file") == -1) + + +# Test command with exit status -1. +# Should not give traceback. +test.write('SConstruct', """ +import os +env = Environment(ENV = os.environ) +env.Command('dummy.txt', None, ['python -c "import sys; sys.exit(-1)"']) +""") + +test.run(status=2, stderr=None) +err = test.stderr() +test.fail_test(string.find(err, 'Exception') != -1 or \ + string.find(err, 'Traceback') != -1) + + +# No tests failed; OK. test.pass_test() diff --git a/test/chdir.py b/test/chdir.py index b46764b..1a1a2d7 100644 --- a/test/chdir.py +++ b/test/chdir.py @@ -31,7 +31,7 @@ Command() calls and execution work1s correctly. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -99,7 +99,7 @@ ofp.close """) test.write(['work1', 'SConstruct'], """ -cat_command = r"%(python)s %(cat_py)s ${TARGET.file} ${SOURCE.file}" +cat_command = r'%(_python_)s %(cat_py)s ${TARGET.file} ${SOURCE.file}' no_chdir_act = Action(cat_command) chdir_sub4_act = Action(cat_command, chdir=1) @@ -229,14 +229,14 @@ work2_sub_f1_out = test.workpath('work2', 'sub', 'f1.out') work2_sub_f2_out = test.workpath('work2', 'sub', 'f2.out') test.write(['work2', 'SConstruct'], """\ -cat_command = r"%(python)s %(cat_py)s ${TARGET.file} ${SOURCE.file}" +cat_command = r'%(_python_)s %(cat_py)s ${TARGET.file} ${SOURCE.file}' env = Environment() env.Command('sub/f1.out', 'sub/f1.in', cat_command, chdir=1) env.Command('sub/f2.out', 'sub/f2.in', [ - r"%(python)s %(cat_py)s .temp ${SOURCE.file}", - r"%(python)s %(cat_py)s ${TARGET.file} .temp", + r'%(_python_)s %(cat_py)s .temp ${SOURCE.file}', + r'%(_python_)s %(cat_py)s ${TARGET.file} .temp', ], chdir=1) """ % locals()) @@ -246,13 +246,13 @@ test.write(['work2', 'sub', 'f2.in'], "work2/sub/f2.in") expect = test.wrap_stdout("""\ os.chdir('sub') -%(python)s %(cat_py)s f1.out f1.in +%(_python_)s %(cat_py)s f1.out f1.in os.chdir(%(work2)s) os.chdir('sub') -%(python)s %(cat_py)s .temp f2.in +%(_python_)s %(cat_py)s .temp f2.in os.chdir(%(work2)s) os.chdir('sub') -%(python)s %(cat_py)s f2.out .temp +%(_python_)s %(cat_py)s f2.out .temp os.chdir(%(work2)s) """ % locals()) diff --git a/test/dependency-cycle.py b/test/dependency-cycle.py index 8d1275f..b2a8974 100644 --- a/test/dependency-cycle.py +++ b/test/dependency-cycle.py @@ -40,6 +40,7 @@ env.Depends(foo3, foo1) """) test.write('f1.c', r""" +#include void f1(void) { diff --git a/test/errors.py b/test/errors.py index 120ea3a..6e0a05f 100644 --- a/test/errors.py +++ b/test/errors.py @@ -29,7 +29,7 @@ import TestSCons import string import sys -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) @@ -85,7 +85,7 @@ a.append(2) test.run(status = 2, stderr = """\ AttributeError: 'int' object has no attribute 'append': - File "SConstruct", line 2: + File ".+SConstruct", line 2: a.append\(2\) """) @@ -98,7 +98,7 @@ a == 1 test.run(status = 2, stderr = """\ NameError: [^\n]* - File "SConstruct", line 1: + File ".+SConstruct", line 1: a == 1 """) @@ -110,7 +110,7 @@ a ! x """) test.run(stdout = "scons: Reading SConscript files ...\n", - stderr = """ File "SConstruct", line 2 + stderr = """ File ".+SConstruct", line 2 a ! x @@ -130,7 +130,7 @@ a[2] = 3 test.run(status = 2, stderr = """\ TypeError: object does not support item assignment: - File "SConstruct", line 2: + File ".+SConstruct", line 2: a\[2\] = 3 """) @@ -146,7 +146,7 @@ raise SCons.Errors.UserError, 'Depends() require both sources and targets.' test.run(stdout = "scons: Reading SConscript files ...\n", stderr = """ scons: \*\*\* Depends\(\) require both sources and targets. -File "SConstruct", line 4, in \? +File ".+SConstruct", line 4, in \? """, status=2) @@ -163,7 +163,7 @@ test.run(stdout = "scons: Reading SConscript files ...\ninternal error\n", File ".+", line \d+, in .+ File ".+", line \d+, in .+ File ".+", line \d+, in .+ - File "SConstruct", line \d+, in \? + File ".+SConstruct", line \d+, in \? raise InternalError, 'error inside' InternalError: error inside """, status=2) @@ -178,8 +178,10 @@ sys.exit(2) # Test ... test.write('SConstruct', """ env=Environment() -Default(env.Command(['one.out', 'two.out'], ['foo.in'], action=r'%s build.py')) -"""%python) +Default(env.Command(['one.out', 'two.out'], + ['foo.in'], + action=r'%(_python_)s build.py')) +""" % locals()) test.run(status=2, stderr="scons: \\*\\*\\* \\[one.out\\] Error 2\n") diff --git a/test/exceptions.py b/test/exceptions.py index 584d4f1..01a2855 100644 --- a/test/exceptions.py +++ b/test/exceptions.py @@ -25,16 +25,19 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os +import re import string import sys import TestSCons import TestCmd -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) -test.write('SConstruct', """ +SConstruct_path = test.workpath('SConstruct') + +test.write(SConstruct_path, """\ def func(source = None, target = None, env = None): raise "func exception" B = Builder(action = func) @@ -51,10 +54,10 @@ Traceback \((most recent call|innermost) last\): )*( File ".+", line \d+, in \S+ )*( File ".+", line \d+, in \S+ [^\n]+ -)* File "SConstruct", line 3, in func +)* File "%s", line 2, in func raise "func exception" func exception -""" +""" % re.escape(SConstruct_path) test.run(arguments = "foo.out", stderr = expected_stderr, status = 2) @@ -69,11 +72,11 @@ import sys sys.exit(1) """) -test.write('SConstruct', """ -Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE') +test.write(SConstruct_path, """ +Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE') env = Environment(BUILDERS = { 'Fail' : Fail }) env.Fail(target = 'f1', source = 'f1.in') -""" % (python)) +""" % locals()) test.write('f1.in', "f1.in\n") @@ -87,13 +90,13 @@ test.run(arguments = '-j2 .', status = 2, stderr = expected_stderr) # even if the exception is raised during the Task.prepare() # [Node.prepare()] -test.write('SConstruct', """ -Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE') +test.write(SConstruct_path, """ +Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE') env = Environment(BUILDERS = { 'Fail' : Fail }) env.Fail(target = 'f1', source = 'f1.in') env.Fail(target = 'f2', source = 'f2.in') env.Fail(target = 'f3', source = 'f3.in') -""" % (python)) +""" % locals()) # f2.in is not created to cause a Task.prepare exception test.write('f3.in', 'f3.in\n') diff --git a/test/expansion.py b/test/expansion.py index 2c22291..0f72134 100644 --- a/test/expansion.py +++ b/test/expansion.py @@ -52,6 +52,8 @@ env.Program(r'%s') os.path.join('$SUBDIR', 'foo4.c'))) test.write(['sub', 'f1.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('f2.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -72,6 +76,8 @@ main(int argc, char *argv[]) """) test.write(['sub', 'f3.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -82,6 +88,8 @@ main(int argc, char *argv[]) """) test.write(['sub', 'foo4.c'], r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/explain.py b/test/explain.py index 7f0fbb5..f69b00f 100644 --- a/test/explain.py +++ b/test/explain.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -85,7 +85,7 @@ kscan = Scanner(name = 'kfile', argument = None, skeys = ['.k']) -cat = Builder(action = r"%s %s $TARGET $SOURCES") +cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES') env = Environment() env.Append(BUILDERS = {'Cat':cat}, @@ -97,7 +97,7 @@ env.Install('../inc', 'aaa') env.InstallAs('../inc/bbb.k', 'bbb.k') env.Install('../inc', 'ddd') env.InstallAs('../inc/eee', 'eee.in') -""" % (python, cat_py) +""" % locals() args = '--debug=explain .' @@ -109,10 +109,12 @@ Import("env") env.Cat('file1', 'file1.in') env.Cat('file2', 'file2.k') env.Cat('file3', ['xxx', 'yyy', 'zzz']) -env.Command('file4', 'file4.in', r"%s %s $TARGET $FILE4FLAG $SOURCES", FILE4FLAG="-") +env.Command('file4', 'file4.in', + r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', + FILE4FLAG='-') env.Cat('file5', 'file5.k') env.Cat('subdir/file6', 'subdir/file6.in') -""" % (python, cat_py)) +""" % locals()) test.write(['work1', 'src', 'aaa'], "aaa 1\n") test.write(['work1', 'src', 'bbb.k'], """\ @@ -155,15 +157,15 @@ work1_inc_eee = test.workpath('work1', 'inc', 'eee') work1_inc_bbb_k = test.workpath('work1', 'inc', 'bbb.k') # -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: building `file1' because it doesn't exist -%(python)s %(cat_py)s file1 file1.in +%(_python_)s %(cat_py)s file1 file1.in scons: building `file2' because it doesn't exist -%(python)s %(cat_py)s file2 file2.k +%(_python_)s %(cat_py)s file2 file2.k scons: building `file3' because it doesn't exist -%(python)s %(cat_py)s file3 xxx yyy zzz +%(_python_)s %(cat_py)s file3 xxx yyy zzz scons: building `file4' because it doesn't exist -%(python)s %(cat_py)s file4 - file4.in +%(_python_)s %(cat_py)s file4 - file4.in scons: building `%(work1_inc_aaa)s' because it doesn't exist Install file: "aaa" as "%(work1_inc_aaa)s" scons: building `%(work1_inc_ddd)s' because it doesn't exist @@ -173,10 +175,12 @@ Install file: "eee.in" as "%(work1_inc_eee)s" scons: building `%(work1_inc_bbb_k)s' because it doesn't exist Install file: "bbb.k" as "%(work1_inc_bbb_k)s" scons: building `file5' because it doesn't exist -%(python)s %(cat_py)s file5 file5.k +%(_python_)s %(cat_py)s file5 file5.k scons: building `%(subdir_file6)s' because it doesn't exist -%(python)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s -""" % locals())) +%(_python_)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file1'], "file1.in 1\n") test.must_match(['work1', 'src', 'file2'], """\ @@ -203,23 +207,25 @@ test.write(['work1', 'src', 'yyy'], "yyy 2\n") test.write(['work1', 'src', 'zzz'], "zzz 2\n") test.write(['work1', 'src', 'bbb.k'], "bbb.k 2\ninclude ccc\n") -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file1' because `file1.in' changed -%(python)s %(cat_py)s file1 file1.in +%(_python_)s %(cat_py)s file1 file1.in scons: rebuilding `file2' because `yyy' changed -%(python)s %(cat_py)s file2 file2.k +%(_python_)s %(cat_py)s file2 file2.k scons: rebuilding `file3' because: `yyy' changed `zzz' changed -%(python)s %(cat_py)s file3 xxx yyy zzz +%(_python_)s %(cat_py)s file3 xxx yyy zzz scons: rebuilding `%(work1_inc_bbb_k)s' because: `%(work1_inc_ddd)s' is no longer a dependency `%(work1_inc_eee)s' is no longer a dependency `bbb.k' changed Install file: "bbb.k" as "%(work1_inc_bbb_k)s" scons: rebuilding `file5' because `%(work1_inc_bbb_k)s' changed -%(python)s %(cat_py)s file5 file5.k -""" % locals())) +%(_python_)s %(cat_py)s file5 file5.k +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file1'], "file1.in 2\n") test.must_match(['work1', 'src', 'file2'], """\ @@ -243,10 +249,12 @@ Import("env") env.Cat('file3', ['xxx', 'yyy']) """) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because `zzz' is no longer a dependency -%(python)s %(cat_py)s file3 xxx yyy -""" % locals())) +%(_python_)s %(cat_py)s file3 xxx yyy +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\n") @@ -256,10 +264,12 @@ Import("env") env.Cat('file3', ['xxx', 'yyy', 'zzz']) """) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because `zzz' is a new dependency -%(python)s %(cat_py)s file3 xxx yyy zzz -""" % locals())) +%(_python_)s %(cat_py)s file3 xxx yyy zzz +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n") @@ -269,12 +279,14 @@ Import("env") env.Cat('file3', ['zzz', 'yyy', 'xxx']) """) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because the dependency order changed: old: ['xxx', 'yyy', 'zzz'] new: ['zzz', 'yyy', 'xxx'] -%(python)s %(cat_py)s file3 zzz yyy xxx -""" % locals())) +%(_python_)s %(cat_py)s file3 zzz yyy xxx +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") @@ -283,20 +295,22 @@ test.write(['work1', 'src', 'SConscript'], """\ Import("env") f3 = File('file3') env.Cat(f3, ['zzz', 'yyy', 'xxx']) -env.AddPostAction(f3, r"%(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy") -env.AddPreAction(f3, r"%(python)s %(cat_py)s ${TARGET}.alt $SOURCES") +env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy') +env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') """ % locals()) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because the build action changed: - old: %(python)s %(cat_py)s $TARGET $SOURCES - new: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES - %(python)s %(cat_py)s $TARGET $SOURCES - %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy -%(python)s %(cat_py)s file3.alt zzz yyy xxx -%(python)s %(cat_py)s file3 zzz yyy xxx -%(python)s %(cat_py)s file3.yyy zzz yyy xxx yyy -""" % locals())) + old: %(_python_)s %(cat_py)s $TARGET $SOURCES + new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy +%(_python_)s %(cat_py)s file3.alt zzz yyy xxx +%(_python_)s %(cat_py)s file3 zzz yyy xxx +%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx yyy +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") @@ -307,22 +321,24 @@ test.write(['work1', 'src', 'SConscript'], """\ Import("env") f3 = File('file3') env.Cat(f3, ['zzz', 'yyy', 'xxx']) -env.AddPostAction(f3, r"%(python)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx") -env.AddPreAction(f3, r"%(python)s %(cat_py)s ${TARGET}.alt $SOURCES") +env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx') +env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES') """ % locals()) -test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file3' because the build action changed: - old: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES - %(python)s %(cat_py)s $TARGET $SOURCES - %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy - new: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES - %(python)s %(cat_py)s $TARGET $SOURCES - %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx -%(python)s %(cat_py)s file3.alt zzz yyy xxx -%(python)s %(cat_py)s file3 zzz yyy xxx -%(python)s %(cat_py)s file3.yyy zzz yyy xxx xxx -""" % locals())) + old: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy + new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES + %(_python_)s %(cat_py)s $TARGET $SOURCES + %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx +%(_python_)s %(cat_py)s file3.alt zzz yyy xxx +%(_python_)s %(cat_py)s file3 zzz yyy xxx +%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx xxx +""" % locals()) + +test.run(chdir='work1/src', arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n") test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n") @@ -331,14 +347,18 @@ test.must_match(['work1', 'src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\nxxx 1\n") # test.write(['work1', 'src', 'SConscript'], """\ Import("env") -env.Command('file4', 'file4.in', r"%(python)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES", FILE4FLAG="") +env.Command('file4', 'file4.in', + r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES', + FILE4FLAG='') """ % locals()) -test.run(chdir='work1/src',arguments=args, stdout=test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: rebuilding `file4' because the contents of the build action changed - action: %(python)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES -%(python)s %(cat_py)s file4 file4.in -""" % locals())) + action: %(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES +%(_python_)s %(cat_py)s file4 file4.in +""" % locals()) + +test.run(chdir='work1/src',arguments=args, stdout=expect) test.must_match(['work1', 'src', 'file4'], "file4.in 1\n") @@ -363,7 +383,7 @@ Import("env") env.Cat('file1', 'file1.in') env.Cat('file2', 'file2.k') env.Cat('file3', ['xxx', 'yyy', 'zzz']) -env.Command('file4', 'file4.in', r"%(python)s %(cat_py)s $TARGET - $SOURCES") +env.Command('file4', 'file4.in', r'%(_python_)s %(cat_py)s $TARGET - $SOURCES') env.Cat('file5', 'file5.k') env.Cat('subdir/file6', 'subdir/file6.in') """ % locals()) @@ -437,20 +457,20 @@ work4_inc_eee = test.workpath('work4', 'inc', 'eee') test.run(chdir='work4/src', arguments=args, stdout=test.wrap_stdout("""\ scons: rebuilding `file1' because `file1.in' changed -%(python)s %(cat_py)s file1 file1.in +%(_python_)s %(cat_py)s file1 file1.in scons: rebuilding `file2' because `yyy' changed -%(python)s %(cat_py)s file2 file2.k +%(_python_)s %(cat_py)s file2 file2.k scons: rebuilding `file3' because: `yyy' changed `zzz' changed -%(python)s %(cat_py)s file3 xxx yyy zzz +%(_python_)s %(cat_py)s file3 xxx yyy zzz scons: rebuilding `%(work4_inc_bbb_k)s' because: `%(work4_inc_ddd)s' is no longer a dependency `%(work4_inc_eee)s' is no longer a dependency `bbb.k' changed Install file: "bbb.k" as "%(work4_inc_bbb_k)s" scons: rebuilding `file5' because `%(work4_inc_bbb_k)s' changed -%(python)s %(cat_py)s file5 file5.k +%(_python_)s %(cat_py)s file5 file5.k """ % locals())) test.must_match(['work4', 'src', 'file1'], "file1.in 2\n") diff --git a/test/gnutools.py b/test/gnutools.py index 82c83ef..4bcea00 100644 --- a/test/gnutools.py +++ b/test/gnutools.py @@ -31,7 +31,7 @@ Testing the gnu tool chain, i.e. the tools 'gcc', 'g++' and 'gnulink'. import TestSCons import string import sys -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _dll = TestSCons._dll dll_ = TestSCons.dll_ @@ -91,10 +91,13 @@ test.write(['work1', 'cppfile2.cpp'],""" /* cpp file 2 */ """) +mygcc_py = test.workpath('gnutools','mygcc.py') +mygxx_py = test.workpath('gnutools','myg++.py') + test.write(['work1', 'SConstruct'],""" env = Environment(tools=['gcc','g++','gnulink'], - CC=r'%s %s', - CXX=r'%s %s', + CC=r'%(_python_)s %(mygcc_py)s', + CXX=r'%(_python_)s %(mygxx_py)s', OBJSUFFIX='.o', SHOBJSUFFIX='.os') env.Program('c-only', Split('cfile1.c cfile2.c')) @@ -104,8 +107,7 @@ env.Program('c-and-cpp', Split('cfile1.c cppfile1.cpp')) env.SharedLibrary('c-only', Split('cfile1.c cfile2.c')) env.SharedLibrary('cpp-only', Split('cppfile1.cpp cppfile2.cpp')) env.SharedLibrary('c-and-cpp', Split('cfile1.c cppfile1.cpp')) -""" % (python, test.workpath('gnutools','mygcc.py'), - python, test.workpath('gnutools','myg++.py'))) +""" % locals()) test.run(chdir='work1') diff --git a/test/ignore-command.py b/test/ignore-command.py index 201c488..d4de8d3 100644 --- a/test/ignore-command.py +++ b/test/ignore-command.py @@ -36,7 +36,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,13 +53,13 @@ sys.exit(1) test.write('SConstruct', """\ env = Environment() -f1 = env.Command('f1.out', 'f1.in', "%(python)s build.py $TARGET $SOURCE") -f2 = env.Command('f2.out', 'f2.in', "-%(python)s build.py $TARGET $SOURCE") -f3 = env.Command('f3.out', 'f3.in', "- %(python)s build.py $TARGET $SOURCE") -f4 = env.Command('f4.out', 'f4.in', "@-%(python)s build.py $TARGET $SOURCE") -f5 = env.Command('f5.out', 'f5.in', "@- %(python)s build.py $TARGET $SOURCE") -f6 = env.Command('f6.out', 'f6.in', "-@%(python)s build.py $TARGET $SOURCE") -f7 = env.Command('f7.out', 'f7.in', "-@ %(python)s build.py $TARGET $SOURCE") +f1 = env.Command('f1.out', 'f1.in', '%(_python_)s build.py $TARGET $SOURCE') +f2 = env.Command('f2.out', 'f2.in', '-%(_python_)s build.py $TARGET $SOURCE') +f3 = env.Command('f3.out', 'f3.in', '- %(_python_)s build.py $TARGET $SOURCE') +f4 = env.Command('f4.out', 'f4.in', '@-%(_python_)s build.py $TARGET $SOURCE') +f5 = env.Command('f5.out', 'f5.in', '@- %(_python_)s build.py $TARGET $SOURCE') +f6 = env.Command('f6.out', 'f6.in', '-@%(_python_)s build.py $TARGET $SOURCE') +f7 = env.Command('f7.out', 'f7.in', '-@ %(_python_)s build.py $TARGET $SOURCE') Default(f2, f3, f4, f5, f6, f7) """ % locals()) diff --git a/test/implicit-cache/GetOption.py b/test/implicit-cache/GetOption.py new file mode 100644 index 0000000..5915cca --- /dev/null +++ b/test/implicit-cache/GetOption.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that SetOption/GetOption('implicit_cache') works and can +be overridden from the command line. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +assert not GetOption('implicit_cache') +SetOption('implicit_cache', 1) +assert GetOption('implicit_cache') +""") + +test.run() + +test.write('SConstruct', """ +assert GetOption('implicit_cache') +SetOption('implicit_cache', 0) +assert GetOption('implicit_cache') +""") + +test.run(arguments='--implicit-cache') + + +test.pass_test() diff --git a/test/implicit-cache/SetOption.py b/test/implicit-cache/SetOption.py new file mode 100644 index 0000000..ee2afa5 --- /dev/null +++ b/test/implicit-cache/SetOption.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that SetOption('implicit_cache', 1) actually enables implicit +caching by detecting the case where implicit caching causes inaccurate +builds: a same-named file dropped into a directory earlier in the +CPPPATH list will *not* be detected because we use what's in the cache. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +SetOption('implicit_cache', 1) +env=Environment(CPPPATH=['i1', 'i2']) +env.Object('foo.c') +""") + +test.subdir('i1') +test.subdir('i2') + +test.write('foo.c', """ +#include + +void foo(void) +{ + FOO_H_DEFINED + ++x; /* reference x */ +} +""") + +test.write('i2/foo.h', """ +#define FOO_H_DEFINED int x = 1; +""") + +test.run(arguments = '.') + +test.write('i1/foo.h', """ +this line will cause a syntax error if it's included by a rebuild +"""); + +test.up_to_date(arguments = '.') + + +test.pass_test() diff --git a/test/implicit-cache/basic.py b/test/implicit-cache/basic.py new file mode 100644 index 0000000..0c9196c --- /dev/null +++ b/test/implicit-cache/basic.py @@ -0,0 +1,317 @@ +#!/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 os.path + +import TestSCons + +_exe = TestSCons._exe +_obj = TestSCons._obj + +prog = 'prog' + _exe +subdir_prog = os.path.join('subdir', 'prog' + _exe) +variant_prog = os.path.join('variant', 'prog' + _exe) + +args = prog + ' ' + subdir_prog + ' ' + variant_prog + +test = TestSCons.TestSCons() + +test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2') + +test.write('SConstruct', """ +env = Environment(CPPPATH = Split('inc2 include')) +obj = env.Object(target='prog', source='subdir/prog.c') +env.Program(target='prog', source=obj) +SConscript('subdir/SConscript', "env") + +BuildDir('variant', 'subdir', 0) +include = Dir('include') +env = Environment(CPPPATH=['inc2', include]) +SConscript('variant/SConscript', "env") + +def copy(target, source, env): + open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read()) +nodep = env.Command('nodeps.c', 'nodeps.in', action=copy) +env.Program('nodeps', 'nodeps.c') + +env.Object(['one', 'two'], ['one.c']) +""") + +test.write(['subdir', 'SConscript'], +""" +Import("env") +env.Program(target='prog', source='prog.c') +""") + +test.write('nodeps.in', r""" +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + return 0; +} +""") + + +test.write(['include', 'foo.h'], r""" +#define FOO_STRING "include/foo.h 1\n" +#include +""") + +test.write(['include', 'bar.h'], r""" +#define BAR_STRING "include/bar.h 1\n" +""") + +test.write(['include', 'baz.h'], r""" +#define BAZ_STRING "include/baz.h 1\n" +""") + +test.write(['subdir', 'prog.c'], r""" +#include +#include + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("subdir/prog.c\n"); + printf(FOO_STRING); + printf(BAR_STRING); + return 0; +} +""") + +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""" +#define BAR_STRING "subdir/include/bar.h 1\n" +""") + +test.write('one.c' , r""" +#include + +void one(void) { } +""") + +test.run(arguments = "--implicit-cache " + args) + +test.run(program = test.workpath(prog), + stdout = "subdir/prog.c\ninclude/foo.h 1\ninclude/bar.h 1\n") + +test.run(program = test.workpath(subdir_prog), + stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") + +test.run(program = test.workpath(variant_prog), + stdout = "subdir/prog.c\ninclude/foo.h 1\ninclude/bar.h 1\n") + +test.up_to_date(arguments = args) + + + +# 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" +""") + +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") + +test.run(program = test.workpath(subdir_prog), + stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") + +test.run(program = test.workpath(variant_prog), + stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") + +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""" +#define FOO_STRING "include/foo.h 2\n" +#include "bar.h" +#include "baz.h" +""") + +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") + +test.run(program = test.workpath(subdir_prog), + stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") + +test.run(program = test.workpath(variant_prog), + stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") + +test.up_to_date(arguments = args) + + + +test.write(['include', 'foo.h'], r""" +#define FOO_STRING "include/foo.h 2\n" +#include "baz.h" +#include "bar.h" +""") + +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") + +test.run(program = test.workpath(subdir_prog), + stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") + +test.run(program = test.workpath(variant_prog), + stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") + +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""" +#define FOO_STRING "inc2/foo.h 1\n" +#include +""") + +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") + +test.run(program = test.workpath(subdir_prog), + stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") + +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""" +#define FOO_STRING "include/foo.h 3\n" +#include "bar.h" +""") + +test.run(arguments = "--implicit-cache " + args) + +test.run(program = test.workpath(prog), + stdout = "subdir/prog.c\ninc2/foo.h 1\ninclude/bar.h 1\n") + +test.run(program = test.workpath(subdir_prog), + stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") + +test.run(program = test.workpath(variant_prog), + stdout = "subdir/prog.c\ninclude/foo.h 3\ninclude/bar.h 1\n") + + + +# 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""" +#include + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + return 0; +} +""") + +test.run(arguments = "--implicit-cache one%s"%_obj) + + + +# Test forcing of implicit caching: +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""" +#define FOO_STRING "include/foo.h 3\n" +#include "baz.h" +#include "bar.h" +""") + +test.not_up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) + +test.write(['include', 'baz.h'], r""" +#define BAZ_STRING "include/baz.h 2\n" +""") + +test.up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) + +test.not_up_to_date(arguments = variant_prog) + + + +# Test forcing rescanning: +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""" +#define FOO_STRING "include/foo.h 3\n" +#include "baz.h" +#include "bar.h" +""") + +test.not_up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) + +test.write(['include', 'baz.h'], r""" +#define BAZ_STRING "include/baz.h 2\n" +""") + +test.up_to_date(options = "--implicit-deps-unchanged", + arguments = variant_prog) + +test.not_up_to_date(options = "--implicit-deps-changed", + arguments = variant_prog) + + + +test.pass_test() diff --git a/test/import.py b/test/import.py index 3663f53..bb070ab 100644 --- a/test/import.py +++ b/test/import.py @@ -33,6 +33,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + platforms = [ 'aix', 'cygwin', @@ -139,27 +141,33 @@ tools = [ # Intel no compiler warning.. intel_no_compiler_fmt = """ -scons: warning: Failed to find Intel compiler for version='None', abi='%s' -File "SConstruct", line 1, in ? +scons: warning: Failed to find Intel compiler for version='None', abi='%(abi)s' +File "%(SConstruct_path)s", line 1, in ? """ -intel_no_compiler_32_warning = intel_no_compiler_fmt % 'ia32' -intel_no_compiler_64_warning = intel_no_compiler_fmt % 'x86_64' +abi = 'ia32' +intel_no_compiler_32_warning = intel_no_compiler_fmt % locals() + +abi = 'x86_64' +intel_no_compiler_64_warning = intel_no_compiler_fmt % locals() # Intel no top dir warning. intel_no_top_dir_fmt = """ -scons: warning: Can't find Intel compiler top dir for version='None', abi='%s' -File "SConstruct", line 1, in ? -""" +scons: warning: Can't find Intel compiler top dir for version='None', abi='%(abi)s' +File "%(SConstruct_path)s", line 1, in ? +""" % locals() -intel_no_top_dir_32_warning = intel_no_top_dir_fmt % 'ia32' -intel_no_top_dir_64_warning = intel_no_top_dir_fmt % 'x86_64' +abi = 'ia32' +intel_no_top_dir_32_warning = intel_no_top_dir_fmt % locals() + +abi = 'x86_64' +intel_no_top_dir_64_warning = intel_no_top_dir_fmt % locals() # Intel no license directory warning intel_license_warning = """ scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort. -File "SConstruct", line 1, in ? -""" +File "%(SConstruct_path)s", line 1, in ? +""" % locals() intel_warnings = [ intel_license_warning, @@ -176,15 +184,20 @@ intel_warnings = [ moc = test.where_is('moc') if moc: import os.path + + qtdir = os.path.dirname(os.path.dirname(moc)) + qt_err = """ -scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%s) -File "SConstruct", line 1, in ? -""" % os.path.dirname(os.path.dirname(moc)) +scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%(qtdir)s) +File "%(SConstruct_path)s", line 1, in ? +""" % locals() + else: + qt_err = """ scons: warning: Could not detect qt, using empty QTDIR -File "SConstruct", line 1, in ? -""" +File "%(SConstruct_path)s", line 1, in ? +""" % locals() error_output = { 'icl' : intel_warnings, diff --git a/test/long-lines.py b/test/long-lines.py index afa8455..1c501e3 100644 --- a/test/long-lines.py +++ b/test/long-lines.py @@ -73,6 +73,8 @@ env.SharedLibrary(target = 'shared', source = 'shared.c', no_import_lib=1) """ % (arflag_init, arflag, linkflag_init, linkflag)) test.write('foo.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -83,6 +85,8 @@ main(int argc, char *argv[]) """) test.write('static.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -93,6 +97,8 @@ main(int argc, char *argv[]) """) test.write('shared.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/multi.py b/test/multi.py index 5a5d667..c8b8df4 100644 --- a/test/multi.py +++ b/test/multi.py @@ -36,6 +36,7 @@ import TestSCons test = TestSCons.TestSCons(match=TestCmd.match_re) +_python_ = TestSCons._python_ # # A builder with "multi" set can be called multiple times and @@ -131,11 +132,11 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:]) test.write('SConstruct', """ -B = Builder(action='%(python)s build.py $foo $TARGET $SOURCES', multi=1) +B = Builder(action='%(_python_)s build.py $foo $TARGET $SOURCES', multi=1) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'file03.out', source = 'file03a.in', foo=1) env.B(target = 'file03.out', source = 'file03b.in', foo=2) -""" % {'python':TestSCons.python}) +""" % locals()) test.write('file03a.in', 'file03a.in\n') test.write('file03b.in', 'file03b.in\n') @@ -162,17 +163,17 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:]) test.write('SConstruct', """ -B = Builder(action='%(python)s build.py $foo $TARGET $SOURCES', multi=1) +B = Builder(action='%(_python_)s build.py $foo $TARGET $SOURCES', multi=1) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'file4.out', source = 'file4a.in', foo=3) env.B(target = 'file4.out', source = 'file4b.in', foo=3) -""" % {'python':TestSCons.python}) +""" % locals()) test.write('file4a.in', 'file4a.in\n') test.write('file4b.in', 'file4b.in\n') python_expr = string.replace(TestSCons.python, '\\', '\\\\') -act = TestSCons.re_escape('%s build.py \$foo \$TARGET \$SOURCES' % python_expr) +act = TestSCons.re_escape('"%s" build.py \$foo \$TARGET \$SOURCES' % python_expr) test.run(arguments='file4.out', stderr=(""" diff --git a/test/multiline.py b/test/multiline.py index 302e17d..59eba60 100644 --- a/test/multiline.py +++ b/test/multiline.py @@ -29,6 +29,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,14 +43,14 @@ sys.exit(0) """) test.write('SConstruct', """ -B1 = Builder(action = [ [ r'%s', 'build.py', '.temp', '$SOURCES' ], - [ r'%s', 'build.py', '$TARGETS', '.temp'] ]) -B2 = Builder(action = r'%s' + " build.py .temp $SOURCES\\n" + r'%s' + " build.py $TARGETS .temp") +B1 = Builder(action = [ [ r'%(python)s', 'build.py', '.temp', '$SOURCES' ], + [ r'%(python)s', 'build.py', '$TARGETS', '.temp'] ]) +B2 = Builder(action = r'%(_python_)s' + ' build.py .temp $SOURCES\\n' + r'%(_python_)s' + " build.py $TARGETS .temp") env = Environment(BUILDERS = { 'B1' : B1, 'B2' : B2 }) env.B1(target = 'foo1.out', source = 'foo1.in') env.B2(target = 'foo2.out', source = 'foo2.in') env.B1(target = 'foo3.out', source = 'foo3.in') -""" % (python, python, python, python)) +""" % locals()) test.write('foo1.in', "foo1.in\n") diff --git a/test/option--.py b/test/option--.py index 5f70769..9540397 100644 --- a/test/option--.py +++ b/test/option--.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,16 +41,16 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = '-f1.out', source = 'f1.in') env.MyBuild(target = '-f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") -expect = test.wrap_stdout("%s build.py -f1.out\n%s build.py -f2.out\n" % (python, python)) +expect = test.wrap_stdout('%(_python_)s build.py -f1.out\n%(_python_)s build.py -f2.out\n' % locals()) test.run(arguments = '-- -f1.out -f2.out', stdout = expect) diff --git a/test/option--D.py b/test/option--D.py index d1a118e..cca8ed1 100644 --- a/test/option--D.py +++ b/test/option--D.py @@ -28,7 +28,7 @@ import sys import TestSCons import os -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,14 +44,14 @@ file.close() test.write('SConstruct', """ import SCons.Defaults -B = Builder(action=r'%s build.py $TARGET $SOURCES') +B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES') env = Environment() env['BUILDERS']['B'] = B env.B(target = 'sub1/foo.out', source = 'sub1/foo.in') Export('env') SConscript('sub1/SConscript') SConscript('sub2/SConscript') -""" % python) +""" % locals()) test.write(['sub1', 'SConscript'], """ Import('env') diff --git a/test/option--Q.py b/test/option--Q.py index 4d1a005..f99031c 100644 --- a/test/option--Q.py +++ b/test/option--Q.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,19 +41,19 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGET') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGET') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") test.run(arguments = '-Q f1.out f2.out', stdout = """\ -%s build.py f1.out -%s build.py f2.out -""" % (python, python)) +%(_python_)s build.py f1.out +%(_python_)s build.py f2.out +""" % locals()) test.fail_test(not os.path.exists(test.workpath('f1.out'))) test.fail_test(not os.path.exists(test.workpath('f2.out'))) diff --git a/test/option--U.py b/test/option--U.py index db6532e..3b0cc0d 100644 --- a/test/option--U.py +++ b/test/option--U.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.subdir('sub1', 'sub2', 'sub3') @@ -47,7 +47,7 @@ file.close() test.write('SConstruct', r""" import SCons.Defaults env = Environment() -env['BUILDERS']['B'] = Builder(action=r'%s build.py $TARGET $SOURCES', multi=1) +env['BUILDERS']['B'] = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES', multi=1) Default(env.B(target = 'sub1/foo.out', source = 'sub1/foo.in')) Export('env') SConscript('sub2/SConscript') @@ -56,7 +56,7 @@ BuildDir('sub2b', 'sub2') SConscript('sub2b/SConscript') Default(env.B(target = 'sub2/xxx.out', source = 'xxx.in')) SConscript('SConscript') -""" % python) +""" % locals()) test.write(['sub2', 'SConscript'], """ Import('env') diff --git a/test/option--Y.py b/test/option--Y.py index 62d8b7a..99d6939 100644 --- a/test/option--Y.py +++ b/test/option--Y.py @@ -49,6 +49,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """) test.write(['repository', 'aaa.c'], r""" +#include void aaa(void) { @@ -57,6 +58,7 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include void bbb(void) { @@ -65,6 +67,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include 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 +#include void bbb(void) { @@ -113,6 +119,8 @@ test.up_to_date(chdir = 'work1', options = opts, arguments = '.') # test.write(['work1', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -121,6 +129,8 @@ aaa(void) """) test.write(['work1', 'foo.c'], r""" +#include +#include 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 +#include 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 +#include 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 +#include 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 +#include int main(int argc, char *argv[]) { @@ -250,6 +268,8 @@ main(int argc, char *argv[]) """) test.write(['r.NEW', 'foo.c'], r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/option--cs.py b/test/option--cs.py index 16a3a73..1e62c49 100644 --- a/test/option--cs.py +++ b/test/option--cs.py @@ -34,7 +34,7 @@ import shutil import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj @@ -51,6 +51,8 @@ for src in sys.argv[2:]: file.close() """) +cache = test.workpath('cache') + test.write(['src1', 'SConstruct'], """ def cat(env, source, target): target = str(target[0]) @@ -61,13 +63,13 @@ def cat(env, source, target): f.write(open(src, "rb").read()) f.close() env = Environment(BUILDERS={'Internal':Builder(action=cat), - 'External':Builder(action='%s build.py $TARGET $SOURCES')}) + 'External':Builder(action='%(_python_)s build.py $TARGET $SOURCES')}) env.External('aaa.out', 'aaa.in') env.External('bbb.out', 'bbb.in') env.Internal('ccc.out', 'ccc.in') env.Internal('all', ['aaa.out', 'bbb.out', 'ccc.out']) -CacheDir(r'%s') -""" % (python, test.workpath('cache'))) +CacheDir(r'%(cache)s') +""" % locals()) test.write(['src1', 'aaa.in'], "aaa.in\n") test.write(['src1', 'bbb.in'], "bbb.in\n") @@ -103,14 +105,14 @@ test.run(chdir = 'src1', arguments = '-c .') # Verify that using --cache-show reports the files as being rebuilt, # even though we actually fetch them from the cache. Then clean up. -test.run(chdir = 'src1', - arguments = '--cache-show .', - stdout = test.wrap_stdout("""\ -%s build.py aaa.out aaa.in -%s build.py bbb.out bbb.in +expect = test.wrap_stdout("""\ +%(_python_)s build.py aaa.out aaa.in +%(_python_)s build.py bbb.out bbb.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""" % (python, python))) +""" % locals()) + +test.run(chdir = 'src1', arguments = '--cache-show .', stdout = expect) test.must_not_exist(test.workpath('src1', 'cat.out')) @@ -121,14 +123,14 @@ test.run(chdir = 'src1', arguments = '-c .') # Verify that using --cache-show -n reports the files as being rebuilt, # even though we don't actually fetch them from the cache. No need to # clean up. -test.run(chdir = 'src1', - arguments = '--cache-show -n .', - stdout = test.wrap_stdout("""\ -%s build.py aaa.out aaa.in -%s build.py bbb.out bbb.in +expect = test.wrap_stdout("""\ +%(_python_)s build.py aaa.out aaa.in +%(_python_)s build.py bbb.out bbb.in cat(["ccc.out"], ["ccc.in"]) cat(["all"], ["aaa.out", "bbb.out", "ccc.out"]) -""" % (python, python))) +""" % locals()) + +test.run(chdir = 'src1', arguments = '--cache-show -n .', stdout = expect) test.must_not_exist(test.workpath('src1', 'cat.out')) @@ -158,6 +160,8 @@ CacheDir(r'%s') """ % (test.workpath('cache'))) test.write(['src2', 'hello.c'], r"""\ +#include +#include int main(int argc, char *argv[]) { diff --git a/test/option--debug.py b/test/option--debug.py index f60710d..a56f261 100644 --- a/test/option--debug.py +++ b/test/option--debug.py @@ -24,12 +24,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons import sys import string import re import time +import TestSCons + +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.write('SConstruct', """ @@ -70,7 +73,7 @@ test.write('bar.h', """ test.run(arguments = "--debug=pdb", stdin = "n\ns\nq\n") test.fail_test(string.find(test.stdout(), "(Pdb)") == -1) -test.fail_test(string.find(test.stdout(), "scons") == -1) +test.fail_test(string.find(test.stdout(), "SCons") == -1) ############################ # test --debug=presub @@ -93,7 +96,7 @@ FILE = Builder(action="$FILECOM") TEMP = Builder(action="$TEMPCOM") LIST = Builder(action="$LISTCOM") FUNC = Builder(action=cat) -env = Environment(PYTHON='%s', +env = Environment(PYTHON='%(_python_)s', BUILDERS = {'FILE':FILE, 'TEMP':TEMP, 'LIST':LIST, 'FUNC':FUNC}, FILECOM="$PYTHON cat.py $SOURCES $TARGET", TEMPCOM="$PYTHON cat.py $SOURCES temp\\n$PYTHON cat.py temp $TARGET", @@ -116,7 +119,7 @@ env.LIST('file15.out', 'file15.in') env.LIST('file16.out', 'file16.in') env.FUNC('file17.out', 'file17.in') env.FUNC('file18.out', 'file18.in') -""" % TestSCons.python) +""" % locals()) test.write('file01.in', "file01.in\n") test.write('file02.in', "file02.in\n") @@ -139,34 +142,34 @@ test.write('file18.in', "file18.in\n") expect = """\ Building file01.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file01.in file01.out +%(_python_)s cat.py file01.in file01.out Building file02.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file02.in file02.out +%(_python_)s cat.py file02.in file02.out Building file03.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file03.in temp +%(_python_)s cat.py file03.in temp Building file03.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file03.out +%(_python_)s cat.py temp file03.out Building file04.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file04.in temp +%(_python_)s cat.py file04.in temp Building file04.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file04.out +%(_python_)s cat.py temp file04.out Building file05.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file05.in temp +%(_python_)s cat.py file05.in temp Building file05.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file05.out +%(_python_)s cat.py temp file05.out Building file06.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file06.in temp +%(_python_)s cat.py file06.in temp Building file06.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file06.out +%(_python_)s cat.py temp file06.out Building file07.out with action: cat(target, source, env) cat(["file07.out"], ["file07.in"]) @@ -178,42 +181,42 @@ Building file09.out with action: cat(["file09.out"], ["file09.in"]) Building file11.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file11.in file11.out +%(_python_)s cat.py file11.in file11.out Building file12.out with action: $PYTHON cat.py $SOURCES $TARGET -__PYTHON__ cat.py file12.in file12.out +%(_python_)s cat.py file12.in file12.out Building file13.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file13.in temp +%(_python_)s cat.py file13.in temp Building file13.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file13.out +%(_python_)s cat.py temp file13.out Building file14.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file14.in temp +%(_python_)s cat.py file14.in temp Building file14.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file14.out +%(_python_)s cat.py temp file14.out Building file15.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file15.in temp +%(_python_)s cat.py file15.in temp Building file15.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file15.out +%(_python_)s cat.py temp file15.out Building file16.out with action: $PYTHON cat.py $SOURCES temp -__PYTHON__ cat.py file16.in temp +%(_python_)s cat.py file16.in temp Building file16.out with action: $PYTHON cat.py temp $TARGET -__PYTHON__ cat.py temp file16.out +%(_python_)s cat.py temp file16.out Building file17.out with action: cat(target, source, env) cat(["file17.out"], ["file17.in"]) Building file18.out with action: cat(target, source, env) cat(["file18.out"], ["file18.in"]) -""" -expect = string.replace(expect, '__PYTHON__', TestSCons.python) +""" % locals() + test.run(arguments = "--debug=presub .", stdout=test.wrap_stdout(expect)) test.must_match('file01.out', "file01.in\n") diff --git a/test/option--implicit-cache.py b/test/option--implicit-cache.py deleted file mode 100644 index 2508cf2..0000000 --- a/test/option--implicit-cache.py +++ /dev/null @@ -1,374 +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__" - -import os -import sys -import TestSCons -import string - -_exe = TestSCons._exe -_obj = TestSCons._obj - -prog = 'prog' + _exe -subdir_prog = os.path.join('subdir', 'prog' + _exe) -variant_prog = os.path.join('variant', 'prog' + _exe) - -args = prog + ' ' + subdir_prog + ' ' + variant_prog - -test = TestSCons.TestSCons() - -test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2') - -test.write('SConstruct', """ -env = Environment(CPPPATH = Split('inc2 include')) -obj = env.Object(target='prog', source='subdir/prog.c') -env.Program(target='prog', source=obj) -SConscript('subdir/SConscript', "env") - -BuildDir('variant', 'subdir', 0) -include = Dir('include') -env = Environment(CPPPATH=['inc2', include]) -SConscript('variant/SConscript', "env") - -def copy(target, source, env): - open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read()) -nodep = env.Command('nodeps.c', 'nodeps.in', action=copy) -env.Program('nodeps', 'nodeps.c') - -env.Object(['one', 'two'], ['one.c']) -""") - -test.write(['subdir', 'SConscript'], -""" -Import("env") -env.Program(target='prog', source='prog.c') -""") - -test.write('nodeps.in', -r""" -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - return 0; -} -""") - - -test.write(['include', 'foo.h'], -r""" -#define FOO_STRING "include/foo.h 1\n" -#include -""") - -test.write(['include', 'bar.h'], -r""" -#define BAR_STRING "include/bar.h 1\n" -""") - -test.write(['include', 'baz.h'], -r""" -#define BAZ_STRING "include/baz.h 1\n" -""") - -test.write(['subdir', 'prog.c'], -r""" -#include -#include - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("subdir/prog.c\n"); - printf(FOO_STRING); - printf(BAR_STRING); - return 0; -} -""") - -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""" -#define BAR_STRING "subdir/include/bar.h 1\n" -""") - -test.write('one.c' , -r""" -#include - -void one(void) { } -""") - -test.run(arguments = "--implicit-cache " + args) - -test.run(program = test.workpath(prog), - stdout = "subdir/prog.c\ninclude/foo.h 1\ninclude/bar.h 1\n") - -test.run(program = test.workpath(subdir_prog), - stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") - -test.run(program = test.workpath(variant_prog), - stdout = "subdir/prog.c\ninclude/foo.h 1\ninclude/bar.h 1\n") - -test.up_to_date(arguments = args) - -# Make sure implicit dependenies work right when one is modifed: -test.write(['include', 'foo.h'], -r""" -#define FOO_STRING "include/foo.h 2\n" -#include "bar.h" -""") - -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") - -test.run(program = test.workpath(subdir_prog), - stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") - -test.run(program = test.workpath(variant_prog), - stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") - -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""" -#define FOO_STRING "include/foo.h 2\n" -#include "bar.h" -#include "baz.h" -""") - -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") - -test.run(program = test.workpath(subdir_prog), - stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") - -test.run(program = test.workpath(variant_prog), - stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") - -test.up_to_date(arguments = args) - -test.write(['include', 'foo.h'], -r""" -#define FOO_STRING "include/foo.h 2\n" -#include "baz.h" -#include "bar.h" -""") - -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") - -test.run(program = test.workpath(subdir_prog), - stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") - -test.run(program = test.workpath(variant_prog), - stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n") - -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""" -#define FOO_STRING "inc2/foo.h 1\n" -#include -""") - -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") - -test.run(program = test.workpath(subdir_prog), - stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") - -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""" -#define FOO_STRING "include/foo.h 3\n" -#include "bar.h" -""") - -test.run(arguments = "--implicit-cache " + args) - -test.run(program = test.workpath(prog), - stdout = "subdir/prog.c\ninc2/foo.h 1\ninclude/bar.h 1\n") - -test.run(program = test.workpath(subdir_prog), - stdout = "subdir/prog.c\nsubdir/include/foo.h 1\nsubdir/include/bar.h 1\n") - -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.run(arguments = "--implicit-cache nodeps%s"%_exe) - -test.write('nodeps.in', -r""" -#include - -int -main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - return 0; -} -""") - -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""" -#define FOO_STRING "include/foo.h 3\n" -#include "bar.h" -""") - -test.run(arguments = "--implicit-cache " + args) - -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.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 = variant_prog) -assert string.find(test.stdout(), 'is up to date') == -1, test.stdout() - -# Test forcing rescanning: -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""" -#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.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 - -void foo(void) -{ - FOO_H_DEFINED - ++x; /* reference x */ -} -""") - -test.write('i2/foo.h', """ -#define FOO_H_DEFINED int x = 1; -""") - -test.run() - -test.write('i1/foo.h', """ -"""); - -test.run() - - -test.pass_test() diff --git a/test/option--max-drift.py b/test/option--max-drift.py index bc26f33..1ac077a 100644 --- a/test/option--max-drift.py +++ b/test/option--max-drift.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -43,11 +43,11 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") @@ -59,8 +59,8 @@ test.run(arguments = 'f1.out') test.run(arguments = 'f1.out f2.out', stdout = test.wrap_stdout( """scons: `f1.out' is up to date. -%s build.py f2.out f2.in -""" % python)) +%(_python_)s build.py f2.out f2.in +""" % locals())) atime = os.path.getatime(test.workpath('f1.in')) mtime = os.path.getmtime(test.workpath('f1.in')) @@ -72,11 +72,12 @@ os.utime(test.workpath('f1.in'), (atime,mtime)) test.up_to_date(options='--max-drift=0', arguments='f1.out f2.out') -test.run(arguments = '--max-drift=-1 f1.out f2.out', - stdout = test.wrap_stdout( -"""%s build.py f1.out f1.in +expect = test.wrap_stdout( +"""%(_python_)s build.py f1.out f1.in scons: `f2.out' is up to date. -""" % python)) +""" % locals()) + +test.run(arguments = '--max-drift=-1 f1.out f2.out', stdout = expect) # Test that Set/GetOption('max_drift') works: test.write('SConstruct', """ @@ -99,10 +100,10 @@ test.run(arguments='--max-drift=1') # by mucking with the file timestamps to make SCons not realize the source has changed test.write('SConstruct', """ SetOption('max_drift', 0) -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.write('foo.in', 'foo.in\n') diff --git a/test/option-c.py b/test/option-c.py index 8814827..7ab4129 100644 --- a/test/option-c.py +++ b/test/option-c.py @@ -32,7 +32,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo1.out', source = 'foo1.in') env.B(target = 'foo2.out', source = 'foo2.xxx') @@ -67,7 +67,7 @@ if hasattr(os, 'symlink'): env.Command(['touch1.out', 'touch2.out'], [], [Touch('${TARGETS[0]}'), Touch('${TARGETS[1]}')]) -""" % python) +""" % locals()) test.write('foo1.in', "foo1.in\n") @@ -191,7 +191,7 @@ test.write(['subd', 'foox.in'], "foox.in\n") test.write('aux1.x', "aux1.x\n") test.write('aux2.x', "aux2.x\n") test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }, FOO = 'foo2') env.B(target = 'foo1.out', source = 'foo1.in') env.B(target = 'foo2.out', source = 'foo2.xxx') @@ -201,7 +201,7 @@ SConscript('subd/SConscript') Clean(foo2_xxx, ['aux1.x']) env.Clean(['${FOO}.xxx'], ['aux2.x']) Clean('.', ['subd']) -""" % python) +""" % locals()) test.write(['subd', 'SConscript'], """ Clean('.', 'foox.in') @@ -248,12 +248,12 @@ test.must_not_exist(test.workpath('subdir')) # Ensure that Set/GetOption('clean') works correctly: test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') assert not GetOption('clean') -"""%python) +""" % locals()) test.write('foo.in', '"Foo", I say!\n') @@ -261,36 +261,36 @@ test.run(arguments='foo.out') test.must_match(test.workpath('foo.out'), '"Foo", I say!\n') test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') assert GetOption('clean') SetOption('clean', 0) assert GetOption('clean') -"""%python) +""" % locals()) test.run(arguments='-c foo.out') test.must_not_exist(test.workpath('foo.out')) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -"""%python) +""" % locals()) test.run(arguments='foo.out') test.must_match(test.workpath('foo.out'), '"Foo", I say!\n') test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') assert not GetOption('clean') SetOption('clean', 1) assert GetOption('clean') -"""%python) +""" % locals()) test.run(arguments='foo.out') test.must_not_exist(test.workpath('foo.out')) diff --git a/test/option-i.py b/test/option-i.py index b0a84f8..a4ea4ac 100644 --- a/test/option-i.py +++ b/test/option-i.py @@ -28,7 +28,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,14 +46,14 @@ sys.exit(1) """) test.write('SConstruct', """ -Succeed = Builder(action = r'%s succeed.py $TARGETS') -Fail = Builder(action = r'%s fail.py $TARGETS') +Succeed = Builder(action = r'%(_python_)s succeed.py $TARGETS') +Fail = Builder(action = r'%(_python_)s fail.py $TARGETS') env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail(target = 'aaa.1', source = 'aaa.in') env.Succeed(target = 'aaa.out', source = 'aaa.1') env.Fail(target = 'bbb.1', source = 'bbb.in') env.Succeed(target = 'bbb.out', source = 'bbb.1') -""" % (python, python)) +""" % locals()) test.write('aaa.in', "aaa.in\n") test.write('bbb.in', "bbb.in\n") diff --git a/test/option-j.py b/test/option-j.py index fdf7b83..8f4c190 100644 --- a/test/option-j.py +++ b/test/option-j.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ try: import threading @@ -64,7 +64,7 @@ foo you """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') @@ -80,7 +80,7 @@ t = env.Command(target=['foo/foo1.out', 'foo/foo2.out'], source='foo/foo.in', action=copyn) env.Install('out', t) -""" % python) +""" % locals()) def RunTest(args, extra): """extra is used to make scons rebuild the output file""" @@ -160,7 +160,7 @@ os.environ['PYTHONPATH'] = save_pythonpath # Test SetJobs() with no -j: test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') @@ -178,7 +178,7 @@ env.Install('out', t) assert GetOption('num_jobs') == 1 SetOption('num_jobs', 2) assert GetOption('num_jobs') == 2 -""" % python) +""" % locals()) # This should be a parallel build because the SConscript sets jobs to 2. # fail if the second file was not started @@ -188,7 +188,7 @@ test.fail_test(not (start2 < finish1)) # Test SetJobs() with -j: test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') @@ -206,7 +206,7 @@ env.Install('out', t) assert GetOption('num_jobs') == 1 SetOption('num_jobs', 2) assert GetOption('num_jobs') == 1 -""" % python) +""" % locals()) # This should be a serial build since -j 1 overrides the call to SetJobs(). # fail if the second file was started @@ -230,14 +230,14 @@ sys.exit(1) """) test.write('SConstruct', """ -MyCopy = Builder(action = r'%s mycopy.py $TARGET $SOURCE') -Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE') +MyCopy = Builder(action = r'%(_python_)s mycopy.py $TARGET $SOURCE') +Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE') env = Environment(BUILDERS = { 'MyCopy' : MyCopy, 'Fail' : Fail }) env.Fail(target = 'f3', source = 'f3.in') env.MyCopy(target = 'f4', source = 'f4.in') env.MyCopy(target = 'f5', source = 'f5.in') env.MyCopy(target = 'f6', source = 'f6.in') -""" % (python, python)) +""" % locals()) test.write('f3.in', "f3.in\n") test.write('f4.in', "f4.in\n") diff --git a/test/option-k.py b/test/option-k.py index 45c31d2..0a46606 100644 --- a/test/option-k.py +++ b/test/option-k.py @@ -28,7 +28,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,13 +50,13 @@ sys.exit(1) """) test.write(['work1', 'SConstruct'], """\ -Succeed = Builder(action = r'%s ../succeed.py $TARGETS') -Fail = Builder(action = r'%s ../fail.py $TARGETS') +Succeed = Builder(action = r'%(_python_)s ../succeed.py $TARGETS') +Fail = Builder(action = r'%(_python_)s ../fail.py $TARGETS') env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail(target = 'aaa.1', source = 'aaa.in') env.Succeed(target = 'aaa.out', source = 'aaa.1') env.Succeed(target = 'bbb.out', source = 'bbb.in') -""" % (python, python)) +""" % locals()) test.write(['work1', 'aaa.in'], "aaa.in\n") test.write(['work1', 'bbb.in'], "bbb.in\n") @@ -93,14 +93,14 @@ test.must_match(['work1', 'bbb.out'], "succeed.py: bbb.out\n") test.write(['work2', 'SConstruct'], """\ -Succeed = Builder(action = r'%s ../succeed.py $TARGETS') -Fail = Builder(action = r'%s ../fail.py $TARGETS') +Succeed = Builder(action = r'%(_python_)s ../succeed.py $TARGETS') +Fail = Builder(action = r'%(_python_)s ../fail.py $TARGETS') env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail('aaa.out', 'aaa.in') env.Succeed('bbb.out', 'aaa.out') env.Succeed('ccc.out', 'ccc.in') env.Succeed('ddd.out', 'ccc.in') -""" % (python, python)) +""" % locals()) test.write(['work2', 'aaa.in'], "aaa.in\n") test.write(['work2', 'ccc.in'], "ccc.in\n") @@ -113,11 +113,11 @@ test.run(chdir = 'work2', scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... -%s ../fail.py aaa.out -%s ../succeed.py ccc.out -%s ../succeed.py ddd.out +%(_python_)s ../fail.py aaa.out +%(_python_)s ../succeed.py ccc.out +%(_python_)s ../succeed.py ddd.out scons: done building targets (errors occurred during build). -""" % (python, python, python)) +""" % locals()) test.must_not_exist(['work2', 'aaa.out']) test.must_not_exist(['work2', 'bbb.out']) diff --git a/test/option-n.py b/test/option-n.py index 769c4dd..2e7694b 100644 --- a/test/option-n.py +++ b/test/option-n.py @@ -47,7 +47,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,14 +61,14 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGETS') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') env.Install('install', 'f3.in') BuildDir('build', 'src', duplicate=1) SConscript('build/SConscript', "env") -""" % python) +""" % locals()) test.write(['src', 'SConscript'], """ Import("env") @@ -82,9 +82,9 @@ test.write(['src', 'f4.in'], "src/f4.in\n") args = 'f1.out f2.out' expect = test.wrap_stdout("""\ -%s build.py f1.out -%s build.py f2.out -""" % (python, python)) +%(_python_)s build.py f1.out +%(_python_)s build.py f2.out +""" % locals()) test.run(arguments = args, stdout = expect) test.fail_test(not os.path.exists(test.workpath('f1.out'))) @@ -118,8 +118,8 @@ test.fail_test(not os.path.exists(test.workpath('f1.out'))) # Test that SCons does not write a modified .sconsign when -n is used. expect = test.wrap_stdout("""\ -%s build.py f1.out -""" % python) +%(_python_)s build.py f1.out +""" % locals()) test.unlink('.sconsign.dblite') test.write('f1.out', "X1.out\n") test.run(arguments = '-n f1.out', stdout = expect) diff --git a/test/option-q.py b/test/option-q.py index e8460f0..9b67d0a 100644 --- a/test/option-q.py +++ b/test/option-q.py @@ -34,7 +34,7 @@ import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.write('build.py', r""" import sys @@ -45,11 +45,11 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action=r'%s build.py $TARGET $SOURCES') +B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'aaa.out', source = 'aaa.in') env.B(target = 'bbb.out', source = 'bbb.in') -""" % python) +""" % locals()) test.write('aaa.in', "aaa.in\n") test.write('bbb.in', "bbb.in\n") diff --git a/test/option-s.py b/test/option-s.py index c1061ba..b3bde5f 100644 --- a/test/option-s.py +++ b/test/option-s.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,11 +41,11 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(action = r'%s build.py $TARGET') +MyBuild = Builder(action = r'%(_python_)s build.py $TARGET') env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") diff --git a/test/option/debug-dtree.py b/test/option/debug-dtree.py index 0a7f4d2..06296b9 100644 --- a/test/option/debug-dtree.py +++ b/test/option/debug-dtree.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-findlibs.py b/test/option/debug-findlibs.py index b18841b..4220402 100644 --- a/test/option/debug-findlibs.py +++ b/test/option/debug-findlibs.py @@ -24,12 +24,15 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons import sys import string import re import time +import TestSCons + +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.subdir('sub1', 'sub2') @@ -49,9 +52,9 @@ env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx', LIBS = ['iii', 'jjj', 'kkk', 'lll', 'mmm'], LIBPREFIXES = ['a-', 'b-', 'c-'], LIBSUFFIXES = ['.aaa', '.bbb', '.ccc'], - LINKCOM = '%(python)s cat.py $TARGET $SOURCES') + LINKCOM = '%(_python_)s cat.py $TARGET $SOURCES') env.Program('foo', 'a.ooo',) -""" % {'python' : TestSCons.python}) +""" % locals()) test.write('a.ooo', "a.ooo\n") @@ -198,8 +201,8 @@ test.run(arguments = "--debug=findlibs foo.xxx", findlibs: looking for 'c-mmm.ccc' in 'sub1' ... findlibs: looking for 'c-mmm.ccc' in 'sub2' ... findlibs: looking for 'c-mmm.ccc' in '.' ... -%(python)s cat.py foo.xxx a.ooo -""" % {'python' : TestSCons.python})) +%(_python_)s cat.py foo.xxx a.ooo +""" % locals())) test.must_match('foo.xxx', "a.ooo\n") diff --git a/test/option/debug-includes.py b/test/option/debug-includes.py index eb7f818..52d64a9 100644 --- a/test/option/debug-includes.py +++ b/test/option/debug-includes.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-stacktrace.py b/test/option/debug-stacktrace.py index 1a3052a..aff25f2 100644 --- a/test/option/debug-stacktrace.py +++ b/test/option/debug-stacktrace.py @@ -114,4 +114,25 @@ if err and must_contain_all_lines(test.stderr(), inner_lines): +# Test that full path names to SConscript files show up in stack traces. + +test.write('SConstruct', """\ +1/0 +""") + +test.run(arguments = '--debug=stacktrace', + status = 2, + stderr = None) + +lines = [ + ' File "%s", line 1:' % test.workpath('SConstruct'), +] + +err = must_contain_all_lines(test.stderr(), lines) +if err: + print string.join(err, '') + test.fail_test(1) + + + test.pass_test() diff --git a/test/option/debug-stree.py b/test/option/debug-stree.py index 69aab06..8ffadc6 100644 --- a/test/option/debug-stree.py +++ b/test/option/debug-stree.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-time.py b/test/option/debug-time.py index 5766cff..b1471ba 100644 --- a/test/option/debug-time.py +++ b/test/option/debug-time.py @@ -38,6 +38,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-tree.py b/test/option/debug-tree.py index faf85d9..4f025c2 100644 --- a/test/option/debug-tree.py +++ b/test/option/debug-tree.py @@ -47,6 +47,8 @@ env.Program('Foo', Split('Foo.c Bar.c')) # (UNIX/Linux) and case-insensitive (Windows) systems. test.write('Foo.c', r""" +#include +#include #include "Foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/profile.py b/test/option/profile.py index b6a0027..9207066 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -33,7 +33,11 @@ import TestSCons test = TestSCons.TestSCons() -test.write('SConstruct', "\n") +test.write('SConstruct', """\ +Command('file.out', 'file.in', Copy("$TARGET", "$SOURCE")) +""") + +test.write('file.in', "file.in\n") scons_prof = test.workpath('scons.prof') @@ -63,30 +67,30 @@ test.fail_test(string.find(s, 'option_parser.py') == -1) scons_prof = test.workpath('scons2.prof') -test.run(arguments = "--profile %s -h" % scons_prof) -test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1) -test.fail_test(string.find(test.stdout(), 'Options:') == -1) +test.run(arguments = "--profile %s" % scons_prof) stats = pstats.Stats(scons_prof) stats.sort_stats('time') -sys.stdout = StringIO.StringIO() +try: + save_stdout = sys.stdout + sys.stdout = StringIO.StringIO() -stats.strip_dirs().print_stats() + stats.strip_dirs().print_stats() -s = sys.stdout.getvalue() + s = sys.stdout.getvalue() +finally: + sys.stdout = save_stdout test.fail_test(string.find(s, 'Main.py') == -1) -test.fail_test(string.find(s, 'print_help') == -1) test.fail_test(string.find(s, '_main') == -1) -test.fail_test(string.find(s, 'option_parser.py') == -1) +test.fail_test(string.find(s, 'FS.py') == -1) scons_prof = test.workpath('scons3.prof') test.run(arguments = "--profile %s --debug=memory -h" % scons_prof) -print test.stdout() test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1) test.fail_test(string.find(test.stdout(), 'Options:') == -1) diff --git a/test/overrides.py b/test/overrides.py index 69f7440..dabf689 100644 --- a/test/overrides.py +++ b/test/overrides.py @@ -31,7 +31,7 @@ import sys test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.write('SConstruct', """ env = Environment(CCFLAGS='-DFOO', LIBS=['a']) @@ -69,11 +69,11 @@ env['LIBS'] = buildlibs test.write('SConstruct', """ env = Environment() env.Program('hello', 'hello.c', - CC=r'%s mycc.py', - LINK=r'%s mylink.py', + CC=r'%(_python_)s mycc.py', + LINK=r'%(_python_)s mylink.py', OBJSUFFIX='.not_obj', PROGSUFFIX='.not_exe') -"""%(python,python)) +""" % locals()) test.write('hello.c',"this ain't no c file!\n") @@ -97,13 +97,13 @@ test.up_to_date(arguments='hello.not_exe') test.write('SConstruct', """\ env = Environment() env.Program('goodbye', 'goodbye.c', - CC=r'%s mycc.py', - LINK=r'%s mylink.py', + CC=r'%(_python_)s mycc.py', + LINK=r'%(_python_)s mylink.py', OBJSUFFIX='.not_obj', PROGSUFFIX='.not_exe', targets='ttt', sources='sss') -""" % (python, python)) +""" % locals()) test.write('goodbye.c',"this ain't no c file!\n") diff --git a/test/parallel-rescan.py b/test/parallel-rescan.py deleted file mode 100644 index 4a1f27e..0000000 --- a/test/parallel-rescan.py +++ /dev/null @@ -1,72 +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__" - -""" -Verify that when a source file is generated and the -j option is used, -the source file correctly gets re-scanned for implicit dependencies -after it's built. -""" - -import TestSCons - -test = TestSCons.TestSCons() - -test.write('SConstruct', """\ -env = Environment() -env['BUILDERS']['COPY'] = Builder(action = Copy("$TARGET", "$SOURCE")) - -env.COPY('a.c', 'a.in') -env.COPY('b.c', 'b.in') - -env.StaticLibrary('lib', ['a.c', 'b.c']) -""") - -test.write("a.in", """\ -#include "a.h" -""") - -test.write("b.in", """\ -#include "b.h" -""") - -test.write("a.h", """\ -char *A_FILE = "b.in"; -""") - -test.write("b.h", """\ -char *B_FILE = "b.in"; -""") - -test.run(arguments = '-j4 .', - stderr=TestSCons.noisy_ar, - match=TestSCons.match_re_dotall) - -# If the dependencies weren't re-scanned properly, the .h files won't -# show up in the previous run's dependency lists, and the .o files and -# library will get rebuilt here. -test.up_to_date(arguments = '.') - -test.pass_test() diff --git a/test/redirection.py b/test/redirection.py index 5aac517..cededdb 100644 --- a/test/redirection.py +++ b/test/redirection.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,14 +44,14 @@ sys.exit(0) test.write('SConstruct', r""" env = Environment() env.Command(target='foo1', source='bar1', - action= '%s cat.py $SOURCES > $TARGET') + action= '%(_python_)s cat.py $SOURCES > $TARGET') env.Command(target='foo2', source='bar2', - action= '%s cat.py < $SOURCES > $TARGET') + action= '%(_python_)s cat.py < $SOURCES > $TARGET') env.Command(target='foo3', source='bar3', - action='%s cat.py $SOURCES | %s cat.py > $TARGET') + action='%(_python_)s cat.py $SOURCES | %(_python_)s cat.py > $TARGET') env.Command(target='foo4', source='bar4', - action='%s cat.py <$SOURCES |%s cat.py >$TARGET') -""" % (python, python, python, python, python, python)) + action='%(_python_)s cat.py <$SOURCES |%(_python_)s cat.py >$TARGET') +""" % locals()) test.write('bar1', 'bar1\r\n') test.write('bar2', 'bar2\r\n') diff --git a/test/runtest/aegis/batch-output.py b/test/runtest/aegis/batch-output.py new file mode 100644 index 0000000..4020239 --- /dev/null +++ b/test/runtest/aegis/batch-output.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test writing Aegis batch output to a file. +""" + +import TestRuntest + +test = TestRuntest.TestRuntest() + +test.subdir('test') + +test.write_failing_test(['test', 'fail.py']) + +test.write_no_result_test(['test', 'no_result.py']) + +test.write_passing_test(['test', 'pass.py']) + +test.run(arguments = '-o aegis.out --aegis test', status=1) + +expect = """\ +test_result = [ + { file_name = "test/fail.py"; + exit_status = 1; }, + { file_name = "test/no_result.py"; + exit_status = 2; }, + { file_name = "test/pass.py"; + exit_status = 0; }, +]; +""" + +# The mode is 'r' (not default 'rb') because QMTest opens the file +# description on which we write as non-binary. +test.must_match('aegis.out', expect, mode='r') + +test.pass_test() diff --git a/test/runtest/baseline/combined.py b/test/runtest/baseline/combined.py index 6382cb1..ab91e87 100644 --- a/test/runtest/baseline/combined.py +++ b/test/runtest/baseline/combined.py @@ -30,8 +30,14 @@ Test a combination of a passing test, failing test, and no-result test with no argument on the command line. """ +import os.path + import TestRuntest +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') +test_pass_py = os.path.join('test', 'pass.py') + test = TestRuntest.TestRuntest() test.subdir('test') @@ -45,37 +51,37 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test --- TEST RESULTS ------------------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL FAILING TEST STDOUT FAILING TEST STDERR - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT NO RESULT TEST STDERR - test/pass.py : PASS + %(test_pass_py)s : PASS --- TESTS WITH UNEXPECTED OUTCOMES ------------------------------------------- - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT - test/pass.py : PASS + %(test_pass_py)s : PASS --- STATISTICS --------------------------------------------------------------- - 1 ( 33%) tests as expected - 1 ( 33%) tests unexpected PASS - 1 ( 33%) tests unexpected NO_RESULT -""" + 1 ( 33%%) tests as expected + 1 ( 33%%) tests unexpected PASS + 1 ( 33%%) tests unexpected NO_RESULT +""" % locals() -test.run(arguments = '--qmtest -b . test', stdout = expect) +test.run(arguments = '-b . test', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/baseline/fail.py b/test/runtest/baseline/fail.py index b650a8c..b61e5da 100644 --- a/test/runtest/baseline/fail.py +++ b/test/runtest/baseline/fail.py @@ -38,7 +38,7 @@ test.write_failing_test(['test', 'fail.py']) # NOTE: The "test/fail.py : FAIL" line has spaces at the end. -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/fail.py +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/fail.py --- TEST RESULTS ------------------------------------------------------------- test/fail.py : FAIL @@ -57,6 +57,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 1 (100%) tests as expected """ -test.run(arguments = '--qmtest -b . test/fail.py', stdout = expect) +test.run(arguments = '-b . test/fail.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/baseline/no_result.py b/test/runtest/baseline/no_result.py index dc2586d..9ef815d 100644 --- a/test/runtest/baseline/no_result.py +++ b/test/runtest/baseline/no_result.py @@ -36,7 +36,7 @@ test.subdir('test') test.write_no_result_test(['test', 'no_result.py']) -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/no_result.py +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/no_result.py --- TEST RESULTS ------------------------------------------------------------- test/no_result.py : NO_RESULT @@ -55,6 +55,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 1 (100%) tests unexpected NO_RESULT """ -test.run(arguments = '--qmtest -b . test/no_result.py', stdout = expect) +test.run(arguments = '-b . test/no_result.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/baseline/pass.py b/test/runtest/baseline/pass.py index b32ecbe..f574e57 100644 --- a/test/runtest/baseline/pass.py +++ b/test/runtest/baseline/pass.py @@ -38,7 +38,7 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/pass.py : PASS" line has spaces at the end. -expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/pass.py +expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/pass.py --- TEST RESULTS ------------------------------------------------------------- test/pass.py : PASS @@ -53,6 +53,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 1 (100%) tests unexpected PASS """ -test.run(arguments = '--qmtest -b . test/pass.py', stdout = expect) +test.run(arguments = '-b . test/pass.py', stdout = expect) test.pass_test() diff --git a/test/runtest/fallback.py b/test/runtest/fallback.py new file mode 100644 index 0000000..90cd4f2 --- /dev/null +++ b/test/runtest/fallback.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that runtest.py falls back (with a warning) using --noqmtest +if it can't find qmtest.py on the $PATH. +""" + +import os +import os.path +import re +import string + +import TestRuntest + +python = TestRuntest.python +_python_ = TestRuntest._python_ + +test = TestRuntest.TestRuntest(noqmtest=1) + +qmtest_py = test.where_is('qmtest.py') + +if qmtest_py: + dir = os.path.split(qmtest_py)[0] + path = string.split(os.environ['PATH'], os.pathsep) + path.remove(dir) + os.environ['PATH'] = string.join(path, os.pathsep) + +test.subdir('test') + +test_pass_py = os.path.join('test', 'pass.py') +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') + +workpath_pass_py = test.workpath(test_pass_py) +workpath_fail_py = test.workpath(test_fail_py) +workpath_no_result_py = test.workpath(test_no_result_py) + +test.write_failing_test(test_fail_py) +test.write_no_result_test(test_no_result_py) +test.write_passing_test(test_pass_py) + +if re.search('\s', python): + expect_python = _python_ +else: + expect_python = python + +expect_stdout = """\ +%(expect_python)s -tt %(workpath_fail_py)s +FAILING TEST STDOUT +%(expect_python)s -tt %(workpath_no_result_py)s +NO RESULT TEST STDOUT +%(expect_python)s -tt %(workpath_pass_py)s +PASSING TEST STDOUT + +Failed the following test: +\t%(test_fail_py)s + +NO RESULT from the following test: +\t%(test_no_result_py)s +""" % locals() + +expect_stderr = """\ +Warning: qmtest.py not found on $PATH, assuming --noqmtest option. +FAILING TEST STDERR +NO RESULT TEST STDERR +PASSING TEST STDERR +""" + +testlist = [ + test_fail_py, + test_no_result_py, + test_pass_py, +] + +test.run(arguments = string.join(testlist), + status = 1, + stdout = expect_stdout, + stderr = expect_stderr) + +test.pass_test() diff --git a/test/runtest/noqmtest.py b/test/runtest/noqmtest.py new file mode 100644 index 0000000..c442125 --- /dev/null +++ b/test/runtest/noqmtest.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --noqmtest option invokes tests directly via Python, not +using qmtest. +""" + +import os.path +import re +import string + +import TestRuntest + +python = TestRuntest.python +_python_ = TestRuntest._python_ + +test = TestRuntest.TestRuntest(noqmtest=1) + +test.subdir('test') + +test_pass_py = os.path.join('test', 'pass.py') +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') + +workpath_pass_py = test.workpath(test_pass_py) +workpath_fail_py = test.workpath(test_fail_py) +workpath_no_result_py = test.workpath(test_no_result_py) + +test.write_failing_test(test_fail_py) +test.write_no_result_test(test_no_result_py) +test.write_passing_test(test_pass_py) + +if re.search('\s', python): + expect_python = _python_ +else: + expect_python = python + +expect_stdout = """\ +%(expect_python)s -tt %(workpath_fail_py)s +FAILING TEST STDOUT +%(expect_python)s -tt %(workpath_no_result_py)s +NO RESULT TEST STDOUT +%(expect_python)s -tt %(workpath_pass_py)s +PASSING TEST STDOUT + +Failed the following test: +\t%(test_fail_py)s + +NO RESULT from the following test: +\t%(test_no_result_py)s +""" % locals() + +expect_stderr = """\ +FAILING TEST STDERR +NO RESULT TEST STDERR +PASSING TEST STDERR +""" + +testlist = [ + test_fail_py, + test_no_result_py, + test_pass_py, +] + +test.run(arguments = '--noqmtest %s' % string.join(testlist), + status = 1, + stdout = expect_stdout, + stderr = expect_stderr) + +test.pass_test() diff --git a/test/runtest/print_time.py b/test/runtest/print_time.py index 1d86baa..39bf810 100644 --- a/test/runtest/print_time.py +++ b/test/runtest/print_time.py @@ -29,9 +29,16 @@ Test a combination of a passing test, failing test, and no-result test with no argument on the command line. """ +import os.path +import re + import TestCmd import TestRuntest +test_fail_py = re.escape(os.path.join('test', 'fail.py')) +test_no_result_py = re.escape(os.path.join('test', 'no_result.py')) +test_pass_py = re.escape(os.path.join('test', 'pass.py')) + test = TestRuntest.TestRuntest(match = TestCmd.match_re) test.subdir('test') @@ -45,10 +52,10 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream --context print_time=1 test +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream\(print_time='1'\)" test --- TEST RESULTS ------------------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL FAILING TEST STDOUT @@ -56,7 +63,7 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc Total execution time: \d+\.\d+ seconds - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT @@ -64,26 +71,26 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc Total execution time: \d+\.\d+ seconds - test/pass.py : PASS + %(test_pass_py)s : PASS Total execution time: \d+\.\d+ seconds --- TESTS THAT DID NOT PASS -------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT --- STATISTICS --------------------------------------------------------------- 3 tests total - 1 \( 33%\) tests PASS - 1 \( 33%\) tests FAIL - 1 \( 33%\) tests NO_RESULT -""" + 1 \( 33%%\) tests PASS + 1 \( 33%%\) tests FAIL + 1 \( 33%%\) tests NO_RESULT +""" % locals() -test.run(arguments = '--qmtest -t test', stdout = expect) +test.run(arguments = '-t test', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/python.py b/test/runtest/python.py index 76eec7d..1af32dd 100644 --- a/test/runtest/python.py +++ b/test/runtest/python.py @@ -28,35 +28,40 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test that the -P option lets us specify a Python version to use. """ +import os.path +import re +import sys + +if not hasattr(os.path, 'pardir'): + os.path.pardir = '..' + import TestRuntest test = TestRuntest.TestRuntest() -mypython_py = test.workpath('mypython.py') -mypython_out = test.workpath('mypython.out') +test_pass_py = os.path.join('test', 'pass.py') -test.subdir('test') +head, python = os.path.split(TestRuntest.python) +head, dir = os.path.split(head) -test.write_passing_test(['test', 'pass.py']) +mypython = os.path.join(head, dir, os.path.pardir, dir, python) -test.write(mypython_py, """\ -#!/usr/bin/env python -import os -import sys -import string -open(r'%s', 'a').write(string.join(sys.argv) + '\\n') -os.system(string.join([sys.executable] + sys.argv[1:])) -""" % mypython_out) +if re.search('\s', mypython): + _mypython_ = '"' + mypython + '"' +else: + _mypython_ = mypython -test.chmod(mypython_py, 0755) +test.subdir('test') + +test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream --context python=%(mypython_py)s test +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" --context python="%(mypython)s" test --- TEST RESULTS ------------------------------------------------------------- - test/pass.py : PASS + %(test_pass_py)s : PASS --- TESTS THAT DID NOT PASS -------------------------------------------------- @@ -70,11 +75,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%%) tests PASS """ % locals() -test.run(arguments = '--qmtest -P %s test' % mypython_py, - stdout = expect) - -test.must_match(mypython_out, """\ -%s ./test/pass.py -""" % mypython_py) +test.run(arguments = '-P %s test' % _mypython_, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/combined.py b/test/runtest/simple/combined.py index 1640d94..58d2f27 100644 --- a/test/runtest/simple/combined.py +++ b/test/runtest/simple/combined.py @@ -30,10 +30,16 @@ Test a combination of a passing test, failing test, and no-result test with no argument on the command line. """ +import os.path + import TestRuntest test = TestRuntest.TestRuntest() +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') +test_pass_py = os.path.join('test', 'pass.py') + test.subdir('test') test.write_failing_test(['test', 'fail.py']) @@ -45,39 +51,39 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both # have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test --- TEST RESULTS ------------------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL FAILING TEST STDOUT FAILING TEST STDERR - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT NO RESULT TEST STDERR - test/pass.py : PASS + %(test_pass_py)s : PASS --- TESTS THAT DID NOT PASS -------------------------------------------------- - test/fail.py : FAIL + %(test_fail_py)s : FAIL - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT --- STATISTICS --------------------------------------------------------------- 3 tests total - 1 ( 33%) tests PASS - 1 ( 33%) tests FAIL - 1 ( 33%) tests NO_RESULT -""" + 1 ( 33%%) tests PASS + 1 ( 33%%) tests FAIL + 1 ( 33%%) tests NO_RESULT +""" % locals() -test.run(arguments = '--qmtest test', stdout = expect) +test.run(arguments = 'test', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/fail.py b/test/runtest/simple/fail.py index ba2cc97..ec9f532 100644 --- a/test/runtest/simple/fail.py +++ b/test/runtest/simple/fail.py @@ -38,7 +38,7 @@ test.write_failing_test(['test', 'fail.py']) # NOTE: The "test/fail.py : FAIL" line has spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/fail.py +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/fail.py --- TEST RESULTS ------------------------------------------------------------- test/fail.py : FAIL @@ -59,6 +59,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests FAIL """ -test.run(arguments = '--qmtest test/fail.py', stdout = expect) +test.run(arguments = 'test/fail.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/no_result.py b/test/runtest/simple/no_result.py index 7c9687e..4ec6e78 100644 --- a/test/runtest/simple/no_result.py +++ b/test/runtest/simple/no_result.py @@ -36,7 +36,7 @@ test.subdir('test') test.write_no_result_test(['test', 'no_result.py']) -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/no_result.py +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/no_result.py --- TEST RESULTS ------------------------------------------------------------- test/no_result.py : NO_RESULT @@ -57,6 +57,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests NO_RESULT """ -test.run(arguments = '--qmtest test/no_result.py', stdout = expect) +test.run(arguments = 'test/no_result.py', status = 1, stdout = expect) test.pass_test() diff --git a/test/runtest/simple/pass.py b/test/runtest/simple/pass.py index 8dfc996..c3a8b02 100644 --- a/test/runtest/simple/pass.py +++ b/test/runtest/simple/pass.py @@ -38,7 +38,7 @@ test.write_passing_test(['test', 'pass.py']) # NOTE: The "test/pass.py : PASS" line has spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/pass.py +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/pass.py --- TEST RESULTS ------------------------------------------------------------- test/pass.py : PASS @@ -55,6 +55,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests PASS """ -test.run(arguments = '--qmtest test/pass.py', stdout = expect) +test.run(arguments = 'test/pass.py', stdout = expect) test.pass_test() diff --git a/test/runtest/src.py b/test/runtest/src.py index 2f723b4..3063a4e 100644 --- a/test/runtest/src.py +++ b/test/runtest/src.py @@ -29,6 +29,8 @@ Verify that we find tests under the src/ tree only if they end with *Tests.py. """ +import os.path + import TestRuntest test = TestRuntest.TestRuntest(verbose=1) @@ -36,6 +38,9 @@ test = TestRuntest.TestRuntest(verbose=1) test.subdir(['src'], ['src', 'suite']) +src_passTests_py = os.path.join('src', 'passTests.py') +src_suite_passTests_py = os.path.join('src', 'suite', 'passTests.py') + test.write_passing_test(['src', 'pass.py']) test.write_passing_test(['src', 'passTests.py']) @@ -44,15 +49,15 @@ test.write_passing_test(['src', 'suite', 'pass.py']) test.write_passing_test(['src', 'suite', 'passTests.py']) -# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both -# have spaces at the end. +# NOTE: The "test/pass.py : PASS" and "test/passTests.py : PASS" lines +# both have spaces at the end. -expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream src +expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" src --- TEST RESULTS ------------------------------------------------------------- - src/passTests.py : PASS + %(src_passTests_py)s : PASS - src/suite/passTests.py : PASS + %(src_suite_passTests_py)s : PASS --- TESTS THAT DID NOT PASS -------------------------------------------------- @@ -63,9 +68,9 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 2 tests total - 2 (100%) tests PASS -""" + 2 (100%%) tests PASS +""" % locals() -test.run(arguments = '--qmtest src', stdout = expect) +test.run(arguments = 'src', stdout = expect) test.pass_test() diff --git a/test/runtest/testlistfile.py b/test/runtest/testlistfile.py new file mode 100644 index 0000000..d738530 --- /dev/null +++ b/test/runtest/testlistfile.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test a list of tests to run in a file specified with the -f option. +""" + +import os.path + +import TestCmd +import TestRuntest + +test_fail_py = os.path.join('test', 'fail.py') +test_no_result_py = os.path.join('test', 'no_result.py') +test_pass_py = os.path.join('test', 'pass.py') + +test = TestRuntest.TestRuntest() + +test.subdir('test') + +test.write_failing_test(['test', 'fail.py']) + +test.write_no_result_test(['test', 'no_result.py']) + +test.write_passing_test(['test', 'pass.py']) + +test.write('t.txt', """\ +#%(test_fail_py)s +%(test_pass_py)s +""" % locals()) + +# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both +# have spaces at the end. + +expect = """qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" %(test_pass_py)s +--- TEST RESULTS ------------------------------------------------------------- + + %(test_pass_py)s : PASS + +--- TESTS THAT DID NOT PASS -------------------------------------------------- + + None. + + +--- STATISTICS --------------------------------------------------------------- + + 1 tests total + + 1 (100%%) tests PASS +""" % locals() + +test.run(arguments = '-f t.txt', stdout = expect) + +test.pass_test() diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py new file mode 100644 index 0000000..e1c14cf --- /dev/null +++ b/test/runtest/xml/output.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test writing XML output to a file. +""" + +import os.path +import re +import sys + +import TestRuntest + +test = TestRuntest.TestRuntest() + +test_fail_py = re.escape(os.path.join('test', 'fail.py')) +test_no_result_py = re.escape(os.path.join('test', 'no_result.py')) +test_pass_py = re.escape(os.path.join('test', 'pass.py')) + +# sys.stdout and sys.stderr are open non-binary ('w' instead of 'wb') +# so the lines written on Windows are terminated \r\n, not just \n. The +# expressions below use 'cr' as the optional carriage return character. +if sys.platform in ['win32']: + cr = '\r' +else: + cr = '' + +test.subdir('test') + +test.write_fake_scons_source_tree() + +test.write_failing_test(['test', 'fail.py']) + +test.write_no_result_test(['test', 'no_result.py']) + +test.write_passing_test(['test', 'pass.py']) + +test.run(arguments = '-o xml.out --xml test', status = 1) + +expect_engine = """\ + + __build__='D456' + __buildsys__='another_fake_system' + __date__='Dec 31 1999' + __developer__='John Doe' + __version__='4\\.5\\.6' + +""" + +expect_script = """\ + + __build__='D123' + __buildsys__='fake_system' + __date__='Jan 1 1970' + __developer__='Anonymous' + __version__='1\\.2\\.3' + +""" + +# 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 = """\ + +""" + +expect_os_environ = """\ + +""" + +expect_fail = """\ + + + "1" + + + "<pre>FAILING TEST STDERR%(cr)s +</pre>" + + + "<pre>FAILING TEST STDOUT%(cr)s +</pre>" + + + "Non-zero exit_code\\." + + + "[\\d.]+" + + + "[\\d.]+" + + + "local" + + +""" % locals() + +expect_no_result = """\ + + + "2" + + + "<pre>NO RESULT TEST STDERR%(cr)s +</pre>" + + + "<pre>NO RESULT TEST STDOUT%(cr)s +</pre>" + + + "Non-zero exit_code\\." + + + "[\\d.]+" + + + "[\\d.]+" + + + "local" + + +""" % locals() + +expect_pass = """\ + + + "[\\d.]+" + + + "[\\d.]+" + + + "local" + + +""" % locals() + +xml_out = test.read('xml.out', 'r') + +expect = [ + expect_engine, + expect_script, + expect_sys, + expect_os_environ, + expect_fail, + expect_no_result, + expect_pass, +] + +non_matches = [] + +for e in expect: + if not re.search(e, xml_out): + non_matches.append(e) + +if non_matches: + for n in non_matches: + print "DID NOT MATCH " + '='*60 + print n + print "ACTUAL XML OUTPUT " + '='*60 + print xml_out + test.fail_test() + +test.pass_test() diff --git a/test/same-name.py b/test/same-name.py index 99a0ea5..8f71ac7 100644 --- a/test/same-name.py +++ b/test/same-name.py @@ -41,6 +41,8 @@ env.Program(source = ['foo.c', 'bu/bu.c']) """) test.write('foo.c', r""" +#include +#include #include int main(int argc, char *argv[]) @@ -57,6 +59,7 @@ void bu(void); """) test.write(['bu', 'bu.c'], r""" +#include void bu(void) { diff --git a/test/scan-once.py b/test/scan-once.py deleted file mode 100644 index 044e260..0000000 --- a/test/scan-once.py +++ /dev/null @@ -1,497 +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. -# - -""" -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__" - -import os.path -import sys - -import TestCmd -import TestSCons - -test = TestSCons.TestSCons() - -test.subdir('simple', - 'SLF', - ['SLF', 'reftree'], ['SLF', 'reftree', 'include'], - ['SLF', 'src'], ['SLF', '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 -### don't seem to work well! ARRGH!!!! -### - -experimenttop = r"%s" - -import os -import os.path -import string -import Mylib - -BStaticLibMerge = Builder(generator = Mylib.Gen_StaticLibMerge) -builders = Environment().Dictionary('BUILDERS') -builders["StaticLibMerge"] = BStaticLibMerge - -env = Environment(BUILDERS = builders) -e = env.Dictionary() # Slightly easier to type - -global_env = env -e["GlobalEnv"] = global_env - -e["REF_INCLUDE"] = os.path.join(experimenttop, "reftree", "include") -e["REF_LIB"] = os.path.join(experimenttop, "reftree", "lib") -e["EXPORT_INCLUDE"] = os.path.join(experimenttop, "export", "include") -e["EXPORT_LIB"] = os.path.join(experimenttop, "export", "lib") -e["INSTALL_BIN"] = os.path.join(experimenttop, "install", "bin") - -build_dir = os.path.join(experimenttop, "tmp-bld-dir") -src_dir = os.path.join(experimenttop, "src") - -env.Append(CPPPATH = [e["EXPORT_INCLUDE"]]) -env.Append(CPPPATH = [e["REF_INCLUDE"]]) -Mylib.AddLibDirs(env, "/via/Mylib.AddLibPath") -env.Append(LIBPATH = [e["EXPORT_LIB"]]) -env.Append(LIBPATH = [e["REF_LIB"]]) - -Mylib.Subdirs(env, "src") -""" % test.workpath('SLF')) - -test.write(['SLF', 'Mylib.py'], """\ -import os -import string -import re - -def Subdirs(env, dirlist): - for file in _subconf_list(dirlist): - env.SConscript(file, "env") - -def _subconf_list(dirlist): - return map(lambda x: os.path.join(x, "SConscript"), string.split(dirlist)) - -def StaticLibMergeMembers(local_env, libname, hackpath, files): - for file in string.split(files): - # QQQ Fix limits in grok'ed regexp - tmp = re.sub(".c$", ".o", file) - objname = re.sub(".cpp", ".o", tmp) - local_env.Object(target = objname, source = file) - e = 'local_env["GlobalEnv"].Append(%s = ["%s"])' % (libname, os.path.join(hackpath, objname)) - exec(e) - -def CreateMergedStaticLibrary(env, libname): - objpaths = env["GlobalEnv"][libname] - libname = "lib%s.a" % (libname) - env.StaticLibMerge(target = libname, source = objpaths) - -# I put the main body of the generator code here to avoid -# namespace problems -def Gen_StaticLibMerge(source, target, env, for_signature): - target_string = "" - for t in target: - target_string = str(t) - subdir = os.path.dirname(target_string) - srclist = [] - for src in source: - srclist.append(src) - return [["ar", "cq"] + target + srclist, ["ranlib"] + target] - -def StaticLibrary(env, target, source): - env.StaticLibrary(target, string.split(source)) - -def SharedLibrary(env, target, source): - env.SharedLibrary(target, string.split(source)) - -def ExportHeader(env, headers): - env.Install(dir = env["EXPORT_INCLUDE"], source = string.split(headers)) - -def ExportLib(env, libs): - env.Install(dir = env["EXPORT_LIB"], source = string.split(libs)) - -def InstallBin(env, bins): - env.Install(dir = env["INSTALL_BIN"], source = string.split(bins)) - -def Program(env, target, source): - env.Program(target, string.split(source)) - -def AddCFlags(env, str): - env.Append(CPPFLAGS = " " + str) - -# QQQ Synonym needed? -#def AddCFLAGS(env, str): -# AddCFlags(env, str) - -def AddIncludeDirs(env, str): - env.Append(CPPPATH = string.split(str)) - -def AddLibs(env, str): - env.Append(LIBS = string.split(str)) - -def AddLibDirs(env, str): - env.Append(LIBPATH = string.split(str)) - -""") - -test.write(['SLF', 'reftree', 'include', 'lib_a.h'], """\ -char *a_letter(void); -""") - -test.write(['SLF', 'reftree', 'include', 'lib_b.h'], """\ -char *b_letter(void); -""") - -test.write(['SLF', 'reftree', 'include', 'lib_ja.h'], """\ -char *j_letter_a(void); -""") - -test.write(['SLF', 'reftree', 'include', 'lib_jb.h.intentionally-moved'], """\ -char *j_letter_b(void); -""") - -test.write(['SLF', 'src', 'SConscript'], """\ -# --- Begin SConscript boilerplate --- -import Mylib -Import("env") - -#env = env.Copy() # Yes, clobber intentionally -#Make environment changes, such as: Mylib.AddCFlags(env, "-g -D_TEST") -#Mylib.Subdirs(env, "lib_a lib_b lib_mergej prog_x") -Mylib.Subdirs(env, "lib_geng") - -env = env.Copy() # Yes, clobber intentionally -# --- End SConscript boilerplate --- - -""") - -test.write(['SLF', 'src', 'lib_geng', 'SConscript'], """\ -# --- Begin SConscript boilerplate --- -import string -import sys -import Mylib -Import("env") - -#env = env.Copy() # Yes, clobber intentionally -#Make environment changes, such as: Mylib.AddCFlags(env, "-g -D_TEST") -#Mylib.Subdirs(env, "foo_dir") - -env = env.Copy() # Yes, clobber intentionally -# --- End SConscript boilerplate --- - -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. -import os -recurse_env = env.Copy() -recurse_env["ENV"] = os.environ - -# Icky code to set up process environment for "make" -# I really ought to drop this into Mylib.... - -fromdict = env.Dictionary() -todict = env["ENV"] -import SCons.Util -import re -for k in fromdict.keys(): - if k != "ENV" and k != "SCANNERS" and k != "CFLAGS" and k != "CXXFLAGS" \ - and not SCons.Util.is_Dict(fromdict[k]): - # The next line can fail on some systems because it would try to - # do env.subst on: - # $RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} ... - # When $TARGET is None, so $TARGET.attributes would throw an - # exception. - f = fromdict[k] - if SCons.Util.is_String(f) and \ - string.find(f, "TARGET") == -1 and \ - string.find(f, "SOURCE") == -1: - todict[k] = env.subst(f) -todict["CFLAGS"] = fromdict["CPPFLAGS"] + " " + \ - string.join(map(lambda x: "-I" + x, env["CPPPATH"])) + " " + \ - string.join(map(lambda x: "-L" + x, env["LIBPATH"])) -todict["CXXFLAGS"] = todict["CFLAGS"] - -generated_hdrs = "libg_gx.h libg_gy.h libg_gz.h" -static_hdrs = "libg_w.h" -#exported_hdrs = generated_hdrs + " " + static_hdrs -exported_hdrs = static_hdrs -lib_name = "g" -lib_fullname = env.subst("${LIBPREFIX}g${LIBSUFFIX}") -lib_srcs = string.split("libg_1.c libg_2.c libg_3.c") -import re -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 -# recursive invocation of SCons (!). -#cmd_both = "cd %s ; make generated ; make" % Dir(".") -#cmd_generated = "cd %s ; sh MAKE-HEADER.sh" % Dir(".") -#cmd_justlib = "cd %s ; make" % Dir(".") - -_ws = re.compile('\s') - -def escape(s): - if _ws.search(s): - s = '"' + s + '"' - return s - -cmd_generated = "%s $SOURCE" % (escape(sys.executable),) -cmd_justlib = "%s %s -C ${SOURCES[0].dir}" % ((sys.executable), - escape(sys.argv[0])) - -##### Deps appear correct ... but wacky scanning? -# Why? -# -# SCons bug?? - -env.Command(string.split(generated_hdrs), - ["MAKE-HEADER.py"], - cmd_generated) -recurse_env.Command([lib_fullname] + lib_objs, - lib_srcs + string.split(generated_hdrs + " " + static_hdrs), - cmd_justlib) -""") - -test.write(['SLF', 'src', 'lib_geng', 'MAKE-HEADER.py'], """\ -#!/usr/bin/env python - -import os -import os.path -import sys - -# chdir to the directory in which this script lives -os.chdir(os.path.split(sys.argv[0])[0]) - -for h in ['libg_gx.h', 'libg_gy.h', 'libg_gz.h']: - open(h, 'w').write('') -""") - -test.write(['SLF', 'src', 'lib_geng', 'SConstruct'], """\ -import os - -Scanned = {} - -def write_out(file, dict): - keys = dict.keys() - keys.sort() - f = open(file, 'wb') - for k in keys: - file = os.path.split(k)[1] - f.write(file + ": " + str(dict[k]) + "\\n") - f.close() - -orig_function = CScan.scan - -def MyCScan(node, paths, orig_function=orig_function): - deps = orig_function(node, paths) - - global Scanned - n = str(node) - try: - Scanned[n] = Scanned[n] + 1 - except KeyError: - Scanned[n] = 1 - write_out(r'%s', Scanned) - - return deps - -CScan.scan = MyCScan - -env = Environment(CPPPATH = ".") -l = env.StaticLibrary("g", Split("libg_1.c libg_2.c libg_3.c")) -Default(l) -""" % test.workpath('MyCScan.out')) - -# These were the original shell script and Makefile from SLF's original -# 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'], """\ -##!/bin/sh -# -#exec touch $* -#""") -# -#test.write(['SLF', 'src', 'lib_geng', 'Makefile'], """\ -#all: libg.a -# -#GEN_HDRS = libg_gx.h libg_gy.h libg_gz.h -#STATIC_HDRS = libg_w.h -# -#$(GEN_HDRS): generated -# -#generated: MAKE-HEADER.sh -# sh ./MAKE-HEADER.sh $(GEN_HDRS) -# -#libg.a: libg_1.o libg_2.o libg_3.o -# ar r libg.a libg_1.o libg_2.o libg_3.o -# -#libg_1.c: $(STATIC_HDRS) $(GEN_HDRS) -#libg_2.c: $(STATIC_HDRS) $(GEN_HDRS) -#libg_3.c: $(STATIC_HDRS) $(GEN_HDRS) -# -#clean: -# -rm -f $(GEN_HDRS) -# -rm -f libg.a *.o core core.* -#""") - -test.write(['SLF', 'src', 'lib_geng', 'libg_w.h'], """\ -""") - -test.write(['SLF', 'src', 'lib_geng', 'libg_1.c'], """\ -#include -#include - -int g_1() -{ - return 1; -} -""") - -test.write(['SLF', 'src', 'lib_geng', 'libg_2.c'], """\ -#include -#include -#include -#include - -int g_2() -{ - return 2; -} -""") - -test.write(['SLF', 'src', 'lib_geng', 'libg_3.c'], """\ -#include -#include - -int g_3() -{ - return 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, - match=TestSCons.match_re_dotall) - -# XXX Note that the generated .h files still get scanned twice, -# once before they're generated and once after. That's the -# next thing to fix here. - -test.must_match("MyCScan.out", """\ -libg_1.c: 1 -libg_2.c: 1 -libg_3.c: 1 -libg_gx.h: 1 -libg_gy.h: 1 -libg_gz.h: 1 -libg_w.h: 1 -""") - -test.pass_test() diff --git a/test/sconsign/script.py b/test/sconsign/script.py index 9e0caa5..d94a956 100644 --- a/test/sconsign/script.py +++ b/test/sconsign/script.py @@ -91,6 +91,8 @@ env2.Program('sub2/hello.c') """) test.write(['work1', 'sub1', 'hello.c'], r"""\ +#include +#include int main(int argc, char *argv[]) { @@ -101,6 +103,8 @@ main(int argc, char *argv[]) """) test.write(['work1', 'sub2', 'hello.c'], r"""\ +#include +#include #include #include int @@ -283,6 +287,8 @@ env2.Program('sub2/hello.c') """) test.write(['work2', 'sub1', 'hello.c'], r"""\ +#include +#include int main(int argc, char *argv[]) { @@ -293,6 +299,8 @@ main(int argc, char *argv[]) """) test.write(['work2', 'sub2', 'hello.c'], r"""\ +#include +#include #include #include int diff --git a/test/signature-order.py b/test/signature-order.py index 8fb15bf..6ec839d 100644 --- a/test/signature-order.py +++ b/test/signature-order.py @@ -65,6 +65,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['work1', 'foo.c'], r""" +#include +#include #include #include int @@ -98,6 +100,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['work2', 'foo.c'], r""" +#include +#include #include "aaa.h" #include "bbb.h" int diff --git a/test/silent-command.py b/test/silent-command.py index a5da7a8..91880bd 100644 --- a/test/silent-command.py +++ b/test/silent-command.py @@ -36,7 +36,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,13 +52,13 @@ fp.close() test.write('SConstruct', """\ env = Environment() -env.Command('f1.out', 'f1.in', "%(python)s build.py $TARGET $SOURCE") -env.Command('f2.out', 'f2.in', "@%(python)s build.py $TARGET $SOURCE") -env.Command('f3.out', 'f3.in', "@ %(python)s build.py $TARGET $SOURCE") -env.Command('f4.out', 'f4.in', "@-%(python)s build.py $TARGET $SOURCE") -env.Command('f5.out', 'f5.in', "@- %(python)s build.py $TARGET $SOURCE") -env.Command('f6.out', 'f6.in', "-@%(python)s build.py $TARGET $SOURCE") -env.Command('f7.out', 'f7.in', "-@ %(python)s build.py $TARGET $SOURCE") +env.Command('f1.out', 'f1.in', '%(_python_)s build.py $TARGET $SOURCE') +env.Command('f2.out', 'f2.in', '@%(_python_)s build.py $TARGET $SOURCE') +env.Command('f3.out', 'f3.in', '@ %(_python_)s build.py $TARGET $SOURCE') +env.Command('f4.out', 'f4.in', '@-%(_python_)s build.py $TARGET $SOURCE') +env.Command('f5.out', 'f5.in', '@- %(_python_)s build.py $TARGET $SOURCE') +env.Command('f6.out', 'f6.in', '-@%(_python_)s build.py $TARGET $SOURCE') +env.Command('f7.out', 'f7.in', '-@ %(_python_)s build.py $TARGET $SOURCE') """ % locals()) test.write('f1.in', "f1.in\n") @@ -70,7 +70,7 @@ test.write('f6.in', "f6.in\n") test.write('f7.in', "f7.in\n") expect = test.wrap_stdout("""\ -%(python)s build.py f1.out f1.in +%(_python_)s build.py f1.out f1.in """ % locals()) test.run(arguments = '.', stdout = expect) diff --git a/test/special-filenames.py b/test/special-filenames.py index 98096b7..11930e5 100644 --- a/test/special-filenames.py +++ b/test/special-filenames.py @@ -30,6 +30,8 @@ import sys import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() attempt_file_names = [ @@ -68,11 +70,13 @@ for fn in attempt_file_names: def buildFileStr(fn): return "env.Build(source=r\"\"\"%s.in\"\"\", target=r\"\"\"%s.out\"\"\")" % ( fn, fn ) +xxx = string.join(map(buildFileStr, file_names), '\n') + test.write("SConstruct", """ -env=Environment(BUILDERS = {'Build' : Builder(action = '%s cat.py $TARGET $SOURCE')}) +env=Environment(BUILDERS = {'Build' : Builder(action = '%(_python_)s cat.py $TARGET $SOURCE')}) -%s -""" % (TestSCons.python, string.join(map(buildFileStr, file_names), '\n'))) +%(xxx)s +""" % locals()) test.run(arguments='.') diff --git a/test/srcchange.py b/test/srcchange.py index ef92aea..ac549f6 100644 --- a/test/srcchange.py +++ b/test/srcchange.py @@ -33,6 +33,8 @@ import os.path import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.write('getrevision', """ @@ -59,16 +61,18 @@ SubRevision = Action(subrevision) env=Environment() content_env=env.Copy() content_env.TargetSignatures('content') -content_env.Command('revision.in', [], '%(python)s getrevision > $TARGET') +content_env.Command('revision.in', [], '%(_python_)s getrevision > $TARGET') content_env.AlwaysBuild('revision.in') env.Precious('main.c') env.Command('main.c', 'revision.in', SubRevision) exe = env.Program('main.c') env.Default(exe) -""" % {'python':TestSCons.python}) +""" % locals()) test.write('main.c', """\ #include +#include +#include int main(int argc, char *argv[]) { @@ -82,8 +86,8 @@ test.write('revnum.in', '3.2\n') prog = 'main' + TestSCons._exe light_build=test.wrap_stdout("""\ -%(python)s getrevision > revision.in -""" % {'python':TestSCons.python}) +%(_python_)s getrevision > revision.in +""" % locals()) test.run(arguments='.') test.must_exist(prog) diff --git a/test/strfunction.py b/test/strfunction.py index a0b2344..62240ee 100644 --- a/test/strfunction.py +++ b/test/strfunction.py @@ -30,7 +30,7 @@ Test how using strfunction() to report different types of import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,12 +53,12 @@ def func(target, source, env): func1action = Action(func, strfunction) func2action = Action(func, strfunction=strfunction) -cmd = r"%(python)s cat.py $SOURCE $TARGET" +cmd = r'%(_python_)s cat.py $SOURCE $TARGET' cmd1action = Action(cmd, strfunction) cmd2action = Action(cmd, strfunction=strfunction) -list = [ r"%(python)s cat.py $SOURCE .temp", - r"%(python)s cat.py .temp $TARGET" ] +list = [ r'%(_python_)s cat.py $SOURCE .temp', + r'%(_python_)s cat.py .temp $TARGET' ] listaction = Action(list, strfunction=strfunction) lazy = '$LAZY' @@ -94,7 +94,7 @@ env = Environment(BUILDERS = { 'Dict' : Builder(action=dict), }, - LAZY = r"%(python)s cat.py $SOURCE $TARGET") + LAZY = r'%(_python_)s cat.py $SOURCE $TARGET') env.Cmd('cmd.out', 'cmd.in') env.Cmd1Str('cmd1str.out', 'cmdstr.in') @@ -139,27 +139,27 @@ test.write('dict7.list', "dict7.list\n") test.write('dict8.liststr', "dict8.liststr\n") expect = test.wrap_stdout("""\ -%(python)s cat.py cmd.in cmd.out +%(_python_)s cat.py cmd.in cmd.out Building cmd1str.out from cmdstr.in Building cmd2str.out from cmdstr.in -%(python)s cat.py dict1.cmd dict1.out +%(_python_)s cat.py dict1.cmd dict1.out Building dict2.out from dict2.cmdstr func(["dict3.out"], ["dict3.func"]) Building dict4.out from dict4.funcstr -%(python)s cat.py dict5.lazy dict5.out +%(_python_)s cat.py dict5.lazy dict5.out Building dict6.out from dict6.lazystr -%(python)s cat.py dict7.list .temp -%(python)s cat.py .temp dict7.out +%(_python_)s cat.py dict7.list .temp +%(_python_)s cat.py .temp dict7.out Building dict8.out from dict8.liststr Building dict8.out from dict8.liststr func(["func.out"], ["func.in"]) Building func1str.out from funcstr.in Building func2str.out from funcstr.in -%(python)s cat.py lazy.in lazy.out +%(_python_)s cat.py lazy.in lazy.out Building lazy1str.out from lazystr.in Building lazy2str.out from lazystr.in -%(python)s cat.py list.in .temp -%(python)s cat.py .temp list.out +%(_python_)s cat.py list.in .temp +%(_python_)s cat.py .temp list.out Building liststr.out from liststr.in Building liststr.out from liststr.in target.out diff --git a/test/subclassing.py b/test/subclassing.py index a040dd4..18be1bc 100644 --- a/test/subclassing.py +++ b/test/subclassing.py @@ -49,6 +49,8 @@ env.Program('hello', 'hello.c') """) test.write('hello.c', """\ +#include +#include int main(int argc, char *argv[]) { printf("hello.c\\n"); diff --git a/test/subdir.py b/test/subdir.py index 03cbed3..991eb23 100644 --- a/test/subdir.py +++ b/test/subdir.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,13 +42,13 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = "%s build.py $TARGETS $SOURCES") +B = Builder(action = '%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'subdir/f1.out', source = 'subdir/f1.in') env.B(target = 'subdir/f2.out', source = 'subdir/f2.in') env.B(target = 'subdir/f3.out', source = 'subdir/f3.in') env.B(target = 'subdir/f4.out', source = 'subdir/f4.in') -""" % python) +""" % locals()) test.write(['subdir', 'f1.in'], "f1.in\n") test.write(['subdir', 'f2.in'], "f2.in\n") diff --git a/test/subdivide.py b/test/subdivide.py index 18219bf..a816957 100644 --- a/test/subdivide.py +++ b/test/subdivide.py @@ -63,6 +63,8 @@ env.Default(p) """ % TestSCons._obj) test.write('foo.c', """\ +#include +#include void foo(void) { printf("foo.c\\n"); @@ -70,6 +72,8 @@ foo(void) { """) test.write(['src', 'main.c'], """\ +#include +#include 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 +#include void bar(void) { printf("bar.c\\n"); diff --git a/test/symlink.py b/test/symlink.py deleted file mode 100644 index ef7a55c..0000000 --- a/test/symlink.py +++ /dev/null @@ -1,72 +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 how we handle symlinks in end-cases. -""" - -import os -import string - -import TestSCons - -test = TestSCons.TestSCons() - -if not hasattr(os, 'symlink'): - print "No os.symlink() method, no symlinks to test." - test.no_result(1) - -foo_obj = 'foo' + TestSCons._obj - -test.write('SConstruct', """ -Program('foo.c') -""") - -test.write('foo.c', """\ -#include "foo.h" -""") - -test.symlink('nonexistent', 'foo.h') - -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.pass_test() diff --git a/test/symlink/BuildDir.py b/test/symlink/BuildDir.py new file mode 100644 index 0000000..eee0e4d --- /dev/null +++ b/test/symlink/BuildDir.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +XXX Put a description of the test here. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +if not hasattr(os, 'symlink'): + print "No os.symlink() method, no symlinks to test." + test.no_result(1) + +test.subdir('obj', + ['obj', 'subdir'], + 'src', + 'srcdir') + +test.write('SConstruct', """ +env = Environment() +BuildDir('obj/subdir', 'src') +Program('hello', ['obj/subdir/main.c']) +""") + +test.write(['srcdir', 'main.c'], r""" +int +main(int ac, char *argv[]) +{ + printf("srcdir/main.c\n"); +} +""") + +os.symlink('../srcdir/main.c', 'src/main.c') + +test.run(arguments = '.') + +test.pass_test() diff --git a/test/symlink/dangling-include.py b/test/symlink/dangling-include.py new file mode 100644 index 0000000..b5ea1e0 --- /dev/null +++ b/test/symlink/dangling-include.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test how we handle #includes of dangling symlinks. +""" + +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) + +foo_obj = 'foo' + TestSCons._obj + +test.write('SConstruct', """ +Program('foo.c') +""") + +test.write('foo.c', """\ +#include "foo.h" +""") + +test.symlink('nonexistent', 'foo.h') + +expect = """\ +scons: *** Source `foo.h' not found, needed by target `%s'. Stop. +"""% foo_obj + +test.run(arguments = '.', status = 2, stderr = expect) + +test.pass_test() diff --git a/test/symlink/dangling-source.py b/test/symlink/dangling-source.py new file mode 100644 index 0000000..e242e61 --- /dev/null +++ b/test/symlink/dangling-source.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test how we handle dangling symlinks as source files. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +if not hasattr(os, 'symlink'): + print "No os.symlink() method, no symlinks to test." + test.no_result(1) + +test.write('SConstruct', """ +Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) +""") + +test.symlink('nonexistent', 'file.in') + +expect = """\ +scons: *** Source `file.in' not found, needed by target `file.out'. Stop. +""" + +test.run(arguments = '.', status = 2, stderr = expect) + +test.pass_test() diff --git a/test/up-to-date.py b/test/up-to-date.py index 460401a..cec5952 100644 --- a/test/up-to-date.py +++ b/test/up-to-date.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,13 +42,13 @@ file.close() """) test.write('SConstruct', """ -B = Builder(action = r'%s build.py $TARGETS $SOURCES') +B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES') env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') env.B(target = 'f4.out', source = 'f4.in') -""" % python) +""" % locals()) test.write('f1.in', "f1.in\n") test.write('f2.in', "f2.in\n") @@ -57,13 +57,14 @@ test.write('f4.in', "f4.in\n") test.run(arguments = 'f1.out f3.out') -test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout = -test.wrap_stdout("""\ +expect = test.wrap_stdout("""\ scons: `f1.out' is up to date. -%s build.py f2.out f2.in +%(_python_)s build.py f2.out f2.in scons: `f3.out' is up to date. -%s build.py f4.out f4.in -""" % (python, python))) +%(_python_)s build.py f4.out f4.in +""" % locals()) + +test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout = expect) test.pass_test() -- cgit v0.12