From 48f19e9e5ecc069f379ad433fdaf280ac9b54e16 Mon Sep 17 00:00:00 2001 From: Luca Falavigna Date: Sat, 23 Jan 2010 15:22:02 +0100 Subject: Imported Upstream version 1.2.0.d20100117 --- LICENSE | 2 +- SConstruct | 11 +- bin/docdiff | 4 +- bin/docrun | 4 +- bin/docupdate | 4 +- bin/import-test.py | 4 +- bin/linecount.py | 4 +- bin/restore.sh | 26 +- bin/scons-doc.py | 868 +++++++++++++++++++++ bin/scons_dev_master.py | 1 + bin/sconsoutput.py | 827 -------------------- doc/SConscript | 12 +- doc/design/scons.mod | 2 +- doc/developer/architecture.xml | 2 +- doc/developer/branches.xml | 2 +- doc/developer/copyright.xml | 2 +- doc/developer/cycle.xml | 2 +- doc/developer/main.xml | 2 +- doc/developer/packaging.xml | 2 +- doc/developer/preface.xml | 2 +- doc/developer/sourcetree.xml | 2 +- doc/developer/testing.xml | 2 +- doc/man/scons-time.1 | 6 +- doc/man/scons.1 | 27 +- doc/man/sconsign.1 | 6 +- doc/python10/scons.mod | 2 +- doc/scons.mod | 3 +- doc/user/README | 2 +- doc/user/actions.in | 2 +- doc/user/actions.xml | 2 +- doc/user/add-method.in | 2 +- doc/user/add-method.xml | 14 +- doc/user/alias.in | 2 +- doc/user/alias.xml | 2 +- doc/user/ant.in | 2 +- doc/user/ant.xml | 2 +- doc/user/build-install.in | 24 +- doc/user/build-install.xml | 24 +- doc/user/builders-built-in.in | 2 +- doc/user/builders-built-in.xml | 14 +- doc/user/builders-commands.in | 2 +- doc/user/builders-commands.xml | 2 +- doc/user/builders-writing.in | 22 +- doc/user/builders-writing.xml | 22 +- doc/user/builders.in | 2 +- doc/user/builders.xml | 2 +- doc/user/caching.in | 2 +- doc/user/caching.xml | 2 +- doc/user/command-line.in | 2 +- doc/user/command-line.xml | 45 +- doc/user/copyright.in | 2 +- doc/user/copyright.xml | 2 +- doc/user/depends.in | 74 +- doc/user/depends.xml | 99 +-- doc/user/environments.in | 2 +- doc/user/environments.xml | 25 +- doc/user/errors.in | 2 +- doc/user/errors.xml | 2 +- doc/user/example.in | 2 +- doc/user/example.xml | 2 +- doc/user/factories.in | 2 +- doc/user/factories.xml | 2 +- doc/user/file-removal.in | 2 +- doc/user/file-removal.xml | 2 +- doc/user/hierarchy.in | 2 +- doc/user/hierarchy.xml | 2 +- doc/user/install.in | 2 +- doc/user/install.xml | 2 +- doc/user/java.in | 2 +- doc/user/java.xml | 2 +- doc/user/less-simple.in | 2 +- doc/user/less-simple.xml | 14 +- doc/user/libraries.in | 2 +- doc/user/libraries.xml | 26 +- doc/user/main.in | 2 +- doc/user/main.xml | 2 +- doc/user/make.in | 2 +- doc/user/make.xml | 2 +- doc/user/mergeflags.in | 2 +- doc/user/mergeflags.xml | 2 +- doc/user/misc.in | 2 +- doc/user/misc.xml | 4 +- doc/user/nodes.in | 2 +- doc/user/nodes.xml | 14 +- doc/user/output.in | 2 +- doc/user/output.xml | 14 +- doc/user/parseconfig.in | 28 +- doc/user/parseconfig.xml | 50 +- doc/user/parseflags.in | 2 +- doc/user/parseflags.xml | 14 +- doc/user/preface.in | 2 +- doc/user/preface.xml | 2 +- doc/user/python.in | 2 +- doc/user/python.xml | 2 +- doc/user/repositories.in | 2 +- doc/user/repositories.xml | 2 +- doc/user/run.in | 2 +- doc/user/run.xml | 2 +- doc/user/scanners.in | 2 +- doc/user/scanners.xml | 2 +- doc/user/sconf.in | 2 +- doc/user/sconf.xml | 2 +- doc/user/separate.in | 2 +- doc/user/separate.xml | 2 +- doc/user/sideeffect.in | 2 +- doc/user/sideeffect.xml | 2 +- doc/user/simple.in | 2 +- doc/user/simple.xml | 38 +- doc/user/sourcecode.in | 2 +- doc/user/sourcecode.xml | 2 +- doc/user/tasks.in | 2 +- doc/user/tasks.xml | 2 +- doc/user/tools.in | 2 +- doc/user/tools.xml | 2 +- doc/user/troubleshoot.in | 2 +- doc/user/troubleshoot.xml | 38 +- doc/user/variables.in | 2 +- doc/user/variables.xml | 2 +- doc/user/variants.in | 2 +- doc/user/variants.xml | 14 +- src/CHANGES.txt | 13 +- src/LICENSE.txt | 2 +- src/README.txt | 24 +- src/RELEASE.txt | 36 +- src/engine/README.txt | 6 +- src/engine/SCons/Action.py | 22 +- src/engine/SCons/Action.xml | 2 +- src/engine/SCons/ActionTests.py | 98 ++- src/engine/SCons/Builder.py | 4 +- src/engine/SCons/BuilderTests.py | 17 +- src/engine/SCons/CacheDir.py | 4 +- src/engine/SCons/CacheDirTests.py | 4 +- src/engine/SCons/Debug.py | 6 +- src/engine/SCons/Defaults.py | 4 +- src/engine/SCons/Defaults.xml | 2 +- src/engine/SCons/DefaultsTests.py | 4 +- src/engine/SCons/Environment.py | 4 +- src/engine/SCons/Environment.xml | 2 +- src/engine/SCons/EnvironmentTests.py | 4 +- src/engine/SCons/Errors.py | 4 +- src/engine/SCons/ErrorsTests.py | 4 +- src/engine/SCons/Executor.py | 4 +- src/engine/SCons/ExecutorTests.py | 4 +- src/engine/SCons/Job.py | 4 +- src/engine/SCons/JobTests.py | 4 +- src/engine/SCons/Memoize.py | 4 +- src/engine/SCons/MemoizeTests.py | 4 +- src/engine/SCons/Node/Alias.py | 4 +- src/engine/SCons/Node/AliasTests.py | 4 +- src/engine/SCons/Node/FS.py | 4 +- src/engine/SCons/Node/FSTests.py | 4 +- src/engine/SCons/Node/NodeTests.py | 4 +- src/engine/SCons/Node/Python.py | 4 +- src/engine/SCons/Node/PythonTests.py | 4 +- src/engine/SCons/Node/__init__.py | 4 +- src/engine/SCons/Options/BoolOption.py | 4 +- src/engine/SCons/Options/EnumOption.py | 4 +- src/engine/SCons/Options/ListOption.py | 4 +- src/engine/SCons/Options/PackageOption.py | 4 +- src/engine/SCons/Options/PathOption.py | 4 +- src/engine/SCons/Options/__init__.py | 4 +- src/engine/SCons/PathList.py | 4 +- src/engine/SCons/PathListTests.py | 4 +- src/engine/SCons/Platform/PlatformTests.py | 4 +- src/engine/SCons/Platform/__init__.py | 4 +- src/engine/SCons/Platform/__init__.xml | 2 +- src/engine/SCons/Platform/aix.py | 4 +- src/engine/SCons/Platform/cygwin.py | 4 +- src/engine/SCons/Platform/darwin.py | 4 +- src/engine/SCons/Platform/hpux.py | 4 +- src/engine/SCons/Platform/irix.py | 4 +- src/engine/SCons/Platform/os2.py | 4 +- src/engine/SCons/Platform/posix.py | 4 +- src/engine/SCons/Platform/posix.xml | 2 +- src/engine/SCons/Platform/sunos.py | 4 +- src/engine/SCons/Platform/sunos.xml | 2 +- src/engine/SCons/Platform/win32.py | 6 +- src/engine/SCons/Platform/win32.xml | 2 +- src/engine/SCons/SConf.py | 4 +- src/engine/SCons/SConfTests.py | 4 +- src/engine/SCons/SConsign.py | 4 +- src/engine/SCons/SConsignTests.py | 4 +- src/engine/SCons/Scanner/C.py | 4 +- src/engine/SCons/Scanner/CTests.py | 4 +- src/engine/SCons/Scanner/D.py | 4 +- src/engine/SCons/Scanner/Dir.py | 4 +- src/engine/SCons/Scanner/DirTests.py | 4 +- src/engine/SCons/Scanner/Fortran.py | 4 +- src/engine/SCons/Scanner/FortranTests.py | 4 +- src/engine/SCons/Scanner/IDL.py | 4 +- src/engine/SCons/Scanner/IDLTests.py | 4 +- src/engine/SCons/Scanner/LaTeX.py | 47 +- src/engine/SCons/Scanner/LaTeXTests.py | 4 +- src/engine/SCons/Scanner/Prog.py | 4 +- src/engine/SCons/Scanner/ProgTests.py | 4 +- src/engine/SCons/Scanner/RC.py | 4 +- src/engine/SCons/Scanner/RCTests.py | 4 +- src/engine/SCons/Scanner/ScannerTests.py | 4 +- src/engine/SCons/Scanner/__init__.py | 4 +- src/engine/SCons/Script/Interactive.py | 4 +- src/engine/SCons/Script/Main.py | 6 +- src/engine/SCons/Script/MainTests.py | 4 +- src/engine/SCons/Script/SConsOptions.py | 4 +- src/engine/SCons/Script/SConscript.py | 4 +- src/engine/SCons/Script/SConscriptTests.py | 4 +- src/engine/SCons/Script/__init__.py | 4 +- src/engine/SCons/Sig.py | 4 +- src/engine/SCons/Subst.py | 4 +- src/engine/SCons/SubstTests.py | 4 +- src/engine/SCons/Taskmaster.py | 4 +- src/engine/SCons/TaskmasterTests.py | 4 +- src/engine/SCons/Tool/386asm.py | 4 +- src/engine/SCons/Tool/386asm.xml | 2 +- src/engine/SCons/Tool/BitKeeper.py | 4 +- src/engine/SCons/Tool/BitKeeper.xml | 2 +- src/engine/SCons/Tool/CVS.py | 4 +- src/engine/SCons/Tool/CVS.xml | 2 +- src/engine/SCons/Tool/FortranCommon.py | 4 +- src/engine/SCons/Tool/JavaCommon.py | 4 +- src/engine/SCons/Tool/JavaCommonTests.py | 4 +- src/engine/SCons/Tool/MSCommon/__init__.py | 4 +- src/engine/SCons/Tool/MSCommon/arch.py | 4 +- src/engine/SCons/Tool/MSCommon/common.py | 27 +- src/engine/SCons/Tool/MSCommon/netframework.py | 4 +- src/engine/SCons/Tool/MSCommon/sdk.py | 4 +- src/engine/SCons/Tool/MSCommon/vc.py | 4 +- src/engine/SCons/Tool/MSCommon/vc.py.bak | 4 +- src/engine/SCons/Tool/MSCommon/vs.py | 4 +- src/engine/SCons/Tool/Perforce.py | 4 +- src/engine/SCons/Tool/Perforce.xml | 2 +- src/engine/SCons/Tool/PharLapCommon.py | 4 +- src/engine/SCons/Tool/PharLapCommonTests.py | 4 +- src/engine/SCons/Tool/RCS.py | 4 +- src/engine/SCons/Tool/RCS.xml | 2 +- src/engine/SCons/Tool/SCCS.py | 4 +- src/engine/SCons/Tool/SCCS.xml | 2 +- src/engine/SCons/Tool/Subversion.py | 4 +- src/engine/SCons/Tool/Subversion.xml | 2 +- src/engine/SCons/Tool/ToolTests.py | 4 +- src/engine/SCons/Tool/__init__.py | 4 +- src/engine/SCons/Tool/__init__.xml | 2 +- src/engine/SCons/Tool/aixc++.py | 4 +- src/engine/SCons/Tool/aixc++.xml | 2 +- src/engine/SCons/Tool/aixcc.py | 4 +- src/engine/SCons/Tool/aixcc.xml | 2 +- src/engine/SCons/Tool/aixf77.py | 4 +- src/engine/SCons/Tool/aixf77.xml | 2 +- src/engine/SCons/Tool/aixlink.py | 4 +- src/engine/SCons/Tool/aixlink.xml | 2 +- src/engine/SCons/Tool/applelink.py | 4 +- src/engine/SCons/Tool/applelink.xml | 2 +- src/engine/SCons/Tool/ar.py | 4 +- src/engine/SCons/Tool/ar.xml | 2 +- src/engine/SCons/Tool/as.py | 4 +- src/engine/SCons/Tool/as.xml | 2 +- src/engine/SCons/Tool/bcc32.py | 4 +- src/engine/SCons/Tool/bcc32.xml | 2 +- src/engine/SCons/Tool/c++.py | 4 +- src/engine/SCons/Tool/c++.xml | 2 +- src/engine/SCons/Tool/cc.py | 4 +- src/engine/SCons/Tool/cc.xml | 2 +- src/engine/SCons/Tool/cvf.py | 4 +- src/engine/SCons/Tool/cvf.xml | 2 +- src/engine/SCons/Tool/default.py | 4 +- src/engine/SCons/Tool/default.xml | 2 +- src/engine/SCons/Tool/dmd.py | 4 +- src/engine/SCons/Tool/dmd.xml | 2 +- src/engine/SCons/Tool/dvi.py | 4 +- src/engine/SCons/Tool/dvi.xml | 2 +- src/engine/SCons/Tool/dvipdf.py | 4 +- src/engine/SCons/Tool/dvipdf.xml | 2 +- src/engine/SCons/Tool/dvips.py | 4 +- src/engine/SCons/Tool/dvips.xml | 2 +- src/engine/SCons/Tool/f77.py | 4 +- src/engine/SCons/Tool/f77.xml | 2 +- src/engine/SCons/Tool/f90.py | 4 +- src/engine/SCons/Tool/f90.xml | 2 +- src/engine/SCons/Tool/f95.py | 4 +- src/engine/SCons/Tool/f95.xml | 2 +- src/engine/SCons/Tool/filesystem.py | 4 +- src/engine/SCons/Tool/fortran.py | 4 +- src/engine/SCons/Tool/fortran.xml | 2 +- src/engine/SCons/Tool/g++.py | 4 +- src/engine/SCons/Tool/g++.xml | 2 +- src/engine/SCons/Tool/g77.py | 4 +- src/engine/SCons/Tool/g77.xml | 2 +- src/engine/SCons/Tool/gas.py | 4 +- src/engine/SCons/Tool/gas.xml | 2 +- src/engine/SCons/Tool/gcc.py | 4 +- src/engine/SCons/Tool/gcc.xml | 2 +- src/engine/SCons/Tool/gfortran.py | 4 +- src/engine/SCons/Tool/gfortran.xml | 2 +- src/engine/SCons/Tool/gnulink.py | 4 +- src/engine/SCons/Tool/gnulink.xml | 2 +- src/engine/SCons/Tool/gs.py | 4 +- src/engine/SCons/Tool/gs.xml | 2 +- src/engine/SCons/Tool/hpc++.py | 4 +- src/engine/SCons/Tool/hpc++.xml | 2 +- src/engine/SCons/Tool/hpcc.py | 4 +- src/engine/SCons/Tool/hpcc.xml | 2 +- src/engine/SCons/Tool/hplink.py | 4 +- src/engine/SCons/Tool/hplink.xml | 2 +- src/engine/SCons/Tool/icc.py | 4 +- src/engine/SCons/Tool/icc.xml | 2 +- src/engine/SCons/Tool/icl.py | 4 +- src/engine/SCons/Tool/icl.xml | 2 +- src/engine/SCons/Tool/ifl.py | 4 +- src/engine/SCons/Tool/ifl.xml | 2 +- src/engine/SCons/Tool/ifort.py | 4 +- src/engine/SCons/Tool/ifort.xml | 2 +- src/engine/SCons/Tool/ilink.py | 4 +- src/engine/SCons/Tool/ilink.xml | 2 +- src/engine/SCons/Tool/ilink32.py | 4 +- src/engine/SCons/Tool/ilink32.xml | 2 +- src/engine/SCons/Tool/install.py | 4 +- src/engine/SCons/Tool/install.xml | 2 +- src/engine/SCons/Tool/intelc.py | 4 +- src/engine/SCons/Tool/intelc.xml | 2 +- src/engine/SCons/Tool/ipkg.py | 4 +- src/engine/SCons/Tool/jar.py | 4 +- src/engine/SCons/Tool/jar.xml | 2 +- src/engine/SCons/Tool/javac.py | 4 +- src/engine/SCons/Tool/javac.xml | 2 +- src/engine/SCons/Tool/javah.py | 4 +- src/engine/SCons/Tool/javah.xml | 2 +- src/engine/SCons/Tool/latex.py | 4 +- src/engine/SCons/Tool/latex.xml | 2 +- src/engine/SCons/Tool/lex.py | 4 +- src/engine/SCons/Tool/lex.xml | 2 +- src/engine/SCons/Tool/link.py | 4 +- src/engine/SCons/Tool/link.xml | 2 +- src/engine/SCons/Tool/linkloc.py | 4 +- src/engine/SCons/Tool/linkloc.xml | 2 +- src/engine/SCons/Tool/m4.py | 4 +- src/engine/SCons/Tool/m4.xml | 2 +- src/engine/SCons/Tool/masm.py | 4 +- src/engine/SCons/Tool/masm.xml | 2 +- src/engine/SCons/Tool/midl.py | 4 +- src/engine/SCons/Tool/midl.xml | 2 +- src/engine/SCons/Tool/mingw.py | 4 +- src/engine/SCons/Tool/mingw.xml | 2 +- src/engine/SCons/Tool/mslib.py | 4 +- src/engine/SCons/Tool/mslib.xml | 2 +- src/engine/SCons/Tool/mslink.py | 4 +- src/engine/SCons/Tool/mslink.xml | 3 +- src/engine/SCons/Tool/mssdk.py | 4 +- src/engine/SCons/Tool/mssdk.xml | 2 +- src/engine/SCons/Tool/msvc.py | 20 +- src/engine/SCons/Tool/msvc.xml | 25 +- src/engine/SCons/Tool/msvs.py | 4 +- src/engine/SCons/Tool/msvs.xml | 111 +-- src/engine/SCons/Tool/msvsTests.py | 4 +- src/engine/SCons/Tool/mwcc.py | 4 +- src/engine/SCons/Tool/mwcc.xml | 2 +- src/engine/SCons/Tool/mwld.py | 4 +- src/engine/SCons/Tool/mwld.xml | 2 +- src/engine/SCons/Tool/nasm.py | 4 +- src/engine/SCons/Tool/nasm.xml | 2 +- src/engine/SCons/Tool/packaging.xml | 2 +- src/engine/SCons/Tool/packaging/__init__.py | 4 +- src/engine/SCons/Tool/packaging/__init__.xml | 2 +- src/engine/SCons/Tool/packaging/ipk.py | 4 +- src/engine/SCons/Tool/packaging/msi.py | 4 +- src/engine/SCons/Tool/packaging/rpm.py | 4 +- src/engine/SCons/Tool/packaging/src_tarbz2.py | 4 +- src/engine/SCons/Tool/packaging/src_targz.py | 4 +- src/engine/SCons/Tool/packaging/src_zip.py | 4 +- src/engine/SCons/Tool/packaging/tarbz2.py | 4 +- src/engine/SCons/Tool/packaging/targz.py | 4 +- src/engine/SCons/Tool/packaging/zip.py | 4 +- src/engine/SCons/Tool/pdf.py | 4 +- src/engine/SCons/Tool/pdf.xml | 2 +- src/engine/SCons/Tool/pdflatex.py | 4 +- src/engine/SCons/Tool/pdflatex.xml | 2 +- src/engine/SCons/Tool/pdftex.py | 4 +- src/engine/SCons/Tool/pdftex.xml | 2 +- src/engine/SCons/Tool/qt.py | 4 +- src/engine/SCons/Tool/qt.xml | 2 +- src/engine/SCons/Tool/rmic.py | 4 +- src/engine/SCons/Tool/rmic.xml | 2 +- src/engine/SCons/Tool/rpcgen.py | 4 +- src/engine/SCons/Tool/rpcgen.xml | 2 +- src/engine/SCons/Tool/rpm.py | 4 +- src/engine/SCons/Tool/sgiar.py | 4 +- src/engine/SCons/Tool/sgiar.xml | 2 +- src/engine/SCons/Tool/sgic++.py | 4 +- src/engine/SCons/Tool/sgic++.xml | 2 +- src/engine/SCons/Tool/sgicc.py | 4 +- src/engine/SCons/Tool/sgicc.xml | 2 +- src/engine/SCons/Tool/sgilink.py | 4 +- src/engine/SCons/Tool/sgilink.xml | 2 +- src/engine/SCons/Tool/sunar.py | 4 +- src/engine/SCons/Tool/sunar.xml | 2 +- src/engine/SCons/Tool/sunc++.py | 4 +- src/engine/SCons/Tool/sunc++.xml | 2 +- src/engine/SCons/Tool/suncc.py | 4 +- src/engine/SCons/Tool/suncc.xml | 2 +- src/engine/SCons/Tool/sunf77.py | 4 +- src/engine/SCons/Tool/sunf77.xml | 2 +- src/engine/SCons/Tool/sunf90.py | 4 +- src/engine/SCons/Tool/sunf90.xml | 2 +- src/engine/SCons/Tool/sunf95.py | 4 +- src/engine/SCons/Tool/sunf95.xml | 2 +- src/engine/SCons/Tool/sunlink.py | 4 +- src/engine/SCons/Tool/sunlink.xml | 2 +- src/engine/SCons/Tool/swig.py | 4 +- src/engine/SCons/Tool/swig.xml | 2 +- src/engine/SCons/Tool/tar.py | 4 +- src/engine/SCons/Tool/tar.xml | 2 +- src/engine/SCons/Tool/tex.py | 23 +- src/engine/SCons/Tool/tex.xml | 2 +- src/engine/SCons/Tool/textfile.py | 4 +- src/engine/SCons/Tool/textfile.xml | 2 +- src/engine/SCons/Tool/tlib.py | 4 +- src/engine/SCons/Tool/tlib.xml | 2 +- src/engine/SCons/Tool/wix.py | 4 +- src/engine/SCons/Tool/yacc.py | 4 +- src/engine/SCons/Tool/yacc.xml | 2 +- src/engine/SCons/Tool/zip.py | 4 +- src/engine/SCons/Tool/zip.xml | 2 +- src/engine/SCons/Util.py | 4 +- src/engine/SCons/UtilTests.py | 4 +- src/engine/SCons/Variables/BoolVariable.py | 4 +- src/engine/SCons/Variables/BoolVariableTests.py | 4 +- src/engine/SCons/Variables/EnumVariable.py | 4 +- src/engine/SCons/Variables/EnumVariableTests.py | 4 +- src/engine/SCons/Variables/ListVariable.py | 4 +- src/engine/SCons/Variables/ListVariableTests.py | 4 +- src/engine/SCons/Variables/PackageVariable.py | 4 +- src/engine/SCons/Variables/PackageVariableTests.py | 4 +- src/engine/SCons/Variables/PathVariable.py | 4 +- src/engine/SCons/Variables/PathVariableTests.py | 4 +- src/engine/SCons/Variables/VariablesTests.py | 4 +- src/engine/SCons/Variables/__init__.py | 4 +- src/engine/SCons/Warnings.py | 4 +- src/engine/SCons/WarningsTests.py | 4 +- src/engine/SCons/__init__.py | 10 +- src/engine/SCons/compat/__init__.py | 4 +- src/engine/SCons/compat/_scons_UserString.py | 4 +- src/engine/SCons/compat/_scons_hashlib.py | 4 +- src/engine/SCons/compat/_scons_itertools.py | 4 +- src/engine/SCons/compat/_scons_platform.py | 4 +- src/engine/SCons/compat/builtins.py | 4 +- src/engine/SCons/cpp.py | 4 +- src/engine/SCons/cppTests.py | 4 +- src/engine/SCons/exitfuncs.py | 4 +- src/engine/setup.py | 8 +- src/script/README.txt | 6 +- src/script/scons-post-install.py | 4 +- src/script/scons-time.py | 4 +- src/script/scons.bat | 8 +- src/script/scons.py | 10 +- src/script/sconsign.py | 10 +- src/script/setup.py | 6 +- src/setup.py | 6 +- src/test_aegistests.py | 4 +- src/test_files.py | 4 +- src/test_interrupts.py | 4 +- src/test_pychecker.py | 4 +- src/test_setup.py | 4 +- src/test_strings.py | 8 +- 461 files changed, 2121 insertions(+), 2101 deletions(-) create mode 100644 bin/scons-doc.py delete mode 100644 bin/sconsoutput.py diff --git a/LICENSE b/LICENSE index 67f1906..77421fa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/SConstruct b/SConstruct index 1a7f0ea..37e8487 100644 --- a/SConstruct +++ b/SConstruct @@ -6,13 +6,13 @@ # When this gets changed, you must also change the copyright_years string # in QMTest/TestSCons.py so the test scripts look for the right string. -copyright_years = '2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009' +copyright_years = '2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010' # This gets inserted into the man pages to reflect the month of release. -month_year = 'December 2009' +month_year = 'January 2010' # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -152,7 +152,6 @@ if not revision and svn: result = result + '[MODIFIED]' return result - checkpoint = ARGUMENTS.get('CHECKPOINT', '') if checkpoint: if checkpoint == 'd': @@ -162,7 +161,6 @@ if checkpoint: checkpoint = 'r' + revision version = version + '.' + checkpoint - build_id = ARGUMENTS.get('BUILD_ID') if build_id is None: if revision: @@ -709,7 +707,6 @@ for p in [ scons ]: pkg = p['pkg'] pkg_version = "%s-%s" % (pkg, version) - src = 'src' if p.has_key('src_subdir'): src = os.path.join(src, p['src_subdir']) @@ -801,7 +798,7 @@ for p in [ scons ]: # # Now run everything in src_file through the sed command we - # concocted to expand SConstruct, 1.2.0.d20091224, etc. + # concocted to expand SConstruct, 1.2.0.d20100117, etc. # for b in src_files: s = p['filemap'].get(b, b) diff --git a/bin/docdiff b/bin/docdiff index c565a04..c7adb05 100644 --- a/bin/docdiff +++ b/bin/docdiff @@ -4,13 +4,13 @@ if test $# -eq 0; then for f in doc/user/*.in; do xml=doc/user/`basename $f .in`.xml echo $f: - python bin/sconsoutput.py $f | diff $DIFFFLAGS $xml - + python bin/scons-doc.py $f | diff $DIFFFLAGS $xml - done else for a in $*; do f=doc/user/$a.in xml=doc/user/$a.xml echo $f: - python bin/sconsoutput.py $f | diff $DIFFFLAGS $xml - + python bin/scons-doc.py $f | diff $DIFFFLAGS $xml - done fi diff --git a/bin/docrun b/bin/docrun index 5ba4215..ad8ea9f 100644 --- a/bin/docrun +++ b/bin/docrun @@ -4,13 +4,13 @@ if test $# -eq 0; then for f in doc/user/*.in; do xml=doc/user/`basename $f .in`.xml echo $f: - python bin/sconsoutput.py $f + python bin/scons-doc.py $f done else for a in $*; do f=doc/user/$a.in xml=doc/user/$a.xml echo $f: - python bin/sconsoutput.py $f + python bin/scons-doc.py $f done fi diff --git a/bin/docupdate b/bin/docupdate index 0e1631b..cd9b532 100644 --- a/bin/docupdate +++ b/bin/docupdate @@ -4,13 +4,13 @@ if test $# -eq 0; then for f in doc/user/*.in; do xml=doc/user/`basename $f .in`.xml echo $f: - python bin/sconsoutput.py $f > $xml + python bin/scons-doc.py $f > $xml done else for a in $*; do f=doc/user/$a.in xml=doc/user/$a.xml echo $f: - python bin/sconsoutput.py $f > $xml + python bin/scons-doc.py $f > $xml done fi diff --git a/bin/import-test.py b/bin/import-test.py index 473a7ed..e7d4db4 100644 --- a/bin/import-test.py +++ b/bin/import-test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation # # tree2test.py - turn a directory tree into TestSCons code # @@ -25,7 +25,7 @@ # """ triple-quotes will need to have their contents edited by hand. # -__revision__ = "bin/import-test.py 4577 2009/12/27 19:44:43 scons" +__revision__ = "bin/import-test.py 4629 2010/01/17 22:23:21 scons" import os.path import sys diff --git a/bin/linecount.py b/bin/linecount.py index 359f642..aa0a8aa 100644 --- a/bin/linecount.py +++ b/bin/linecount.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation # # Count statistics about SCons test and source files. This must be run # against a fully-populated tree (for example, one that's been freshly @@ -23,7 +23,7 @@ # interesting one for most purposes. # -__revision__ = "bin/linecount.py 4577 2009/12/27 19:44:43 scons" +__revision__ = "bin/linecount.py 4629 2010/01/17 22:23:21 scons" import os.path import string diff --git a/bin/restore.sh b/bin/restore.sh index a5da9e8..0eec02f 100644 --- a/bin/restore.sh +++ b/bin/restore.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh # -# Simple hack script to restore __revision__, __COPYRIGHT_, 1.2.0.d20091224 +# Simple hack script to restore __revision__, __COPYRIGHT_, 1.2.0.d20100117 # and other similar variables to what gets checked in to source. This # comes in handy when people send in diffs based on the released source. # @@ -22,9 +22,9 @@ header() { for i in `find $DIRS -name '*.py'`; do header $i ed $i < +# +# env = Environment() +# env.Program('foo') +# +# +# int main() { printf("foo.c\n"); } +# +# +# +# The contents within the tag will get written +# into a temporary directory whenever example output needs to be +# generated. By default, the contents are not inserted into text +# directly, unless you set the "printme" attribute on one or more files, +# in which case they will get inserted within a tag. +# This makes it easy to define the example at the appropriate +# point in the text where you intend to show the SConstruct file. +# +# Note that you should usually give the a "name" +# attribute so that you can refer to the example configuration later to +# run SCons and generate output. +# +# If you just want to show a file's contents without worry about running +# SCons, there's a shorter tag: +# +# +# env = Environment() +# env.Program('foo') +# +# +# This is essentially equivalent to , +# but it's more straightforward. +# +# SCons output is generated from the following sort of tag: +# +# +# scons -Q foo +# scons -Q foo +# +# +# You tell it which example to use with the "example" attribute, and then +# give it a list of tags to execute. You can also +# supply an "os" tag, which specifies the type of operating system this +# example is intended to show; if you omit this, default value is "posix". +# +# The generated SGML will show the command line (with the appropriate +# command-line prompt for the operating system), execute the command in +# a temporary directory with the example files, capture the standard +# output from SCons, and insert it into the text as appropriate. +# Error output gets passed through to your error output so you +# can see if there are any problems executing the command. +# + +import optparse +import os +import re +import sgmllib +import string +import sys +import time + +sys.path.append(os.path.join(os.getcwd(), 'QMTest')) +sys.path.append(os.path.join(os.getcwd(), 'build', 'QMTest')) + +scons_py = os.path.join('bootstrap', 'src', 'script', 'scons.py') +if not os.path.exists(scons_py): + scons_py = os.path.join('src', 'script', 'scons.py') + +scons_lib_dir = os.path.join(os.getcwd(), 'bootstrap', 'src', 'engine') +if not os.path.exists(scons_lib_dir): + scons_lib_dir = os.path.join(os.getcwd(), 'src', 'engine') + +os.environ['SCONS_LIB_DIR'] = scons_lib_dir + +import TestCmd + +# The regular expression that identifies entity references in the +# standard sgmllib omits the underscore from the legal characters. +# Override it with our own regular expression that adds underscore. +sgmllib.entityref = re.compile('&([a-zA-Z][-_.a-zA-Z0-9]*)[^-_a-zA-Z0-9]') + +# Classes for collecting different types of data we're interested in. +class DataCollector: + """Generic class for collecting data between a start tag and end + tag. We subclass for various types of tags we care about.""" + def __init__(self): + self.data = "" + def afunc(self, data): + self.data = self.data + data + +class Example(DataCollector): + """An SCons example. This is essentially a list of files that + will get written to a temporary directory to collect output + from one or more SCons runs.""" + def __init__(self): + DataCollector.__init__(self) + self.files = [] + self.dirs = [] + +class File(DataCollector): + """A file, that will get written out to a temporary directory + for one or more SCons runs.""" + def __init__(self, name): + DataCollector.__init__(self) + self.name = name + +class Directory(DataCollector): + """A directory, that will get created in a temporary directory + for one or more SCons runs.""" + def __init__(self, name): + DataCollector.__init__(self) + self.name = name + +class Output(DataCollector): + """Where the command output goes. This is essentially + a list of commands that will get executed.""" + def __init__(self): + DataCollector.__init__(self) + self.commandlist = [] + +class Command(DataCollector): + """A tag for where the command output goes. This is essentially + a list of commands that will get executed.""" + def __init__(self): + DataCollector.__init__(self) + self.output = None + +Prompt = { + 'posix' : '% ', + 'win32' : 'C:\\>' +} + +# The magick SCons hackery that makes this work. +# +# So that our examples can still use the default SConstruct file, we +# actually feed the following into SCons via stdin and then have it +# SConscript() the SConstruct file. This stdin wrapper creates a set +# of ToolSurrogates for the tools for the appropriate platform. These +# Surrogates print output like the real tools and behave like them +# without actually having to be on the right platform or have the right +# tool installed. +# +# The upshot: The wrapper transparently changes the world out from +# under the top-level SConstruct file in an example just so we can get +# the command output. + +Stdin = """\ +import os +import re +import string +import SCons.Action +import SCons.Defaults +import SCons.Node.FS + +platform = '%(osname)s' + +Sep = { + 'posix' : '/', + 'win32' : '\\\\', +}[platform] + + +# Slip our own __str__() method into the EntryProxy class used to expand +# $TARGET{S} and $SOURCE{S} to translate the path-name separators from +# what's appropriate for the system we're running on to what's appropriate +# for the example system. +orig = SCons.Node.FS.EntryProxy +class MyEntryProxy(orig): + def __str__(self): + return string.replace(str(self._Proxy__subject), os.sep, Sep) +SCons.Node.FS.EntryProxy = MyEntryProxy + +# Slip our own RDirs() method into the Node.FS.File class so that the +# expansions of $_{CPPINC,F77INC,LIBDIR}FLAGS will have the path-name +# separators translated from what's appropriate for the system we're +# running on to what's appropriate for the example system. +orig_RDirs = SCons.Node.FS.File.RDirs +def my_RDirs(self, pathlist, orig_RDirs=orig_RDirs): + return map(lambda x: string.replace(str(x), os.sep, Sep), + orig_RDirs(self, pathlist)) +SCons.Node.FS.File.RDirs = my_RDirs + +class Curry: + def __init__(self, fun, *args, **kwargs): + self.fun = fun + self.pending = args[:] + self.kwargs = kwargs.copy() + + def __call__(self, *args, **kwargs): + if kwargs and self.kwargs: + kw = self.kwargs.copy() + kw.update(kwargs) + else: + kw = kwargs or self.kwargs + + return apply(self.fun, self.pending + args, kw) + +def Str(target, source, env, cmd=""): + result = [] + for cmd in env.subst_list(cmd, target=target, source=source): + result.append(string.join(map(str, cmd))) + return string.join(result, '\\n') + +class ToolSurrogate: + def __init__(self, tool, variable, func, varlist): + self.tool = tool + if not type(variable) is type([]): + variable = [variable] + self.variable = variable + self.func = func + self.varlist = varlist + def __call__(self, env): + t = Tool(self.tool) + t.generate(env) + for v in self.variable: + orig = env[v] + try: + strfunction = orig.strfunction + except AttributeError: + strfunction = Curry(Str, cmd=orig) + # Don't call Action() through its global function name, because + # that leads to infinite recursion in trying to initialize the + # Default Environment. + env[v] = SCons.Action.Action(self.func, + strfunction=strfunction, + varlist=self.varlist) + def __repr__(self): + # This is for the benefit of printing the 'TOOLS' + # variable through env.Dump(). + return repr(self.tool) + +def Null(target, source, env): + pass + +def Cat(target, source, env): + target = str(target[0]) + f = open(target, "wb") + for src in map(str, source): + f.write(open(src, "rb").read()) + f.close() + +def CCCom(target, source, env): + target = str(target[0]) + fp = open(target, "wb") + def process(source_file, fp=fp): + for line in open(source_file, "rb").readlines(): + m = re.match(r'#include\s[<"]([^<"]+)[>"]', line) + if m: + include = m.group(1) + for d in [str(env.Dir('$CPPPATH')), '.']: + f = os.path.join(d, include) + if os.path.exists(f): + process(f) + break + elif line[:11] != "STRIP CCCOM": + fp.write(line) + for src in map(str, source): + process(src) + fp.write('debug = ' + ARGUMENTS.get('debug', '0') + '\\n') + fp.close() + +public_class_re = re.compile('^public class (\S+)', re.MULTILINE) + +def JavaCCom(target, source, env): + # This is a fake Java compiler that just looks for + # public class FooBar + # lines in the source file(s) and spits those out + # to .class files named after the class. + tlist = map(str, target) + not_copied = {} + for t in tlist: + not_copied[t] = 1 + for src in map(str, source): + contents = open(src, "rb").read() + classes = public_class_re.findall(contents) + for c in classes: + for t in filter(lambda x: string.find(x, c) != -1, tlist): + open(t, "wb").write(contents) + del not_copied[t] + for t in not_copied.keys(): + open(t, "wb").write("\\n") + +def JavaHCom(target, source, env): + tlist = map(str, target) + slist = map(str, source) + for t, s in zip(tlist, slist): + open(t, "wb").write(open(s, "rb").read()) + +def find_class_files(arg, dirname, names): + class_files = filter(lambda n: n[-6:] == '.class', names) + paths = map(lambda n, d=dirname: os.path.join(d, n), class_files) + arg.extend(paths) + +def JarCom(target, source, env): + target = str(target[0]) + class_files = [] + for src in map(str, source): + os.path.walk(src, find_class_files, class_files) + f = open(target, "wb") + for cf in class_files: + f.write(open(cf, "rb").read()) + f.close() + +# XXX Adding COLOR, COLORS and PACKAGE to the 'cc' varlist(s) by hand +# here is bogus. It's for the benefit of doc/user/command-line.in, which +# uses examples that want to rebuild based on changes to these variables. +# It would be better to figure out a way to do it based on the content of +# the generated command-line, or else find a way to let the example markup +# language in doc/user/command-line.in tell this script what variables to +# add, but that's more difficult than I want to figure out how to do right +# now, so let's just use the simple brute force approach for the moment. + +ToolList = { + 'posix' : [('cc', ['CCCOM', 'SHCCCOM'], CCCom, ['CCFLAGS', 'CPPDEFINES', 'COLOR', 'COLORS', 'PACKAGE']), + ('link', ['LINKCOM', 'SHLINKCOM'], Cat, []), + ('ar', ['ARCOM', 'RANLIBCOM'], Cat, []), + ('tar', 'TARCOM', Null, []), + ('zip', 'ZIPCOM', Null, []), + ('BitKeeper', 'BITKEEPERCOM', Cat, []), + ('CVS', 'CVSCOM', Cat, []), + ('RCS', 'RCS_COCOM', Cat, []), + ('SCCS', 'SCCSCOM', Cat, []), + ('javac', 'JAVACCOM', JavaCCom, []), + ('javah', 'JAVAHCOM', JavaHCom, []), + ('jar', 'JARCOM', JarCom, []), + ('rmic', 'RMICCOM', Cat, []), + ], + 'win32' : [('msvc', ['CCCOM', 'SHCCCOM', 'RCCOM'], CCCom, ['CCFLAGS', 'CPPDEFINES', 'COLOR', 'COLORS', 'PACKAGE']), + ('mslink', ['LINKCOM', 'SHLINKCOM'], Cat, []), + ('mslib', 'ARCOM', Cat, []), + ('tar', 'TARCOM', Null, []), + ('zip', 'ZIPCOM', Null, []), + ('BitKeeper', 'BITKEEPERCOM', Cat, []), + ('CVS', 'CVSCOM', Cat, []), + ('RCS', 'RCS_COCOM', Cat, []), + ('SCCS', 'SCCSCOM', Cat, []), + ('javac', 'JAVACCOM', JavaCCom, []), + ('javah', 'JAVAHCOM', JavaHCom, []), + ('jar', 'JARCOM', JarCom, []), + ('rmic', 'RMICCOM', Cat, []), + ], +} + +toollist = ToolList[platform] +filter_tools = string.split('%(tools)s') +if filter_tools: + toollist = filter(lambda x, ft=filter_tools: x[0] in ft, toollist) + +toollist = map(lambda t: apply(ToolSurrogate, t), toollist) + +toollist.append('install') + +def surrogate_spawn(sh, escape, cmd, args, env): + pass + +def surrogate_pspawn(sh, escape, cmd, args, env, stdout, stderr): + pass + +SCons.Defaults.ConstructionEnvironment.update({ + 'PLATFORM' : platform, + 'TOOLS' : toollist, + 'SPAWN' : surrogate_spawn, + 'PSPAWN' : surrogate_pspawn, +}) + +SConscript('SConstruct') +""" + +# "Commands" that we will execute in our examples. +def command_scons(args, c, test, dict): + save_vals = {} + delete_keys = [] + try: + ce = c.environment + except AttributeError: + pass + else: + for arg in string.split(c.environment): + key, val = string.split(arg, '=') + try: + save_vals[key] = os.environ[key] + except KeyError: + delete_keys.append(key) + os.environ[key] = val + test.run(interpreter = sys.executable, + program = scons_py, + # We use ToolSurrogates to capture win32 output by "building" + # examples using a fake win32 tool chain. Suppress the + # warnings that come from the new revamped VS support so + # we can build doc on (Linux) systems that don't have + # Visual C installed. + arguments = '--warn=no-visual-c-missing -f - ' + string.join(args), + chdir = test.workpath('WORK'), + stdin = Stdin % dict) + os.environ.update(save_vals) + for key in delete_keys: + del(os.environ[key]) + out = test.stdout() + out = string.replace(out, test.workpath('ROOT'), '') + out = string.replace(out, test.workpath('WORK/SConstruct'), + '/home/my/project/SConstruct') + lines = string.split(out, '\n') + if lines: + while lines[-1] == '': + lines = lines[:-1] + #err = test.stderr() + #if err: + # sys.stderr.write(err) + return lines + +def command_touch(args, c, test, dict): + if args[0] == '-t': + t = int(time.mktime(time.strptime(args[1], '%Y%m%d%H%M'))) + times = (t, t) + args = args[2:] + else: + time.sleep(1) + times = None + for file in args: + if not os.path.isabs(file): + file = os.path.join(test.workpath('WORK'), file) + if not os.path.exists(file): + open(file, 'wb') + os.utime(file, times) + return [] + +def command_edit(args, c, test, dict): + try: + add_string = c.edit[:] + except AttributeError: + add_string = 'void edit(void) { ; }\n' + if add_string[-1] != '\n': + add_string = add_string + '\n' + for file in args: + if not os.path.isabs(file): + file = os.path.join(test.workpath('WORK'), file) + contents = open(file, 'rb').read() + open(file, 'wb').write(contents + add_string) + return [] + +def command_ls(args, c, test, dict): + def ls(a): + files = os.listdir(a) + files = filter(lambda x: x[0] != '.', files) + files.sort() + return [string.join(files, ' ')] + if args: + l = [] + for a in args: + l.extend(ls(test.workpath('WORK', a))) + return l + else: + return ls(test.workpath('WORK')) + +def command_sleep(args, c, test, dict): + time.sleep(int(args[0])) + +CommandDict = { + 'scons' : command_scons, + 'touch' : command_touch, + 'edit' : command_edit, + 'ls' : command_ls, + 'sleep' : command_sleep, +} + +def ExecuteCommand(args, c, t, dict): + try: + func = CommandDict[args[0]] + except KeyError: + func = lambda args, c, t, dict: [] + return func(args[1:], c, t, dict) + +class MySGML(sgmllib.SGMLParser): + """A subclass of the standard Python 2.2 sgmllib SGML parser. + + This extends the standard sgmllib parser to recognize, and do cool + stuff with, the added tags that describe our SCons examples, + commands, and other stuff. + + Note that this doesn't work with the 1.5.2 sgmllib module, because + that didn't have the ability to work with ENTITY declarations. + """ + def __init__(self, outfp): + sgmllib.SGMLParser.__init__(self) + self.examples = {} + self.afunclist = [] + self.outfp = outfp + + # The first set of methods here essentially implement pass-through + # handling of most of the stuff in an SGML file. We're really + # only concerned with the tags specific to SCons example processing, + # the methods for which get defined below. + + def handle_data(self, data): + try: + f = self.afunclist[-1] + except IndexError: + self.outfp.write(data) + else: + f(data) + + def handle_comment(self, data): + self.outfp.write('') + + def handle_decl(self, data): + self.outfp.write('') + + def unknown_starttag(self, tag, attrs): + try: + f = self.example.afunc + except AttributeError: + f = self.outfp.write + if not attrs: + f('<' + tag + '>') + else: + f('<' + tag) + for name, value in attrs: + f(' ' + name + '=' + '"' + value + '"') + f('>') + + def unknown_endtag(self, tag): + self.outfp.write('') + + def unknown_entityref(self, ref): + self.outfp.write('&' + ref + ';') + + def unknown_charref(self, ref): + self.outfp.write('&#' + ref + ';') + + # Here is where the heavy lifting begins. The following methods + # handle the begin-end tags of our SCons examples. + + def start_scons_example(self, attrs): + t = filter(lambda t: t[0] == 'name', attrs) + if t: + name = t[0][1] + try: + e = self.examples[name] + except KeyError: + e = self.examples[name] = Example() + else: + e = Example() + for name, value in attrs: + setattr(e, name, value) + self.e = e + self.afunclist.append(e.afunc) + + def end_scons_example(self): + e = self.e + files = filter(lambda f: f.printme, e.files) + if files: + self.outfp.write('') + for f in files: + if f.printme: + i = len(f.data) - 1 + while f.data[i] == ' ': + i = i - 1 + output = string.replace(f.data[:i+1], '__ROOT__', '') + output = string.replace(output, '<', '<') + output = string.replace(output, '>', '>') + self.outfp.write(output) + if e.data and e.data[0] == '\n': + e.data = e.data[1:] + self.outfp.write(e.data + '') + delattr(self, 'e') + self.afunclist = self.afunclist[:-1] + + def start_file(self, attrs): + try: + e = self.e + except AttributeError: + self.error(" tag outside of ") + t = filter(lambda t: t[0] == 'name', attrs) + if not t: + self.error("no name attribute found") + try: + e.prefix + except AttributeError: + e.prefix = e.data + e.data = "" + f = File(t[0][1]) + f.printme = None + for name, value in attrs: + setattr(f, name, value) + e.files.append(f) + self.afunclist.append(f.afunc) + + def end_file(self): + self.e.data = "" + self.afunclist = self.afunclist[:-1] + + def start_directory(self, attrs): + try: + e = self.e + except AttributeError: + self.error(" tag outside of ") + t = filter(lambda t: t[0] == 'name', attrs) + if not t: + self.error("no name attribute found") + try: + e.prefix + except AttributeError: + e.prefix = e.data + e.data = "" + d = Directory(t[0][1]) + for name, value in attrs: + setattr(d, name, value) + e.dirs.append(d) + self.afunclist.append(d.afunc) + + def end_directory(self): + self.e.data = "" + self.afunclist = self.afunclist[:-1] + + def start_scons_example_file(self, attrs): + t = filter(lambda t: t[0] == 'example', attrs) + if not t: + self.error("no example attribute found") + exname = t[0][1] + try: + e = self.examples[exname] + except KeyError: + self.error("unknown example name '%s'" % exname) + fattrs = filter(lambda t: t[0] == 'name', attrs) + if not fattrs: + self.error("no name attribute found") + fname = fattrs[0][1] + f = filter(lambda f, fname=fname: f.name == fname, e.files) + if not f: + self.error("example '%s' does not have a file named '%s'" % (exname, fname)) + self.f = f[0] + + def end_scons_example_file(self): + f = self.f + self.outfp.write('') + self.outfp.write(f.data + '') + delattr(self, 'f') + + def start_scons_output(self, attrs): + t = filter(lambda t: t[0] == 'example', attrs) + if not t: + self.error("no example attribute found") + exname = t[0][1] + try: + e = self.examples[exname] + except KeyError: + self.error("unknown example name '%s'" % exname) + # Default values for an example. + o = Output() + o.preserve = None + o.os = 'posix' + o.tools = '' + o.e = e + # Locally-set. + for name, value in attrs: + setattr(o, name, value) + self.o = o + self.afunclist.append(o.afunc) + + def end_scons_output(self): + # The real raison d'etre for this script, this is where we + # actually execute SCons to fetch the output. + o = self.o + e = o.e + t = TestCmd.TestCmd(workdir='', combine=1) + if o.preserve: + t.preserve() + t.subdir('ROOT', 'WORK') + t.rootpath = string.replace(t.workpath('ROOT'), '\\', '\\\\') + + for d in e.dirs: + dir = t.workpath('WORK', d.name) + if not os.path.exists(dir): + os.makedirs(dir) + + for f in e.files: + i = 0 + while f.data[i] == '\n': + i = i + 1 + lines = string.split(f.data[i:], '\n') + i = 0 + while lines[0][i] == ' ': + i = i + 1 + lines = map(lambda l, i=i: l[i:], lines) + path = string.replace(f.name, '__ROOT__', t.rootpath) + if not os.path.isabs(path): + path = t.workpath('WORK', path) + dir, name = os.path.split(path) + if dir and not os.path.exists(dir): + os.makedirs(dir) + content = string.join(lines, '\n') + content = string.replace(content, '__ROOT__', t.rootpath) + path = t.workpath('WORK', path) + t.write(path, content) + if hasattr(f, 'chmod'): + os.chmod(path, int(f.chmod, 0)) + + i = len(o.prefix) + while o.prefix[i-1] != '\n': + i = i - 1 + + self.outfp.write('' + o.prefix[:i]) + p = o.prefix[i:] + + # Regular expressions for making the doc output consistent, + # regardless of reported addresses or Python version. + + # Massage addresses in object repr strings to a constant. + address_re = re.compile(r' at 0x[0-9a-fA-F]*\>') + + # Massage file names in stack traces (sometimes reported as absolute + # paths) to a consistent relative path. + engine_re = re.compile(r' File ".*/src/engine/SCons/') + + # Python 2.5 changed the stack trace when the module is read + # from standard input from read "... line 7, in ?" to + # "... line 7, in ". + file_re = re.compile(r'^( *File ".*", line \d+, in) \?$', re.M) + + # Python 2.6 made UserList a new-style class, which changes the + # AttributeError message generated by our NodeList subclass. + nodelist_re = re.compile(r'(AttributeError:) NodeList instance (has no attribute \S+)') + + for c in o.commandlist: + self.outfp.write(p + Prompt[o.os]) + d = string.replace(c.data, '__ROOT__', '') + self.outfp.write('' + d + '\n') + + e = string.replace(c.data, '__ROOT__', t.workpath('ROOT')) + args = string.split(e) + lines = ExecuteCommand(args, c, t, {'osname':o.os, 'tools':o.tools}) + content = None + if c.output: + content = c.output + elif lines: + content = string.join(lines, '\n' + p) + if content: + content = address_re.sub(r' at 0x700000>', content) + content = engine_re.sub(r' File "bootstrap/src/engine/SCons/', content) + content = file_re.sub(r'\1 ', content) + content = nodelist_re.sub(r"\1 'NodeList' object \2", content) + content = string.replace(content, '<', '<') + content = string.replace(content, '>', '>') + self.outfp.write(p + content + '\n') + + if o.data[0] == '\n': + o.data = o.data[1:] + self.outfp.write(o.data + '') + delattr(self, 'o') + self.afunclist = self.afunclist[:-1] + + def start_scons_output_command(self, attrs): + try: + o = self.o + except AttributeError: + self.error(" tag outside of ") + try: + o.prefix + except AttributeError: + o.prefix = o.data + o.data = "" + c = Command() + for name, value in attrs: + setattr(c, name, value) + o.commandlist.append(c) + self.afunclist.append(c.afunc) + + def end_scons_output_command(self): + self.o.data = "" + self.afunclist = self.afunclist[:-1] + + def start_sconstruct(self, attrs): + f = File('') + self.f = f + self.afunclist.append(f.afunc) + + def end_sconstruct(self): + f = self.f + self.outfp.write('') + output = string.replace(f.data, '__ROOT__', '') + self.outfp.write(output + '') + delattr(self, 'f') + self.afunclist = self.afunclist[:-1] + +def process(filename): + if filename == '-': + f = sys.stdin + else: + try: + f = open(filename, 'r') + except EnvironmentError, e: + sys.stderr.write('%s: %s\n' % (filename, msg)) + return 1 + + data = f.read() + if f is not sys.stdin: + f.close() + + if data.startswith(' -# -# env = Environment() -# env.Program('foo') -# -# -# int main() { printf("foo.c\n"); } -# -# -# -# The contents within the tag will get written -# into a temporary directory whenever example output needs to be -# generated. By default, the contents are not inserted into text -# directly, unless you set the "printme" attribute on one or more files, -# in which case they will get inserted within a tag. -# This makes it easy to define the example at the appropriate -# point in the text where you intend to show the SConstruct file. -# -# Note that you should usually give the a "name" -# attribute so that you can refer to the example configuration later to -# run SCons and generate output. -# -# If you just want to show a file's contents without worry about running -# SCons, there's a shorter tag: -# -# -# env = Environment() -# env.Program('foo') -# -# -# This is essentially equivalent to , -# but it's more straightforward. -# -# SCons output is generated from the following sort of tag: -# -# -# scons -Q foo -# scons -Q foo -# -# -# You tell it which example to use with the "example" attribute, and then -# give it a list of tags to execute. You can also -# supply an "os" tag, which specifies the type of operating system this -# example is intended to show; if you omit this, default value is "posix". -# -# The generated SGML will show the command line (with the appropriate -# command-line prompt for the operating system), execute the command in -# a temporary directory with the example files, capture the standard -# output from SCons, and insert it into the text as appropriate. -# Error output gets passed through to your error output so you -# can see if there are any problems executing the command. -# - -import os -import os.path -import re -import sgmllib -import string -import sys -import time - -sys.path.append(os.path.join(os.getcwd(), 'QMTest')) -sys.path.append(os.path.join(os.getcwd(), 'build', 'QMTest')) - -scons_py = os.path.join('bootstrap', 'src', 'script', 'scons.py') -if not os.path.exists(scons_py): - scons_py = os.path.join('src', 'script', 'scons.py') - -scons_lib_dir = os.path.join(os.getcwd(), 'bootstrap', 'src', 'engine') -if not os.path.exists(scons_lib_dir): - scons_lib_dir = os.path.join(os.getcwd(), 'src', 'engine') - -os.environ['SCONS_LIB_DIR'] = scons_lib_dir - -import TestCmd - -# The regular expression that identifies entity references in the -# standard sgmllib omits the underscore from the legal characters. -# Override it with our own regular expression that adds underscore. -sgmllib.entityref = re.compile('&([a-zA-Z][-_.a-zA-Z0-9]*)[^-_a-zA-Z0-9]') - -# Classes for collecting different types of data we're interested in. -class DataCollector: - """Generic class for collecting data between a start tag and end - tag. We subclass for various types of tags we care about.""" - def __init__(self): - self.data = "" - def afunc(self, data): - self.data = self.data + data - -class Example(DataCollector): - """An SCons example. This is essentially a list of files that - will get written to a temporary directory to collect output - from one or more SCons runs.""" - def __init__(self): - DataCollector.__init__(self) - self.files = [] - self.dirs = [] - -class File(DataCollector): - """A file, that will get written out to a temporary directory - for one or more SCons runs.""" - def __init__(self, name): - DataCollector.__init__(self) - self.name = name - -class Directory(DataCollector): - """A directory, that will get created in a temporary directory - for one or more SCons runs.""" - def __init__(self, name): - DataCollector.__init__(self) - self.name = name - -class Output(DataCollector): - """Where the command output goes. This is essentially - a list of commands that will get executed.""" - def __init__(self): - DataCollector.__init__(self) - self.commandlist = [] - -class Command(DataCollector): - """A tag for where the command output goes. This is essentially - a list of commands that will get executed.""" - def __init__(self): - DataCollector.__init__(self) - self.output = None - -Prompt = { - 'posix' : '% ', - 'win32' : 'C:\\>' -} - -# The magick SCons hackery that makes this work. -# -# So that our examples can still use the default SConstruct file, we -# actually feed the following into SCons via stdin and then have it -# SConscript() the SConstruct file. This stdin wrapper creates a set -# of ToolSurrogates for the tools for the appropriate platform. These -# Surrogates print output like the real tools and behave like them -# without actually having to be on the right platform or have the right -# tool installed. -# -# The upshot: The wrapper transparently changes the world out from -# under the top-level SConstruct file in an example just so we can get -# the command output. - -Stdin = """\ -import os -import re -import string -import SCons.Action -import SCons.Defaults -import SCons.Node.FS - -platform = '%(osname)s' - -Sep = { - 'posix' : '/', - 'win32' : '\\\\', -}[platform] - - -# Slip our own __str__() method into the EntryProxy class used to expand -# $TARGET{S} and $SOURCE{S} to translate the path-name separators from -# what's appropriate for the system we're running on to what's appropriate -# for the example system. -orig = SCons.Node.FS.EntryProxy -class MyEntryProxy(orig): - def __str__(self): - return string.replace(str(self._Proxy__subject), os.sep, Sep) -SCons.Node.FS.EntryProxy = MyEntryProxy - -# Slip our own RDirs() method into the Node.FS.File class so that the -# expansions of $_{CPPINC,F77INC,LIBDIR}FLAGS will have the path-name -# separators translated from what's appropriate for the system we're -# running on to what's appropriate for the example system. -orig_RDirs = SCons.Node.FS.File.RDirs -def my_RDirs(self, pathlist, orig_RDirs=orig_RDirs): - return map(lambda x: string.replace(str(x), os.sep, Sep), - orig_RDirs(self, pathlist)) -SCons.Node.FS.File.RDirs = my_RDirs - -class Curry: - def __init__(self, fun, *args, **kwargs): - self.fun = fun - self.pending = args[:] - self.kwargs = kwargs.copy() - - def __call__(self, *args, **kwargs): - if kwargs and self.kwargs: - kw = self.kwargs.copy() - kw.update(kwargs) - else: - kw = kwargs or self.kwargs - - return apply(self.fun, self.pending + args, kw) - -def Str(target, source, env, cmd=""): - result = [] - for cmd in env.subst_list(cmd, target=target, source=source): - result.append(string.join(map(str, cmd))) - return string.join(result, '\\n') - -class ToolSurrogate: - def __init__(self, tool, variable, func, varlist): - self.tool = tool - if not type(variable) is type([]): - variable = [variable] - self.variable = variable - self.func = func - self.varlist = varlist - def __call__(self, env): - t = Tool(self.tool) - t.generate(env) - for v in self.variable: - orig = env[v] - try: - strfunction = orig.strfunction - except AttributeError: - strfunction = Curry(Str, cmd=orig) - # Don't call Action() through its global function name, because - # that leads to infinite recursion in trying to initialize the - # Default Environment. - env[v] = SCons.Action.Action(self.func, - strfunction=strfunction, - varlist=self.varlist) - def __repr__(self): - # This is for the benefit of printing the 'TOOLS' - # variable through env.Dump(). - return repr(self.tool) - -def Null(target, source, env): - pass - -def Cat(target, source, env): - target = str(target[0]) - f = open(target, "wb") - for src in map(str, source): - f.write(open(src, "rb").read()) - f.close() - -def CCCom(target, source, env): - target = str(target[0]) - fp = open(target, "wb") - def process(source_file, fp=fp): - for line in open(source_file, "rb").readlines(): - m = re.match(r'#include\s[<"]([^<"]+)[>"]', line) - if m: - include = m.group(1) - for d in [str(env.Dir('$CPPPATH')), '.']: - f = os.path.join(d, include) - if os.path.exists(f): - process(f) - break - elif line[:11] != "STRIP CCCOM": - fp.write(line) - for src in map(str, source): - process(src) - fp.write('debug = ' + ARGUMENTS.get('debug', '0') + '\\n') - fp.close() - -public_class_re = re.compile('^public class (\S+)', re.MULTILINE) - -def JavaCCom(target, source, env): - # This is a fake Java compiler that just looks for - # public class FooBar - # lines in the source file(s) and spits those out - # to .class files named after the class. - tlist = map(str, target) - not_copied = {} - for t in tlist: - not_copied[t] = 1 - for src in map(str, source): - contents = open(src, "rb").read() - classes = public_class_re.findall(contents) - for c in classes: - for t in filter(lambda x: string.find(x, c) != -1, tlist): - open(t, "wb").write(contents) - del not_copied[t] - for t in not_copied.keys(): - open(t, "wb").write("\\n") - -def JavaHCom(target, source, env): - tlist = map(str, target) - slist = map(str, source) - for t, s in zip(tlist, slist): - open(t, "wb").write(open(s, "rb").read()) - -def find_class_files(arg, dirname, names): - class_files = filter(lambda n: n[-6:] == '.class', names) - paths = map(lambda n, d=dirname: os.path.join(d, n), class_files) - arg.extend(paths) - -def JarCom(target, source, env): - target = str(target[0]) - class_files = [] - for src in map(str, source): - os.path.walk(src, find_class_files, class_files) - f = open(target, "wb") - for cf in class_files: - f.write(open(cf, "rb").read()) - f.close() - -# XXX Adding COLOR, COLORS and PACKAGE to the 'cc' varlist(s) by hand -# here is bogus. It's for the benefit of doc/user/command-line.in, which -# uses examples that want to rebuild based on changes to these variables. -# It would be better to figure out a way to do it based on the content of -# the generated command-line, or else find a way to let the example markup -# language in doc/user/command-line.in tell this script what variables to -# add, but that's more difficult than I want to figure out how to do right -# now, so let's just use the simple brute force approach for the moment. - -ToolList = { - 'posix' : [('cc', ['CCCOM', 'SHCCCOM'], CCCom, ['CCFLAGS', 'CPPDEFINES', 'COLOR', 'COLORS', 'PACKAGE']), - ('link', ['LINKCOM', 'SHLINKCOM'], Cat, []), - ('ar', ['ARCOM', 'RANLIBCOM'], Cat, []), - ('tar', 'TARCOM', Null, []), - ('zip', 'ZIPCOM', Null, []), - ('BitKeeper', 'BITKEEPERCOM', Cat, []), - ('CVS', 'CVSCOM', Cat, []), - ('RCS', 'RCS_COCOM', Cat, []), - ('SCCS', 'SCCSCOM', Cat, []), - ('javac', 'JAVACCOM', JavaCCom, []), - ('javah', 'JAVAHCOM', JavaHCom, []), - ('jar', 'JARCOM', JarCom, []), - ('rmic', 'RMICCOM', Cat, []), - ], - 'win32' : [('msvc', ['CCCOM', 'SHCCCOM', 'RCCOM'], CCCom, ['CCFLAGS', 'CPPDEFINES', 'COLOR', 'COLORS', 'PACKAGE']), - ('mslink', ['LINKCOM', 'SHLINKCOM'], Cat, []), - ('mslib', 'ARCOM', Cat, []), - ('tar', 'TARCOM', Null, []), - ('zip', 'ZIPCOM', Null, []), - ('BitKeeper', 'BITKEEPERCOM', Cat, []), - ('CVS', 'CVSCOM', Cat, []), - ('RCS', 'RCS_COCOM', Cat, []), - ('SCCS', 'SCCSCOM', Cat, []), - ('javac', 'JAVACCOM', JavaCCom, []), - ('javah', 'JAVAHCOM', JavaHCom, []), - ('jar', 'JARCOM', JarCom, []), - ('rmic', 'RMICCOM', Cat, []), - ], -} - -toollist = ToolList[platform] -filter_tools = string.split('%(tools)s') -if filter_tools: - toollist = filter(lambda x, ft=filter_tools: x[0] in ft, toollist) - -toollist = map(lambda t: apply(ToolSurrogate, t), toollist) - -toollist.append('install') - -def surrogate_spawn(sh, escape, cmd, args, env): - pass - -def surrogate_pspawn(sh, escape, cmd, args, env, stdout, stderr): - pass - -SCons.Defaults.ConstructionEnvironment.update({ - 'PLATFORM' : platform, - 'TOOLS' : toollist, - 'SPAWN' : surrogate_spawn, - 'PSPAWN' : surrogate_pspawn, -}) - -SConscript('SConstruct') -""" - -# "Commands" that we will execute in our examples. -def command_scons(args, c, test, dict): - save_vals = {} - delete_keys = [] - try: - ce = c.environment - except AttributeError: - pass - else: - for arg in string.split(c.environment): - key, val = string.split(arg, '=') - try: - save_vals[key] = os.environ[key] - except KeyError: - delete_keys.append(key) - os.environ[key] = val - test.run(interpreter = sys.executable, - program = scons_py, - arguments = '-f - ' + string.join(args), - chdir = test.workpath('WORK'), - stdin = Stdin % dict) - os.environ.update(save_vals) - for key in delete_keys: - del(os.environ[key]) - out = test.stdout() - out = string.replace(out, test.workpath('ROOT'), '') - out = string.replace(out, test.workpath('WORK/SConstruct'), - '/home/my/project/SConstruct') - lines = string.split(out, '\n') - if lines: - while lines[-1] == '': - lines = lines[:-1] - #err = test.stderr() - #if err: - # sys.stderr.write(err) - return lines - -def command_touch(args, c, test, dict): - if args[0] == '-t': - t = int(time.mktime(time.strptime(args[1], '%Y%m%d%H%M'))) - times = (t, t) - args = args[2:] - else: - time.sleep(1) - times = None - for file in args: - if not os.path.isabs(file): - file = os.path.join(test.workpath('WORK'), file) - if not os.path.exists(file): - open(file, 'wb') - os.utime(file, times) - return [] - -def command_edit(args, c, test, dict): - try: - add_string = c.edit[:] - except AttributeError: - add_string = 'void edit(void) { ; }\n' - if add_string[-1] != '\n': - add_string = add_string + '\n' - for file in args: - if not os.path.isabs(file): - file = os.path.join(test.workpath('WORK'), file) - contents = open(file, 'rb').read() - open(file, 'wb').write(contents + add_string) - return [] - -def command_ls(args, c, test, dict): - def ls(a): - files = os.listdir(a) - files = filter(lambda x: x[0] != '.', files) - files.sort() - return [string.join(files, ' ')] - if args: - l = [] - for a in args: - l.extend(ls(test.workpath('WORK', a))) - return l - else: - return ls(test.workpath('WORK')) - -CommandDict = { - 'scons' : command_scons, - 'touch' : command_touch, - 'edit' : command_edit, - 'ls' : command_ls, -} - -def ExecuteCommand(args, c, t, dict): - try: - func = CommandDict[args[0]] - except KeyError: - func = lambda args, c, t, dict: [] - return func(args[1:], c, t, dict) - -class MySGML(sgmllib.SGMLParser): - """A subclass of the standard Python 2.2 sgmllib SGML parser. - - This extends the standard sgmllib parser to recognize, and do cool - stuff with, the added tags that describe our SCons examples, - commands, and other stuff. - - Note that this doesn't work with the 1.5.2 sgmllib module, because - that didn't have the ability to work with ENTITY declarations. - """ - def __init__(self): - sgmllib.SGMLParser.__init__(self) - self.examples = {} - self.afunclist = [] - - # The first set of methods here essentially implement pass-through - # handling of most of the stuff in an SGML file. We're really - # only concerned with the tags specific to SCons example processing, - # the methods for which get defined below. - - def handle_data(self, data): - try: - f = self.afunclist[-1] - except IndexError: - sys.stdout.write(data) - else: - f(data) - - def handle_comment(self, data): - sys.stdout.write('') - - def handle_decl(self, data): - sys.stdout.write('') - - def unknown_starttag(self, tag, attrs): - try: - f = self.example.afunc - except AttributeError: - f = sys.stdout.write - if not attrs: - f('<' + tag + '>') - else: - f('<' + tag) - for name, value in attrs: - f(' ' + name + '=' + '"' + value + '"') - f('>') - - def unknown_endtag(self, tag): - sys.stdout.write('') - - def unknown_entityref(self, ref): - sys.stdout.write('&' + ref + ';') - - def unknown_charref(self, ref): - sys.stdout.write('&#' + ref + ';') - - # Here is where the heavy lifting begins. The following methods - # handle the begin-end tags of our SCons examples. - - def start_scons_example(self, attrs): - t = filter(lambda t: t[0] == 'name', attrs) - if t: - name = t[0][1] - try: - e = self.examples[name] - except KeyError: - e = self.examples[name] = Example() - else: - e = Example() - for name, value in attrs: - setattr(e, name, value) - self.e = e - self.afunclist.append(e.afunc) - - def end_scons_example(self): - e = self.e - files = filter(lambda f: f.printme, e.files) - if files: - sys.stdout.write('') - for f in files: - if f.printme: - i = len(f.data) - 1 - while f.data[i] == ' ': - i = i - 1 - output = string.replace(f.data[:i+1], '__ROOT__', '') - output = string.replace(output, '<', '<') - output = string.replace(output, '>', '>') - sys.stdout.write(output) - if e.data and e.data[0] == '\n': - e.data = e.data[1:] - sys.stdout.write(e.data + '') - delattr(self, 'e') - self.afunclist = self.afunclist[:-1] - - def start_file(self, attrs): - try: - e = self.e - except AttributeError: - self.error(" tag outside of ") - t = filter(lambda t: t[0] == 'name', attrs) - if not t: - self.error("no name attribute found") - try: - e.prefix - except AttributeError: - e.prefix = e.data - e.data = "" - f = File(t[0][1]) - f.printme = None - for name, value in attrs: - setattr(f, name, value) - e.files.append(f) - self.afunclist.append(f.afunc) - - def end_file(self): - self.e.data = "" - self.afunclist = self.afunclist[:-1] - - def start_directory(self, attrs): - try: - e = self.e - except AttributeError: - self.error(" tag outside of ") - t = filter(lambda t: t[0] == 'name', attrs) - if not t: - self.error("no name attribute found") - try: - e.prefix - except AttributeError: - e.prefix = e.data - e.data = "" - d = Directory(t[0][1]) - for name, value in attrs: - setattr(d, name, value) - e.dirs.append(d) - self.afunclist.append(d.afunc) - - def end_directory(self): - self.e.data = "" - self.afunclist = self.afunclist[:-1] - - def start_scons_example_file(self, attrs): - t = filter(lambda t: t[0] == 'example', attrs) - if not t: - self.error("no example attribute found") - exname = t[0][1] - try: - e = self.examples[exname] - except KeyError: - self.error("unknown example name '%s'" % exname) - fattrs = filter(lambda t: t[0] == 'name', attrs) - if not fattrs: - self.error("no name attribute found") - fname = fattrs[0][1] - f = filter(lambda f, fname=fname: f.name == fname, e.files) - if not f: - self.error("example '%s' does not have a file named '%s'" % (exname, fname)) - self.f = f[0] - - def end_scons_example_file(self): - f = self.f - sys.stdout.write('') - sys.stdout.write(f.data + '') - delattr(self, 'f') - - def start_scons_output(self, attrs): - t = filter(lambda t: t[0] == 'example', attrs) - if not t: - self.error("no example attribute found") - exname = t[0][1] - try: - e = self.examples[exname] - except KeyError: - self.error("unknown example name '%s'" % exname) - # Default values for an example. - o = Output() - o.preserve = None - o.os = 'posix' - o.tools = '' - o.e = e - # Locally-set. - for name, value in attrs: - setattr(o, name, value) - self.o = o - self.afunclist.append(o.afunc) - - def end_scons_output(self): - # The real raison d'etre for this script, this is where we - # actually execute SCons to fetch the output. - o = self.o - e = o.e - t = TestCmd.TestCmd(workdir='', combine=1) - if o.preserve: - t.preserve() - t.subdir('ROOT', 'WORK') - t.rootpath = string.replace(t.workpath('ROOT'), '\\', '\\\\') - - for d in e.dirs: - dir = t.workpath('WORK', d.name) - if not os.path.exists(dir): - os.makedirs(dir) - - for f in e.files: - i = 0 - while f.data[i] == '\n': - i = i + 1 - lines = string.split(f.data[i:], '\n') - i = 0 - while lines[0][i] == ' ': - i = i + 1 - lines = map(lambda l, i=i: l[i:], lines) - path = string.replace(f.name, '__ROOT__', t.rootpath) - if not os.path.isabs(path): - path = t.workpath('WORK', path) - dir, name = os.path.split(path) - if dir and not os.path.exists(dir): - os.makedirs(dir) - content = string.join(lines, '\n') - content = string.replace(content, '__ROOT__', t.rootpath) - path = t.workpath('WORK', path) - t.write(path, content) - if hasattr(f, 'chmod'): - os.chmod(path, int(f.chmod, 0)) - - i = len(o.prefix) - while o.prefix[i-1] != '\n': - i = i - 1 - - sys.stdout.write('' + o.prefix[:i]) - p = o.prefix[i:] - - for c in o.commandlist: - sys.stdout.write(p + Prompt[o.os]) - d = string.replace(c.data, '__ROOT__', '') - sys.stdout.write('' + d + '\n') - - e = string.replace(c.data, '__ROOT__', t.workpath('ROOT')) - args = string.split(e) - lines = ExecuteCommand(args, c, t, {'osname':o.os, 'tools':o.tools}) - content = None - if c.output: - content = c.output - elif lines: - content = string.join(lines, '\n' + p) - if content: - content = re.sub(' at 0x[0-9a-fA-F]*\>', ' at 0x700000>', content) - content = string.replace(content, '<', '<') - content = string.replace(content, '>', '>') - sys.stdout.write(p + content + '\n') - - if o.data[0] == '\n': - o.data = o.data[1:] - sys.stdout.write(o.data + '') - delattr(self, 'o') - self.afunclist = self.afunclist[:-1] - - def start_scons_output_command(self, attrs): - try: - o = self.o - except AttributeError: - self.error(" tag outside of ") - try: - o.prefix - except AttributeError: - o.prefix = o.data - o.data = "" - c = Command() - for name, value in attrs: - setattr(c, name, value) - o.commandlist.append(c) - self.afunclist.append(c.afunc) - - def end_scons_output_command(self): - self.o.data = "" - self.afunclist = self.afunclist[:-1] - - def start_sconstruct(self, attrs): - f = File('') - self.f = f - self.afunclist.append(f.afunc) - - def end_sconstruct(self): - f = self.f - sys.stdout.write('') - output = string.replace(f.data, '__ROOT__', '') - sys.stdout.write(output + '') - delattr(self, 'f') - self.afunclist = self.afunclist[:-1] - -# The main portion of the program itself, short and simple. -try: - file = sys.argv[1] -except IndexError: - file = '-' - -if file == '-': - f = sys.stdin -else: - try: - f = open(file, 'r') - except IOError, msg: - print file, ":", msg - sys.exit(1) - -data = f.read() -if f is not sys.stdin: - f.close() - -if data.startswith(' $TARGET") + "$PYTHON $SCONS_DOC_PY $SOURCE > $TARGET") orig_env.SCons_revision(build_s, doc_s) Local(build_s) diff --git a/doc/design/scons.mod b/doc/design/scons.mod index d805210..012bc3e 100644 --- a/doc/design/scons.mod +++ b/doc/design/scons.mod @@ -1,6 +1,6 @@ + - - % scons -Q - gcc -o hello.o -c hello.c - gcc -o version.o -c version.c - gcc -o hello hello.o version.o - % scons -Q - gcc -o version.o -c version.c - gcc -o hello hello.o version.o - % scons -Q - gcc -o version.o -c version.c - gcc -o hello hello.o version.o - + (Note that for the above example to work, + we &sleep; for one second in between each run, + so that the &SConstruct; file will create a + version.c file with a time string + that's one second later than the previous run.) + + @@ -1694,19 +1691,24 @@ With these changes, - we get the desired behavior of - re-building the version.o file, - and therefore re-linking the hello executable, - only when the hello.c has changed: + we get the desired behavior of only + re-linking the hello executable + when the hello.c has changed, + even though the version.o is rebuilt + (because the &SConstruct; file still changes the + version.c contents directly each run): - scons -Q - scons -Q + scons -Q hello + sleep 1 + scons -Q hello + sleep 1 edit hello.c - scons -Q - scons -Q + scons -Q hello + sleep 1 + scons -Q hello diff --git a/doc/user/depends.xml b/doc/user/depends.xml index b72f41f..d386a1f 100644 --- a/doc/user/depends.xml +++ b/doc/user/depends.xml @@ -1,6 +1,6 @@ @@ -1568,7 +1559,7 @@ If we list version.c as an actual source file, - though, then version.o + though, then the version.o file will get rebuilt every time we run &SCons; (because the &SConstruct; file itself changes the contents of version.c) @@ -1578,27 +1569,30 @@ - + (Note that for the above example to work, + we &sleep; for one second in between each run, + so that the &SConstruct; file will create a + version.c file with a time string + that's one second later than the previous run.) - - % scons -Q - gcc -o hello.o -c hello.c - gcc -o version.o -c version.c - gcc -o hello hello.o version.o - % scons -Q - gcc -o version.o -c version.c - gcc -o hello hello.o version.o - % scons -Q - gcc -o version.o -c version.c - gcc -o hello hello.o version.o - + @@ -1644,28 +1638,35 @@ With these changes, - we get the desired behavior of - re-building the version.o file, - and therefore re-linking the hello executable, - only when the hello.c has changed: + we get the desired behavior of only + re-linking the hello executable + when the hello.c has changed, + even though the version.o is rebuilt + (because the &SConstruct; file still changes the + version.c contents directly each run): - % scons -Q + % scons -Q hello cc -o version.o -c version.c cc -o hello.o -c hello.c cc -o hello version.o hello.o - % scons -Q - scons: `.' is up to date. + % sleep 1 + % scons -Q hello + cc -o version.o -c version.c + scons: `hello' is up to date. + % sleep 1 % edit hello.c [CHANGE THE CONTENTS OF hello.c] - % scons -Q + % scons -Q hello cc -o version.o -c version.c cc -o hello.o -c hello.c cc -o hello version.o hello.o - % scons -Q - scons: `.' is up to date. + % sleep 1 + % scons -Q hello + cc -o version.o -c version.c + scons: `hello' is up to date. diff --git a/doc/user/environments.in b/doc/user/environments.in index 124aaaa..dfe98f2 100644 --- a/doc/user/environments.in +++ b/doc/user/environments.in @@ -1,6 +1,6 @@ + + + % scons -Q + ['/lib/compat', '/usr/X11/include'] + scons: `.' is up to date. + @@ -109,6 +122,19 @@ + + + + % scons -Q + ['/usr/X11/include'] + scons: `.' is up to date. + diff --git a/doc/user/parseconfig.xml b/doc/user/parseconfig.xml index 1f85ad0..534ea3d 100644 --- a/doc/user/parseconfig.xml +++ b/doc/user/parseconfig.xml @@ -1,6 +1,6 @@ + % scons -Q - Package x11 was not found in the pkg-config search path. - Perhaps you should add the directory containing `x11.pc' - to the PKG_CONFIG_PATH environment variable - No package 'x11' found - OSError: 'pkg-config x11 --cflags --libs' exited 1: - File "/home/my/project/SConstruct", line 3: - env.ParseConfig("pkg-config x11 --cflags --libs") - File "bootstrap/src/engine/SCons/Environment.py", line 1474: - None - File "bootstrap/src/engine/SCons/Environment.py", line 593: - None + ['/lib/compat', '/usr/X11/include'] + scons: `.' is up to date. @@ -116,17 +118,19 @@ print env['CPPPATH'] + + % scons -Q - Package x11 was not found in the pkg-config search path. - Perhaps you should add the directory containing `x11.pc' - to the PKG_CONFIG_PATH environment variable - No package 'x11' found - OSError: 'pkg-config x11 --cflags --libs' exited 1: - File "/home/my/project/SConstruct", line 2: - env.ParseConfig("pkg-config x11 --cflags --libs") - File "bootstrap/src/engine/SCons/Environment.py", line 1474: - None - File "bootstrap/src/engine/SCons/Environment.py", line 593: - None + ['/usr/X11/include'] + scons: `.' is up to date. diff --git a/doc/user/parseflags.in b/doc/user/parseflags.in index b21df4f..d65e5b8 100644 --- a/doc/user/parseflags.in +++ b/doc/user/parseflags.in @@ -1,6 +1,6 @@